first commit
This commit is contained in:
939
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/MQClientAPIImpl.cpp
vendored
Normal file
939
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/MQClientAPIImpl.cpp
vendored
Normal file
@@ -0,0 +1,939 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "MQClientAPIImpl.h"
|
||||
#include <assert.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <fstream>
|
||||
#include "CommunicationMode.h"
|
||||
#include "Logging.h"
|
||||
#include "MQDecoder.h"
|
||||
#include "PullResultExt.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!************************************************************************
|
||||
MQClientAPIImpl::MQClientAPIImpl(const string& mqClientId, bool enableSsl, const std::string& sslPropertyFile)
|
||||
: m_firstFetchNameSrv(true), m_mqClientId(mqClientId) {}
|
||||
MQClientAPIImpl::MQClientAPIImpl(const string& mqClientId,
|
||||
ClientRemotingProcessor* clientRemotingProcessor,
|
||||
int pullThreadNum,
|
||||
uint64_t tcpConnectTimeout,
|
||||
uint64_t tcpTransportTryLockTimeout,
|
||||
string unitName,
|
||||
bool enableSsl,
|
||||
const std::string& sslPropertyFile)
|
||||
: m_firstFetchNameSrv(true), m_mqClientId(mqClientId) {
|
||||
m_pRemotingClient.reset(
|
||||
new TcpRemotingClient(pullThreadNum, tcpConnectTimeout, tcpTransportTryLockTimeout, enableSsl, sslPropertyFile));
|
||||
m_pRemotingClient->registerProcessor(CHECK_TRANSACTION_STATE, clientRemotingProcessor);
|
||||
m_pRemotingClient->registerProcessor(RESET_CONSUMER_CLIENT_OFFSET, clientRemotingProcessor);
|
||||
m_pRemotingClient->registerProcessor(GET_CONSUMER_STATUS_FROM_CLIENT, clientRemotingProcessor);
|
||||
m_pRemotingClient->registerProcessor(GET_CONSUMER_RUNNING_INFO, clientRemotingProcessor);
|
||||
m_pRemotingClient->registerProcessor(NOTIFY_CONSUMER_IDS_CHANGED, clientRemotingProcessor);
|
||||
m_pRemotingClient->registerProcessor(CONSUME_MESSAGE_DIRECTLY, clientRemotingProcessor);
|
||||
|
||||
m_topAddressing.reset(new TopAddressing(unitName));
|
||||
}
|
||||
|
||||
MQClientAPIImpl::~MQClientAPIImpl() {
|
||||
m_pRemotingClient = NULL;
|
||||
m_topAddressing = NULL;
|
||||
}
|
||||
|
||||
void MQClientAPIImpl::stopAllTcpTransportThread() {
|
||||
m_pRemotingClient->stopAllTcpTransportThread();
|
||||
}
|
||||
|
||||
bool MQClientAPIImpl::writeDataToFile(string filename, string data, bool isSync) {
|
||||
if (data.size() == 0)
|
||||
return false;
|
||||
|
||||
FILE* pFd = fopen(filename.c_str(), "w+");
|
||||
if (NULL == pFd) {
|
||||
LOG_ERROR("fopen failed, filename:%s", filename.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
int byte_write = 0;
|
||||
int byte_left = data.size();
|
||||
const char* pData = data.c_str();
|
||||
while (byte_left > 0) {
|
||||
byte_write = fwrite(pData, sizeof(char), byte_left, pFd);
|
||||
if (byte_write == byte_left) {
|
||||
if (ferror(pFd)) {
|
||||
LOG_ERROR("write data fail, data len:" SIZET_FMT ", file:%s, msg:%s", data.size(), filename.c_str(),
|
||||
strerror(errno));
|
||||
fclose(pFd);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
byte_left -= byte_write;
|
||||
pData += byte_write;
|
||||
}
|
||||
pData = NULL;
|
||||
|
||||
if (isSync) {
|
||||
LOG_INFO("fsync with filename:%s", filename.c_str());
|
||||
fflush(pFd);
|
||||
}
|
||||
fclose(pFd);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
string MQClientAPIImpl::fetchNameServerAddr(const string& NSDomain) {
|
||||
try {
|
||||
string homeDir(UtilAll::getHomeDirectory());
|
||||
string storePath = homeDir + "/logs/rocketmq-cpp/snapshot";
|
||||
|
||||
boost::filesystem::path dir(storePath);
|
||||
boost::system::error_code ec;
|
||||
if (!boost::filesystem::exists(dir, ec)) {
|
||||
if (!boost::filesystem::create_directory(dir, ec)) {
|
||||
LOG_ERROR("create data dir:%s error", storePath.c_str());
|
||||
return "";
|
||||
}
|
||||
}
|
||||
string file(storePath);
|
||||
string fileBak(storePath);
|
||||
vector<string> ret_;
|
||||
int retSize = UtilAll::Split(ret_, m_mqClientId, "@");
|
||||
if (retSize == 2) {
|
||||
file.append("/nameserver_addr-").append(ret_[retSize - 1]);
|
||||
} else {
|
||||
LOG_ERROR("split mqClientId:%s fail", m_mqClientId.c_str());
|
||||
file.append("/nameserver_addr-DEFAULT");
|
||||
}
|
||||
boost::filesystem::path snapshot_file(file);
|
||||
fileBak.append("/nameserver_addr.bak");
|
||||
const string addrs = m_topAddressing->fetchNSAddr(NSDomain);
|
||||
if (addrs.empty()) {
|
||||
if (m_nameSrvAddr.empty()) {
|
||||
LOG_INFO("Load the name server snapshot local file:%s", file.c_str());
|
||||
if (boost::filesystem::exists(snapshot_file)) {
|
||||
ifstream snapshot_file(file, ios::binary);
|
||||
istreambuf_iterator<char> beg(snapshot_file), end;
|
||||
string filecontent(beg, end);
|
||||
updateNameServerAddr(filecontent);
|
||||
m_nameSrvAddr = filecontent;
|
||||
} else {
|
||||
LOG_WARN("The name server snapshot local file not exists");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (m_firstFetchNameSrv == true) {
|
||||
// it is the first time, so need to create the name server snapshot
|
||||
// local file
|
||||
m_firstFetchNameSrv = false;
|
||||
}
|
||||
if (addrs.compare(m_nameSrvAddr) != 0) {
|
||||
LOG_INFO("name server address changed, old: %s, new: %s", m_nameSrvAddr.c_str(), addrs.c_str());
|
||||
updateNameServerAddr(addrs);
|
||||
m_nameSrvAddr = addrs;
|
||||
} else {
|
||||
if (!m_firstFetchNameSrv)
|
||||
return m_nameSrvAddr;
|
||||
}
|
||||
// update the snapshot local file if nameSrv changes or
|
||||
// m_firstFetchNameSrv==true
|
||||
if (writeDataToFile(fileBak, addrs, true)) {
|
||||
if (!UtilAll::ReplaceFile(fileBak, file))
|
||||
LOG_ERROR("could not rename bak file:%s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
if (!boost::filesystem::exists(snapshot_file)) {
|
||||
// the name server snapshot local file maybe deleted by force, create it
|
||||
if (writeDataToFile(fileBak, m_nameSrvAddr, true)) {
|
||||
if (!UtilAll::ReplaceFile(fileBak, file))
|
||||
LOG_ERROR("could not rename bak file:%s", strerror(errno));
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
}
|
||||
return m_nameSrvAddr;
|
||||
}
|
||||
|
||||
void MQClientAPIImpl::updateNameServerAddr(const string& addrs) {
|
||||
if (m_pRemotingClient != NULL)
|
||||
m_pRemotingClient->updateNameServerAddressList(addrs);
|
||||
}
|
||||
|
||||
void MQClientAPIImpl::callSignatureBeforeRequest(const string& addr,
|
||||
RemotingCommand& request,
|
||||
const SessionCredentials& session_credentials) {
|
||||
ClientRPCHook rpcHook(session_credentials);
|
||||
rpcHook.doBeforeRequest(addr, request);
|
||||
}
|
||||
|
||||
// Note: all request rules: throw exception if got broker error response,
|
||||
// exclude getTopicRouteInfoFromNameServer and unregisterClient
|
||||
void MQClientAPIImpl::createTopic(const string& addr,
|
||||
const string& defaultTopic,
|
||||
TopicConfig topicConfig,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
string topicWithProjectGroup = topicConfig.getTopicName();
|
||||
CreateTopicRequestHeader* requestHeader = new CreateTopicRequestHeader();
|
||||
requestHeader->topic = (topicWithProjectGroup);
|
||||
requestHeader->defaultTopic = (defaultTopic);
|
||||
requestHeader->readQueueNums = (topicConfig.getReadQueueNums());
|
||||
requestHeader->writeQueueNums = (topicConfig.getWriteQueueNums());
|
||||
requestHeader->perm = (topicConfig.getPerm());
|
||||
requestHeader->topicFilterType = (topicConfig.getTopicFilterType());
|
||||
|
||||
RemotingCommand request(UPDATE_AND_CREATE_TOPIC, requestHeader);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request));
|
||||
|
||||
if (response) {
|
||||
switch (response->getCode()) {
|
||||
case SUCCESS_VALUE:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
|
||||
}
|
||||
|
||||
void MQClientAPIImpl::endTransactionOneway(std::string addr,
|
||||
EndTransactionRequestHeader* requestHeader,
|
||||
std::string remark,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
RemotingCommand request(END_TRANSACTION, requestHeader);
|
||||
request.setRemark(remark);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
m_pRemotingClient->invokeOneway(addr, request);
|
||||
return;
|
||||
}
|
||||
|
||||
SendResult MQClientAPIImpl::sendMessage(const string& addr,
|
||||
const string& brokerName,
|
||||
const MQMessage& msg,
|
||||
SendMessageRequestHeader* pRequestHeader,
|
||||
int timeoutMillis,
|
||||
int maxRetrySendTimes,
|
||||
int communicationMode,
|
||||
SendCallback* pSendCallback,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
// RemotingCommand request(SEND_MESSAGE, pRequestHeader);
|
||||
// Using MQ V2 Protocol to end messages.
|
||||
SendMessageRequestHeaderV2* pRequestHeaderV2 = new SendMessageRequestHeaderV2(*pRequestHeader);
|
||||
RemotingCommand request(SEND_MESSAGE_V2, pRequestHeaderV2);
|
||||
delete pRequestHeader; // delete to avoid memory leak.
|
||||
string body = msg.getBody();
|
||||
request.SetBody(body.c_str(), body.length());
|
||||
request.setMsgBody(body);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
switch (communicationMode) {
|
||||
case ComMode_ONEWAY:
|
||||
m_pRemotingClient->invokeOneway(addr, request);
|
||||
break;
|
||||
case ComMode_ASYNC:
|
||||
sendMessageAsync(addr, brokerName, msg, request, pSendCallback, timeoutMillis, maxRetrySendTimes, 1);
|
||||
break;
|
||||
case ComMode_SYNC:
|
||||
return sendMessageSync(addr, brokerName, msg, request, timeoutMillis);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return SendResult();
|
||||
}
|
||||
|
||||
void MQClientAPIImpl::sendHeartbeat(const string& addr,
|
||||
HeartbeatData* pHeartbeatData,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
RemotingCommand request(HEART_BEAT, NULL);
|
||||
|
||||
string body;
|
||||
pHeartbeatData->Encode(body);
|
||||
request.SetBody(body.data(), body.length());
|
||||
request.setMsgBody(body);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
if (m_pRemotingClient->invokeHeartBeat(addr, request)) {
|
||||
LOG_DEBUG("sendHeartbeat to broker:%s success", addr.c_str());
|
||||
} else {
|
||||
LOG_WARN("sendHeartbeat to broker:%s failed", addr.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void MQClientAPIImpl::unregisterClient(const string& addr,
|
||||
const string& clientID,
|
||||
const string& producerGroup,
|
||||
const string& consumerGroup,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
LOG_INFO("unregisterClient to broker:%s", addr.c_str());
|
||||
RemotingCommand request(UNREGISTER_CLIENT, new UnregisterClientRequestHeader(clientID, producerGroup, consumerGroup));
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request));
|
||||
|
||||
if (response) {
|
||||
switch (response->getCode()) {
|
||||
case SUCCESS_VALUE:
|
||||
LOG_INFO("unregisterClient to:%s success", addr.c_str());
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
LOG_WARN("unregisterClient fail:%s,%d", response->getRemark().c_str(), response->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
// return NULL if got no response or error response
|
||||
TopicRouteData* MQClientAPIImpl::getTopicRouteInfoFromNameServer(const string& topic,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
RemotingCommand request(GET_ROUTEINTO_BY_TOPIC, new GetRouteInfoRequestHeader(topic));
|
||||
callSignatureBeforeRequest("", request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync("", request, timeoutMillis));
|
||||
|
||||
if (pResponse != NULL) {
|
||||
if (((*(pResponse->GetBody())).getSize() == 0) || ((*(pResponse->GetBody())).getData() != NULL)) {
|
||||
switch (pResponse->getCode()) {
|
||||
case SUCCESS_VALUE: {
|
||||
const MemoryBlock* pbody = pResponse->GetBody();
|
||||
if (pbody->getSize()) {
|
||||
TopicRouteData* topicRoute = TopicRouteData::Decode(pbody);
|
||||
return topicRoute;
|
||||
}
|
||||
}
|
||||
case TOPIC_NOT_EXIST: {
|
||||
LOG_WARN("Get topic[%s] route failed [TOPIC_NOT_EXIST].", topic.c_str());
|
||||
return NULL;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
LOG_WARN("%s,%d", pResponse->getRemark().c_str(), pResponse->getCode());
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
LOG_WARN("Get topic[%s] route failed [Null Response].", topic.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TopicList* MQClientAPIImpl::getTopicListFromNameServer(const SessionCredentials& sessionCredentials) {
|
||||
RemotingCommand request(GET_ALL_TOPIC_LIST_FROM_NAMESERVER, NULL);
|
||||
callSignatureBeforeRequest("", request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync("", request));
|
||||
if (pResponse != NULL) {
|
||||
if (((*(pResponse->GetBody())).getSize() == 0) || ((*(pResponse->GetBody())).getData() != NULL)) {
|
||||
switch (pResponse->getCode()) {
|
||||
case SUCCESS_VALUE: {
|
||||
const MemoryBlock* pbody = pResponse->GetBody();
|
||||
if (pbody->getSize()) {
|
||||
TopicList* topicList = TopicList::Decode(pbody);
|
||||
return topicList;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
THROW_MQEXCEPTION(MQClientException, pResponse->getRemark(), pResponse->getCode());
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int MQClientAPIImpl::wipeWritePermOfBroker(const string& namesrvAddr, const string& brokerName, int timeoutMillis) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MQClientAPIImpl::deleteTopicInBroker(const string& addr, const string& topic, int timeoutMillis) {}
|
||||
|
||||
void MQClientAPIImpl::deleteTopicInNameServer(const string& addr, const string& topic, int timeoutMillis) {}
|
||||
|
||||
void MQClientAPIImpl::deleteSubscriptionGroup(const string& addr, const string& groupName, int timeoutMillis) {}
|
||||
|
||||
string MQClientAPIImpl::getKVConfigByValue(const string& projectNamespace,
|
||||
const string& projectGroup,
|
||||
int timeoutMillis) {
|
||||
return "";
|
||||
}
|
||||
|
||||
KVTable MQClientAPIImpl::getKVListByNamespace(const string& projectNamespace, int timeoutMillis) {
|
||||
return KVTable();
|
||||
}
|
||||
|
||||
void MQClientAPIImpl::deleteKVConfigByValue(const string& projectNamespace,
|
||||
const string& projectGroup,
|
||||
int timeoutMillis) {}
|
||||
|
||||
SendResult MQClientAPIImpl::sendMessageSync(const string& addr,
|
||||
const string& brokerName,
|
||||
const MQMessage& msg,
|
||||
RemotingCommand& request,
|
||||
int timeoutMillis) {
|
||||
//<!block util response;
|
||||
unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
|
||||
if (pResponse != NULL) {
|
||||
try {
|
||||
SendResult result = processSendResponse(brokerName, msg, pResponse.get());
|
||||
LOG_DEBUG("sendMessageSync success:%s to addr:%s,brokername:%s, send status:%d", msg.toString().c_str(),
|
||||
addr.c_str(), brokerName.c_str(), (int)result.getSendStatus());
|
||||
return result;
|
||||
} catch (...) {
|
||||
LOG_ERROR("send error");
|
||||
}
|
||||
}
|
||||
THROW_MQEXCEPTION(MQClientException, "response is null", -1);
|
||||
}
|
||||
|
||||
void MQClientAPIImpl::sendMessageAsync(const string& addr,
|
||||
const string& brokerName,
|
||||
const MQMessage& msg,
|
||||
RemotingCommand& request,
|
||||
SendCallback* pSendCallback,
|
||||
int64 timeoutMilliseconds,
|
||||
int maxRetryTimes,
|
||||
int retrySendTimes) {
|
||||
int64 begin_time = UtilAll::currentTimeMillis();
|
||||
//<!delete in future;
|
||||
// AsyncCallbackWrap* cbw = new SendCallbackWrap(brokerName, msg, pSendCallback, this);
|
||||
|
||||
LOG_DEBUG("sendMessageAsync request:%s, timeout:%lld, maxRetryTimes:%d retrySendTimes:%d", request.ToString().data(),
|
||||
timeoutMilliseconds, maxRetryTimes, retrySendTimes);
|
||||
// Use smart ptr to control cbw.
|
||||
std::shared_ptr<AsyncCallbackWrap> cbw = std::make_shared<SendCallbackWrap>(brokerName, msg, pSendCallback, this);
|
||||
if (m_pRemotingClient->invokeAsync(addr, request, cbw, timeoutMilliseconds, maxRetryTimes, retrySendTimes) == false) {
|
||||
LOG_WARN("invokeAsync failed to addr:%s,topic:%s, timeout:%lld, maxRetryTimes:%d, retrySendTimes:%d", addr.c_str(),
|
||||
msg.getTopic().data(), timeoutMilliseconds, maxRetryTimes, retrySendTimes);
|
||||
// when getTcp return false, need consider retrySendTimes
|
||||
int retry_time = retrySendTimes + 1;
|
||||
int64 time_out = timeoutMilliseconds - (UtilAll::currentTimeMillis() - begin_time);
|
||||
while (retry_time < maxRetryTimes && time_out > 0) {
|
||||
begin_time = UtilAll::currentTimeMillis();
|
||||
if (m_pRemotingClient->invokeAsync(addr, request, cbw, time_out, maxRetryTimes, retry_time) == false) {
|
||||
retry_time += 1;
|
||||
time_out = time_out - (UtilAll::currentTimeMillis() - begin_time);
|
||||
LOG_WARN("invokeAsync retry failed to addr:%s,topic:%s, timeout:%lld, maxRetryTimes:%d, retrySendTimes:%d",
|
||||
addr.c_str(), msg.getTopic().data(), time_out, maxRetryTimes, retry_time);
|
||||
continue;
|
||||
} else {
|
||||
return; // invokeAsync success
|
||||
}
|
||||
}
|
||||
|
||||
LOG_ERROR("sendMessageAsync failed to addr:%s,topic:%s, timeout:%lld, maxRetryTimes:%d, retrySendTimes:%d",
|
||||
addr.c_str(), msg.getTopic().data(), time_out, maxRetryTimes, retrySendTimes);
|
||||
|
||||
if (cbw && pSendCallback != nullptr) {
|
||||
cbw->onException();
|
||||
// deleteAndZero(cbw);
|
||||
} else {
|
||||
THROW_MQEXCEPTION(MQClientException, "sendMessageAsync failed", -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PullResult* MQClientAPIImpl::pullMessage(const string& addr,
|
||||
PullMessageRequestHeader* pRequestHeader,
|
||||
int timeoutMillis,
|
||||
int communicationMode,
|
||||
PullCallback* pullCallback,
|
||||
void* pArg,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
RemotingCommand request(PULL_MESSAGE, pRequestHeader);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
switch (communicationMode) {
|
||||
case ComMode_ONEWAY:
|
||||
break;
|
||||
case ComMode_ASYNC:
|
||||
pullMessageAsync(addr, request, timeoutMillis, pullCallback, pArg);
|
||||
break;
|
||||
case ComMode_SYNC:
|
||||
return pullMessageSync(addr, request, timeoutMillis);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void MQClientAPIImpl::pullMessageAsync(const string& addr,
|
||||
RemotingCommand& request,
|
||||
int timeoutMillis,
|
||||
PullCallback* pullCallback,
|
||||
void* pArg) {
|
||||
// AsyncCallbackWrap* cbw = new PullCallbackWrap(pullCallback, this, pArg);
|
||||
std::shared_ptr<AsyncCallbackWrap> cbw = std::make_shared<PullCallbackWrap>(pullCallback, this, pArg);
|
||||
if (m_pRemotingClient->invokeAsync(addr, request, cbw, timeoutMillis) == false) {
|
||||
LOG_ERROR("pullMessageAsync failed of addr:%s, mq:%s", addr.c_str(),
|
||||
static_cast<AsyncArg*>(pArg)->mq.toString().data());
|
||||
// deleteAndZero(cbw);
|
||||
THROW_MQEXCEPTION(MQClientException, "pullMessageAsync failed", -1);
|
||||
}
|
||||
}
|
||||
|
||||
PullResult* MQClientAPIImpl::pullMessageSync(const string& addr, RemotingCommand& request, int timeoutMillis) {
|
||||
unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
|
||||
if (pResponse != NULL) {
|
||||
if (((*(pResponse->GetBody())).getSize() == 0) || ((*(pResponse->GetBody())).getData() != NULL)) {
|
||||
try {
|
||||
PullResult* pullResult = processPullResponse(pResponse.get()); // pullMessage will handle
|
||||
// exception from
|
||||
// processPullResponse
|
||||
return pullResult;
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("%s", e.what());
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SendResult MQClientAPIImpl::processSendResponse(const string& brokerName,
|
||||
const MQMessage& msg,
|
||||
RemotingCommand* pResponse) {
|
||||
SendStatus sendStatus = SEND_OK;
|
||||
int res = 0;
|
||||
switch (pResponse->getCode()) {
|
||||
case FLUSH_DISK_TIMEOUT:
|
||||
sendStatus = SEND_FLUSH_DISK_TIMEOUT;
|
||||
break;
|
||||
case FLUSH_SLAVE_TIMEOUT:
|
||||
sendStatus = SEND_FLUSH_SLAVE_TIMEOUT;
|
||||
break;
|
||||
case SLAVE_NOT_AVAILABLE:
|
||||
sendStatus = SEND_SLAVE_NOT_AVAILABLE;
|
||||
break;
|
||||
case SUCCESS_VALUE:
|
||||
sendStatus = SEND_OK;
|
||||
break;
|
||||
default:
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
if (res == 0) {
|
||||
SendMessageResponseHeader* responseHeader = (SendMessageResponseHeader*)pResponse->getCommandHeader();
|
||||
MQMessageQueue messageQueue(msg.getTopic(), brokerName, responseHeader->queueId);
|
||||
string unique_msgId = msg.getProperty(MQMessage::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX);
|
||||
return SendResult(sendStatus, unique_msgId, responseHeader->msgId, messageQueue, responseHeader->queueOffset,
|
||||
responseHeader->regionId);
|
||||
}
|
||||
LOG_ERROR("processSendResponse error remark:%s, error code:%d", (pResponse->getRemark()).c_str(),
|
||||
pResponse->getCode());
|
||||
THROW_MQEXCEPTION(MQClientException, pResponse->getRemark(), pResponse->getCode());
|
||||
}
|
||||
|
||||
PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* pResponse) {
|
||||
PullStatus pullStatus = NO_NEW_MSG;
|
||||
switch (pResponse->getCode()) {
|
||||
case SUCCESS_VALUE:
|
||||
pullStatus = FOUND;
|
||||
break;
|
||||
case PULL_NOT_FOUND:
|
||||
pullStatus = NO_NEW_MSG;
|
||||
break;
|
||||
case PULL_RETRY_IMMEDIATELY:
|
||||
pullStatus = NO_MATCHED_MSG;
|
||||
break;
|
||||
case PULL_OFFSET_MOVED:
|
||||
pullStatus = OFFSET_ILLEGAL;
|
||||
break;
|
||||
default:
|
||||
THROW_MQEXCEPTION(MQBrokerException, pResponse->getRemark(), pResponse->getCode());
|
||||
break;
|
||||
}
|
||||
|
||||
PullMessageResponseHeader* responseHeader = static_cast<PullMessageResponseHeader*>(pResponse->getCommandHeader());
|
||||
|
||||
if (!responseHeader) {
|
||||
LOG_ERROR("processPullResponse:responseHeader is NULL");
|
||||
THROW_MQEXCEPTION(MQClientException, "processPullResponse:responseHeader is NULL", -1);
|
||||
}
|
||||
//<!get body,delete outsite;
|
||||
MemoryBlock bodyFromResponse = *(pResponse->GetBody()); // response data judgement had been done outside
|
||||
// of processPullResponse
|
||||
if (bodyFromResponse.getSize() == 0) {
|
||||
if (pullStatus != FOUND) {
|
||||
return new PullResultExt(pullStatus, responseHeader->nextBeginOffset, responseHeader->minOffset,
|
||||
responseHeader->maxOffset, (int)responseHeader->suggestWhichBrokerId);
|
||||
} else {
|
||||
THROW_MQEXCEPTION(MQClientException, "memoryBody size is 0, but pullStatus equals found", -1);
|
||||
}
|
||||
} else {
|
||||
return new PullResultExt(pullStatus, responseHeader->nextBeginOffset, responseHeader->minOffset,
|
||||
responseHeader->maxOffset, (int)responseHeader->suggestWhichBrokerId, bodyFromResponse);
|
||||
}
|
||||
}
|
||||
|
||||
//<!***************************************************************************
|
||||
int64 MQClientAPIImpl::getMinOffset(const string& addr,
|
||||
const string& topic,
|
||||
int queueId,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
GetMinOffsetRequestHeader* pRequestHeader = new GetMinOffsetRequestHeader();
|
||||
pRequestHeader->topic = topic;
|
||||
pRequestHeader->queueId = queueId;
|
||||
|
||||
RemotingCommand request(GET_MIN_OFFSET, pRequestHeader);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
|
||||
|
||||
if (response) {
|
||||
switch (response->getCode()) {
|
||||
case SUCCESS_VALUE: {
|
||||
GetMinOffsetResponseHeader* responseHeader = (GetMinOffsetResponseHeader*)response->getCommandHeader();
|
||||
|
||||
int64 offset = responseHeader->offset;
|
||||
return offset;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
|
||||
}
|
||||
|
||||
int64 MQClientAPIImpl::getMaxOffset(const string& addr,
|
||||
const string& topic,
|
||||
int queueId,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
GetMaxOffsetRequestHeader* pRequestHeader = new GetMaxOffsetRequestHeader();
|
||||
pRequestHeader->topic = topic;
|
||||
pRequestHeader->queueId = queueId;
|
||||
|
||||
RemotingCommand request(GET_MAX_OFFSET, pRequestHeader);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
|
||||
|
||||
if (response) {
|
||||
switch (response->getCode()) {
|
||||
case SUCCESS_VALUE: {
|
||||
GetMaxOffsetResponseHeader* responseHeader = (GetMaxOffsetResponseHeader*)response->getCommandHeader();
|
||||
|
||||
int64 offset = responseHeader->offset;
|
||||
return offset;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
|
||||
}
|
||||
|
||||
int64 MQClientAPIImpl::searchOffset(const string& addr,
|
||||
const string& topic,
|
||||
int queueId,
|
||||
uint64_t timestamp,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
SearchOffsetRequestHeader* pRequestHeader = new SearchOffsetRequestHeader();
|
||||
pRequestHeader->topic = topic;
|
||||
pRequestHeader->queueId = queueId;
|
||||
pRequestHeader->timestamp = timestamp;
|
||||
|
||||
RemotingCommand request(SEARCH_OFFSET_BY_TIMESTAMP, pRequestHeader);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
|
||||
|
||||
if (response) {
|
||||
switch (response->getCode()) {
|
||||
case SUCCESS_VALUE: {
|
||||
SearchOffsetResponseHeader* responseHeader = (SearchOffsetResponseHeader*)response->getCommandHeader();
|
||||
|
||||
int64 offset = responseHeader->offset;
|
||||
return offset;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
|
||||
}
|
||||
|
||||
MQMessageExt* MQClientAPIImpl::viewMessage(const string& addr,
|
||||
int64 phyoffset,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
ViewMessageRequestHeader* pRequestHeader = new ViewMessageRequestHeader();
|
||||
pRequestHeader->offset = phyoffset;
|
||||
|
||||
RemotingCommand request(VIEW_MESSAGE_BY_ID, pRequestHeader);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
|
||||
|
||||
if (response) {
|
||||
switch (response->getCode()) {
|
||||
case SUCCESS_VALUE: {
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
|
||||
}
|
||||
|
||||
int64 MQClientAPIImpl::getEarliestMsgStoretime(const string& addr,
|
||||
const string& topic,
|
||||
int queueId,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
GetEarliestMsgStoretimeRequestHeader* pRequestHeader = new GetEarliestMsgStoretimeRequestHeader();
|
||||
pRequestHeader->topic = topic;
|
||||
pRequestHeader->queueId = queueId;
|
||||
|
||||
RemotingCommand request(GET_EARLIEST_MSG_STORETIME, pRequestHeader);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
|
||||
|
||||
if (response) {
|
||||
switch (response->getCode()) {
|
||||
case SUCCESS_VALUE: {
|
||||
GetEarliestMsgStoretimeResponseHeader* responseHeader =
|
||||
(GetEarliestMsgStoretimeResponseHeader*)response->getCommandHeader();
|
||||
|
||||
int64 timestamp = responseHeader->timestamp;
|
||||
return timestamp;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
|
||||
}
|
||||
|
||||
void MQClientAPIImpl::getConsumerIdListByGroup(const string& addr,
|
||||
const string& consumerGroup,
|
||||
vector<string>& cids,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
GetConsumerListByGroupRequestHeader* pRequestHeader = new GetConsumerListByGroupRequestHeader();
|
||||
pRequestHeader->consumerGroup = consumerGroup;
|
||||
|
||||
RemotingCommand request(GET_CONSUMER_LIST_BY_GROUP, pRequestHeader);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
|
||||
|
||||
if (pResponse != NULL) {
|
||||
if ((pResponse->GetBody()->getSize() == 0) || (pResponse->GetBody()->getData() != NULL)) {
|
||||
switch (pResponse->getCode()) {
|
||||
case SUCCESS_VALUE: {
|
||||
const MemoryBlock* pbody = pResponse->GetBody();
|
||||
if (pbody->getSize()) {
|
||||
GetConsumerListByGroupResponseBody::Decode(pbody, cids);
|
||||
return;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, pResponse->getRemark(), pResponse->getCode());
|
||||
}
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
|
||||
}
|
||||
|
||||
int64 MQClientAPIImpl::queryConsumerOffset(const string& addr,
|
||||
QueryConsumerOffsetRequestHeader* pRequestHeader,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
RemotingCommand request(QUERY_CONSUMER_OFFSET, pRequestHeader);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
|
||||
|
||||
if (response) {
|
||||
switch (response->getCode()) {
|
||||
case SUCCESS_VALUE: {
|
||||
QueryConsumerOffsetResponseHeader* responseHeader =
|
||||
(QueryConsumerOffsetResponseHeader*)response->getCommandHeader();
|
||||
int64 consumerOffset = responseHeader->offset;
|
||||
return consumerOffset;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void MQClientAPIImpl::updateConsumerOffset(const string& addr,
|
||||
UpdateConsumerOffsetRequestHeader* pRequestHeader,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
RemotingCommand request(UPDATE_CONSUMER_OFFSET, pRequestHeader);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
|
||||
|
||||
if (response) {
|
||||
switch (response->getCode()) {
|
||||
case SUCCESS_VALUE: {
|
||||
return;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
|
||||
}
|
||||
|
||||
void MQClientAPIImpl::updateConsumerOffsetOneway(const string& addr,
|
||||
UpdateConsumerOffsetRequestHeader* pRequestHeader,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
RemotingCommand request(UPDATE_CONSUMER_OFFSET, pRequestHeader);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
m_pRemotingClient->invokeOneway(addr, request);
|
||||
}
|
||||
|
||||
void MQClientAPIImpl::consumerSendMessageBack(const string addr,
|
||||
MQMessageExt& msg,
|
||||
const string& consumerGroup,
|
||||
int delayLevel,
|
||||
int timeoutMillis,
|
||||
int maxReconsumeTimes,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
ConsumerSendMsgBackRequestHeader* pRequestHeader = new ConsumerSendMsgBackRequestHeader();
|
||||
pRequestHeader->group = consumerGroup;
|
||||
pRequestHeader->offset = msg.getCommitLogOffset();
|
||||
pRequestHeader->delayLevel = delayLevel;
|
||||
pRequestHeader->unitMode = false;
|
||||
pRequestHeader->originTopic = msg.getTopic();
|
||||
pRequestHeader->originMsgId = msg.getMsgId();
|
||||
pRequestHeader->maxReconsumeTimes = maxReconsumeTimes;
|
||||
|
||||
// string addr = socketAddress2IPPort(msg.getStoreHost());
|
||||
RemotingCommand request(CONSUMER_SEND_MSG_BACK, pRequestHeader);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
|
||||
|
||||
if (response) {
|
||||
switch (response->getCode()) {
|
||||
case SUCCESS_VALUE: {
|
||||
return;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
|
||||
}
|
||||
|
||||
void MQClientAPIImpl::lockBatchMQ(const string& addr,
|
||||
LockBatchRequestBody* requestBody,
|
||||
vector<MQMessageQueue>& mqs,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
RemotingCommand request(LOCK_BATCH_MQ, NULL);
|
||||
string body;
|
||||
requestBody->Encode(body);
|
||||
request.SetBody(body.data(), body.length());
|
||||
request.setMsgBody(body);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
|
||||
|
||||
if (pResponse != NULL) {
|
||||
if (((*(pResponse->GetBody())).getSize() == 0) || ((*(pResponse->GetBody())).getData() != NULL)) {
|
||||
switch (pResponse->getCode()) {
|
||||
case SUCCESS_VALUE: {
|
||||
const MemoryBlock* pbody = pResponse->GetBody();
|
||||
if (pbody->getSize()) {
|
||||
LockBatchResponseBody::Decode(pbody, mqs);
|
||||
}
|
||||
return;
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, pResponse->getRemark(), pResponse->getCode());
|
||||
}
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
|
||||
}
|
||||
|
||||
void MQClientAPIImpl::unlockBatchMQ(const string& addr,
|
||||
UnlockBatchRequestBody* requestBody,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials) {
|
||||
RemotingCommand request(UNLOCK_BATCH_MQ, NULL);
|
||||
string body;
|
||||
requestBody->Encode(body);
|
||||
request.SetBody(body.data(), body.length());
|
||||
request.setMsgBody(body);
|
||||
callSignatureBeforeRequest(addr, request, sessionCredentials);
|
||||
request.Encode();
|
||||
|
||||
unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
|
||||
|
||||
if (pResponse != NULL) {
|
||||
switch (pResponse->getCode()) {
|
||||
case SUCCESS_VALUE: {
|
||||
return;
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, pResponse->getRemark(), pResponse->getCode());
|
||||
}
|
||||
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
|
||||
}
|
||||
|
||||
//<!************************************************************************
|
||||
} // namespace rocketmq
|
||||
233
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/MQClientAPIImpl.h
vendored
Normal file
233
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/MQClientAPIImpl.h
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __MQCLIENTAPIIMPL_H__
|
||||
#define __MQCLIENTAPIIMPL_H__
|
||||
#include "AsyncCallback.h"
|
||||
#include "ClientRPCHook.h"
|
||||
#include "ClientRemotingProcessor.h"
|
||||
#include "CommandHeader.h"
|
||||
#include "HeartbeatData.h"
|
||||
#include "KVTable.h"
|
||||
#include "LockBatchBody.h"
|
||||
#include "MQClientException.h"
|
||||
#include "MQMessageExt.h"
|
||||
#include "MQProtos.h"
|
||||
#include "SendResult.h"
|
||||
#include "SocketUtil.h"
|
||||
#include "TcpRemotingClient.h"
|
||||
#include "TopAddressing.h"
|
||||
#include "TopicConfig.h"
|
||||
#include "TopicList.h"
|
||||
#include "TopicRouteData.h"
|
||||
#include "UtilAll.h"
|
||||
#include "VirtualEnvUtil.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!wrap all API to net ;
|
||||
//<!************************************************************************
|
||||
class MQClientAPIImpl {
|
||||
public:
|
||||
MQClientAPIImpl(const string& mqClientId, bool enableSsl, const std::string& sslPropertyFile);
|
||||
MQClientAPIImpl(const string& mqClientId,
|
||||
ClientRemotingProcessor* clientRemotingProcessor,
|
||||
int pullThreadNum,
|
||||
uint64_t tcpConnectTimeout,
|
||||
uint64_t tcpTransportTryLockTimeout,
|
||||
string unitName,
|
||||
bool enableSsl,
|
||||
const std::string& sslPropertyFile);
|
||||
virtual ~MQClientAPIImpl();
|
||||
virtual void stopAllTcpTransportThread();
|
||||
virtual bool writeDataToFile(string filename, string data, bool isSync);
|
||||
virtual string fetchNameServerAddr(const string& NSDomain);
|
||||
virtual void updateNameServerAddr(const string& addrs);
|
||||
|
||||
virtual void callSignatureBeforeRequest(const string& addr,
|
||||
RemotingCommand& request,
|
||||
const SessionCredentials& session_credentials);
|
||||
virtual void createTopic(const string& addr,
|
||||
const string& defaultTopic,
|
||||
TopicConfig topicConfig,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
virtual void endTransactionOneway(std::string addr,
|
||||
EndTransactionRequestHeader* requestHeader,
|
||||
std::string remark,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual SendResult sendMessage(const string& addr,
|
||||
const string& brokerName,
|
||||
const MQMessage& msg,
|
||||
SendMessageRequestHeader* pRequestHeader,
|
||||
int timeoutMillis,
|
||||
int maxRetrySendTimes,
|
||||
int communicationMode,
|
||||
SendCallback* pSendCallback,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual PullResult* pullMessage(const string& addr,
|
||||
PullMessageRequestHeader* pRequestHeader,
|
||||
int timeoutMillis,
|
||||
int communicationMode,
|
||||
PullCallback* pullCallback,
|
||||
void* pArg,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual void sendHeartbeat(const string& addr,
|
||||
HeartbeatData* pHeartbeatData,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual void unregisterClient(const string& addr,
|
||||
const string& clientID,
|
||||
const string& producerGroup,
|
||||
const string& consumerGroup,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual TopicRouteData* getTopicRouteInfoFromNameServer(const string& topic,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual TopicList* getTopicListFromNameServer(const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual int wipeWritePermOfBroker(const string& namesrvAddr, const string& brokerName, int timeoutMillis);
|
||||
|
||||
virtual void deleteTopicInBroker(const string& addr, const string& topic, int timeoutMillis);
|
||||
|
||||
virtual void deleteTopicInNameServer(const string& addr, const string& topic, int timeoutMillis);
|
||||
|
||||
virtual void deleteSubscriptionGroup(const string& addr, const string& groupName, int timeoutMillis);
|
||||
|
||||
virtual string getKVConfigByValue(const string& projectNamespace, const string& projectGroup, int timeoutMillis);
|
||||
|
||||
virtual KVTable getKVListByNamespace(const string& projectNamespace, int timeoutMillis);
|
||||
|
||||
virtual void deleteKVConfigByValue(const string& projectNamespace, const string& projectGroup, int timeoutMillis);
|
||||
|
||||
virtual SendResult processSendResponse(const string& brokerName, const MQMessage& msg, RemotingCommand* pResponse);
|
||||
|
||||
virtual PullResult* processPullResponse(RemotingCommand* pResponse);
|
||||
|
||||
virtual int64 getMinOffset(const string& addr,
|
||||
const string& topic,
|
||||
int queueId,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual int64 getMaxOffset(const string& addr,
|
||||
const string& topic,
|
||||
int queueId,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual int64 searchOffset(const string& addr,
|
||||
const string& topic,
|
||||
int queueId,
|
||||
uint64_t timestamp,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual MQMessageExt* viewMessage(const string& addr,
|
||||
int64 phyoffset,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual int64 getEarliestMsgStoretime(const string& addr,
|
||||
const string& topic,
|
||||
int queueId,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual void getConsumerIdListByGroup(const string& addr,
|
||||
const string& consumerGroup,
|
||||
vector<string>& cids,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual int64 queryConsumerOffset(const string& addr,
|
||||
QueryConsumerOffsetRequestHeader* pRequestHeader,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual void updateConsumerOffset(const string& addr,
|
||||
UpdateConsumerOffsetRequestHeader* pRequestHeader,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual void updateConsumerOffsetOneway(const string& addr,
|
||||
UpdateConsumerOffsetRequestHeader* pRequestHeader,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual void consumerSendMessageBack(const string addr,
|
||||
MQMessageExt& msg,
|
||||
const string& consumerGroup,
|
||||
int delayLevel,
|
||||
int timeoutMillis,
|
||||
int maxReconsumeTimes,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual void lockBatchMQ(const string& addr,
|
||||
LockBatchRequestBody* requestBody,
|
||||
vector<MQMessageQueue>& mqs,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual void unlockBatchMQ(const string& addr,
|
||||
UnlockBatchRequestBody* requestBody,
|
||||
int timeoutMillis,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
|
||||
virtual void sendMessageAsync(const string& addr,
|
||||
const string& brokerName,
|
||||
const MQMessage& msg,
|
||||
RemotingCommand& request,
|
||||
SendCallback* pSendCallback,
|
||||
int64 timeoutMilliseconds,
|
||||
int maxRetryTimes = 1,
|
||||
int retrySendTimes = 1);
|
||||
|
||||
private:
|
||||
SendResult sendMessageSync(const string& addr,
|
||||
const string& brokerName,
|
||||
const MQMessage& msg,
|
||||
RemotingCommand& request,
|
||||
int timeoutMillis);
|
||||
/*
|
||||
void sendMessageAsync(const string& addr, const string& brokerName,
|
||||
const MQMessage& msg, RemotingCommand& request,
|
||||
SendCallback* pSendCallback, int64 timeoutMilliseconds);
|
||||
*/
|
||||
PullResult* pullMessageSync(const string& addr, RemotingCommand& request, int timeoutMillis);
|
||||
|
||||
void pullMessageAsync(const string& addr,
|
||||
RemotingCommand& request,
|
||||
int timeoutMillis,
|
||||
PullCallback* pullCallback,
|
||||
void* pArg);
|
||||
|
||||
protected:
|
||||
unique_ptr<TcpRemotingClient> m_pRemotingClient;
|
||||
|
||||
private:
|
||||
unique_ptr<TopAddressing> m_topAddressing;
|
||||
string m_nameSrvAddr;
|
||||
bool m_firstFetchNameSrv;
|
||||
string m_mqClientId;
|
||||
};
|
||||
} // namespace rocketmq
|
||||
//<!***************************************************************************
|
||||
#endif
|
||||
1230
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/MQClientFactory.cpp
vendored
Normal file
1230
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/MQClientFactory.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
221
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/MQClientFactory.h
vendored
Normal file
221
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/MQClientFactory.h
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __MQCLIENTFACTORY_H__
|
||||
#define __MQCLIENTFACTORY_H__
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include "FindBrokerResult.h"
|
||||
#include "MQClientAPIImpl.h"
|
||||
#include "MQClientException.h"
|
||||
#include "MQConsumer.h"
|
||||
#include "MQDecoder.h"
|
||||
#include "MQMessageQueue.h"
|
||||
#include "MQProducer.h"
|
||||
#include "PermName.h"
|
||||
#include "QueryResult.h"
|
||||
#include "ServiceState.h"
|
||||
#include "SocketUtil.h"
|
||||
#include "TopicConfig.h"
|
||||
#include "TopicRouteData.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!************************************************************************
|
||||
class TopicPublishInfo;
|
||||
class MQClientFactory {
|
||||
public:
|
||||
MQClientFactory(const string& clientID,
|
||||
int pullThreadNum,
|
||||
uint64_t tcpConnectTimeout,
|
||||
uint64_t tcpTransportTryLockTimeout,
|
||||
string unitName,
|
||||
bool enableSsl,
|
||||
const std::string& sslPropertyFile);
|
||||
MQClientFactory(const string& clientID, bool enableSsl, const std::string& sslPropertyFile);
|
||||
virtual ~MQClientFactory();
|
||||
|
||||
virtual void start();
|
||||
virtual void shutdown();
|
||||
virtual bool registerProducer(MQProducer* pProducer);
|
||||
virtual void unregisterProducer(MQProducer* pProducer);
|
||||
virtual bool registerConsumer(MQConsumer* pConsumer);
|
||||
virtual void unregisterConsumer(MQConsumer* pConsumer);
|
||||
|
||||
void createTopic(const string& key,
|
||||
const string& newTopic,
|
||||
int queueNum,
|
||||
const SessionCredentials& session_credentials);
|
||||
int64 minOffset(const MQMessageQueue& mq, const SessionCredentials& session_credentials);
|
||||
int64 maxOffset(const MQMessageQueue& mq, const SessionCredentials& session_credentials);
|
||||
int64 searchOffset(const MQMessageQueue& mq, int64 timestamp, const SessionCredentials& session_credentials);
|
||||
int64 earliestMsgStoreTime(const MQMessageQueue& mq, const SessionCredentials& session_credentials);
|
||||
MQMessageExt* viewMessage(const string& msgId, const SessionCredentials& session_credentials);
|
||||
QueryResult queryMessage(const string& topic,
|
||||
const string& key,
|
||||
int maxNum,
|
||||
int64 begin,
|
||||
int64 end,
|
||||
const SessionCredentials& session_credentials);
|
||||
void endTransactionOneway(const MQMessageQueue& mq,
|
||||
EndTransactionRequestHeader* requestHeader,
|
||||
const SessionCredentials& sessionCredentials);
|
||||
void checkTransactionState(const std::string& addr,
|
||||
const MQMessageExt& message,
|
||||
const CheckTransactionStateRequestHeader& checkRequestHeader);
|
||||
virtual MQClientAPIImpl* getMQClientAPIImpl();
|
||||
MQProducer* selectProducer(const string& group);
|
||||
MQConsumer* selectConsumer(const string& group);
|
||||
|
||||
boost::shared_ptr<TopicPublishInfo> topicRouteData2TopicPublishInfo(const string& topic, TopicRouteData* pRoute);
|
||||
|
||||
void topicRouteData2TopicSubscribeInfo(const string& topic, TopicRouteData* pRoute, vector<MQMessageQueue>& mqs);
|
||||
|
||||
FindBrokerResult* findBrokerAddressInSubscribe(const string& brokerName, int brokerId, bool onlyThisBroker);
|
||||
|
||||
FindBrokerResult* findBrokerAddressInAdmin(const string& brokerName);
|
||||
|
||||
virtual string findBrokerAddressInPublish(const string& brokerName);
|
||||
|
||||
virtual boost::shared_ptr<TopicPublishInfo> tryToFindTopicPublishInfo(const string& topic,
|
||||
const SessionCredentials& session_credentials);
|
||||
|
||||
void fetchSubscribeMessageQueues(const string& topic,
|
||||
vector<MQMessageQueue>& mqs,
|
||||
const SessionCredentials& session_credentials);
|
||||
|
||||
bool updateTopicRouteInfoFromNameServer(const string& topic,
|
||||
const SessionCredentials& session_credentials,
|
||||
bool isDefault = false);
|
||||
void rebalanceImmediately();
|
||||
void doRebalanceByConsumerGroup(const string& consumerGroup);
|
||||
virtual void sendHeartbeatToAllBroker();
|
||||
|
||||
void cleanOfflineBrokers();
|
||||
|
||||
void findConsumerIds(const string& topic,
|
||||
const string& group,
|
||||
vector<string>& cids,
|
||||
const SessionCredentials& session_credentials);
|
||||
void resetOffset(const string& group, const string& topic, const map<MQMessageQueue, int64>& offsetTable);
|
||||
ConsumerRunningInfo* consumerRunningInfo(const string& consumerGroup);
|
||||
bool getSessionCredentialFromConsumer(const string& consumerGroup, SessionCredentials& sessionCredentials);
|
||||
void addBrokerToAddrMap(const string& brokerName, map<int, string>& brokerAddrs);
|
||||
map<string, map<int, string>> getBrokerAddrMap();
|
||||
void clearBrokerAddrMap();
|
||||
|
||||
bool isBrokerAddressInUse(const std::string& address);
|
||||
|
||||
private:
|
||||
void unregisterClient(const string& producerGroup,
|
||||
const string& consumerGroup,
|
||||
const SessionCredentials& session_credentials);
|
||||
TopicRouteData* getTopicRouteData(const string& topic);
|
||||
void addTopicRouteData(const string& topic, TopicRouteData* pTopicRouteData);
|
||||
HeartbeatData* prepareHeartbeatData();
|
||||
|
||||
void startScheduledTask(bool startFetchNSService = true);
|
||||
//<!timer async callback
|
||||
void fetchNameServerAddr(boost::system::error_code& ec, boost::shared_ptr<boost::asio::deadline_timer> t);
|
||||
void updateTopicRouteInfo(boost::system::error_code& ec, boost::shared_ptr<boost::asio::deadline_timer> t);
|
||||
void timerCB_sendHeartbeatToAllBroker(boost::system::error_code& ec,
|
||||
boost::shared_ptr<boost::asio::deadline_timer> t);
|
||||
|
||||
void timerCB_cleanOfflineBrokers(boost::system::error_code& ec, boost::shared_ptr<boost::asio::deadline_timer> t);
|
||||
|
||||
// consumer related operation
|
||||
void consumer_timerOperation();
|
||||
void persistAllConsumerOffset(boost::system::error_code& ec, boost::shared_ptr<boost::asio::deadline_timer> t);
|
||||
void doRebalance();
|
||||
void timerCB_doRebalance(boost::system::error_code& ec, boost::shared_ptr<boost::asio::deadline_timer> t);
|
||||
bool getSessionCredentialFromConsumerTable(SessionCredentials& sessionCredentials);
|
||||
void eraseConsumerFromTable(const string& consumerName);
|
||||
int getConsumerTableSize();
|
||||
void getTopicListFromConsumerSubscription(set<string>& topicList);
|
||||
void updateConsumerSubscribeTopicInfo(const string& topic, vector<MQMessageQueue> mqs);
|
||||
void insertConsumerInfoToHeartBeatData(HeartbeatData* pHeartbeatData);
|
||||
|
||||
// producer related operation
|
||||
bool getSessionCredentialFromProducerTable(SessionCredentials& sessionCredentials);
|
||||
void eraseProducerFromTable(const string& producerName);
|
||||
int getProducerTableSize();
|
||||
void insertProducerInfoToHeartBeatData(HeartbeatData* pHeartbeatData);
|
||||
|
||||
// topicPublishInfo related operation
|
||||
void addTopicInfoToTable(const string& topic, boost::shared_ptr<TopicPublishInfo> pTopicPublishInfo);
|
||||
void eraseTopicInfoFromTable(const string& topic);
|
||||
bool isTopicInfoValidInTable(const string& topic);
|
||||
boost::shared_ptr<TopicPublishInfo> getTopicPublishInfoFromTable(const string& topic);
|
||||
void getTopicListFromTopicPublishInfo(set<string>& topicList);
|
||||
|
||||
void getSessionCredentialsFromOneOfProducerOrConsumer(SessionCredentials& session_credentials);
|
||||
|
||||
protected:
|
||||
string m_clientId;
|
||||
unique_ptr<MQClientAPIImpl> m_pClientAPIImpl;
|
||||
unique_ptr<ClientRemotingProcessor> m_pClientRemotingProcessor;
|
||||
|
||||
bool addProducerToTable(const string& producerName, MQProducer* pMQProducer);
|
||||
bool addConsumerToTable(const string& consumerName, MQConsumer* pMQConsumer);
|
||||
|
||||
private:
|
||||
string m_nameSrvDomain; // per clientId
|
||||
ServiceState m_serviceState;
|
||||
bool m_bFetchNSService;
|
||||
|
||||
//<! group --> MQProducer;
|
||||
typedef map<string, MQProducer*> MQPMAP;
|
||||
boost::mutex m_producerTableMutex;
|
||||
MQPMAP m_producerTable;
|
||||
|
||||
//<! group --> MQConsumer;
|
||||
typedef map<string, MQConsumer*> MQCMAP;
|
||||
// Changed to recursive mutex due to avoid deadlock issue:
|
||||
boost::recursive_mutex m_consumerTableMutex;
|
||||
MQCMAP m_consumerTable;
|
||||
|
||||
//<! Topic---> TopicRouteData
|
||||
typedef map<string, TopicRouteData*> TRDMAP;
|
||||
boost::mutex m_topicRouteTableMutex;
|
||||
TRDMAP m_topicRouteTable;
|
||||
|
||||
//<!-----brokerName
|
||||
//<! ------brokerid;
|
||||
//<! ------add;
|
||||
boost::mutex m_brokerAddrlock;
|
||||
typedef map<string, map<int, string>> BrokerAddrMAP;
|
||||
BrokerAddrMAP m_brokerAddrTable;
|
||||
|
||||
//<!topic ---->TopicPublishInfo> ;
|
||||
typedef map<string, boost::shared_ptr<TopicPublishInfo>> TPMap;
|
||||
boost::mutex m_topicPublishInfoTableMutex;
|
||||
TPMap m_topicPublishInfoTable;
|
||||
boost::mutex m_factoryLock;
|
||||
boost::mutex m_topicPublishInfoLock;
|
||||
|
||||
boost::asio::io_service m_async_ioService;
|
||||
unique_ptr<boost::thread> m_async_service_thread;
|
||||
|
||||
boost::asio::io_service m_consumer_async_ioService;
|
||||
unique_ptr<boost::thread> m_consumer_async_service_thread;
|
||||
};
|
||||
|
||||
} // namespace rocketmq
|
||||
|
||||
#endif
|
||||
59
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/MQClientManager.cpp
vendored
Normal file
59
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/MQClientManager.cpp
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "MQClientManager.h"
|
||||
#include "Logging.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!************************************************************************
|
||||
MQClientManager::MQClientManager() {}
|
||||
|
||||
MQClientManager::~MQClientManager() {
|
||||
m_factoryTable.clear();
|
||||
}
|
||||
|
||||
MQClientManager* MQClientManager::getInstance() {
|
||||
static MQClientManager instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
MQClientFactory* MQClientManager::getMQClientFactory(const string& clientId,
|
||||
int pullThreadNum,
|
||||
uint64_t tcpConnectTimeout,
|
||||
uint64_t tcpTransportTryLockTimeout,
|
||||
string unitName,
|
||||
bool enableSsl,
|
||||
const std::string& sslPropertyFile) {
|
||||
FTMAP::iterator it = m_factoryTable.find(clientId);
|
||||
if (it != m_factoryTable.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
MQClientFactory* factory = new MQClientFactory(clientId, pullThreadNum, tcpConnectTimeout,
|
||||
tcpTransportTryLockTimeout, unitName, enableSsl, sslPropertyFile);
|
||||
m_factoryTable[clientId] = factory;
|
||||
return factory;
|
||||
}
|
||||
}
|
||||
|
||||
void MQClientManager::removeClientFactory(const string& clientId) {
|
||||
FTMAP::iterator it = m_factoryTable.find(clientId);
|
||||
if (it != m_factoryTable.end()) {
|
||||
deleteAndZero(it->second);
|
||||
m_factoryTable.erase(it);
|
||||
}
|
||||
}
|
||||
//<!************************************************************************
|
||||
} // namespace rocketmq
|
||||
52
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/MQClientManager.h
vendored
Normal file
52
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/MQClientManager.h
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __MQCLIENTMANAGER_H__
|
||||
#define __MQCLIENTMANAGER_H__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "Logging.h"
|
||||
#include "MQClientFactory.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
class MQClientManager {
|
||||
public:
|
||||
virtual ~MQClientManager();
|
||||
virtual MQClientFactory* getMQClientFactory(const string& clientId,
|
||||
int pullThreadNum,
|
||||
uint64_t tcpConnectTimeout,
|
||||
uint64_t tcpTransportTryLockTimeout,
|
||||
string unitName,
|
||||
bool enableSsl,
|
||||
const std::string& sslPropertyFile);
|
||||
void removeClientFactory(const string& clientId);
|
||||
|
||||
static MQClientManager* getInstance();
|
||||
|
||||
private:
|
||||
MQClientManager();
|
||||
|
||||
private:
|
||||
typedef map<string, MQClientFactory*> FTMAP;
|
||||
FTMAP m_factoryTable;
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
|
||||
#endif
|
||||
67
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/Arg_helper.cpp
vendored
Normal file
67
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/Arg_helper.cpp
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "Arg_helper.h"
|
||||
#include "UtilAll.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
Arg_helper::Arg_helper(int argc, char* argv[]) {
|
||||
for (int i = 0; i < argc; i++) {
|
||||
m_args.push_back(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Arg_helper::Arg_helper(string arg_str_) {
|
||||
vector<string> v;
|
||||
UtilAll::Split(v, arg_str_, " ");
|
||||
m_args.insert(m_args.end(), v.begin(), v.end());
|
||||
}
|
||||
|
||||
string Arg_helper::get_option(int idx_) const {
|
||||
if ((size_t)idx_ >= m_args.size()) {
|
||||
return "";
|
||||
}
|
||||
return m_args[idx_];
|
||||
}
|
||||
|
||||
bool Arg_helper::is_enable_option(string opt_) const {
|
||||
for (size_t i = 0; i < m_args.size(); ++i) {
|
||||
if (opt_ == m_args[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
string Arg_helper::get_option_value(string opt_) const {
|
||||
string ret = "";
|
||||
for (size_t i = 0; i < m_args.size(); ++i) {
|
||||
if (opt_ == m_args[i]) {
|
||||
size_t value_idx = ++i;
|
||||
if (value_idx >= m_args.size()) {
|
||||
return ret;
|
||||
}
|
||||
ret = m_args[value_idx];
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
36
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/AsyncArg.h
vendored
Normal file
36
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/AsyncArg.h
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _AsyncArg_H_
|
||||
#define _AsyncArg_H_
|
||||
|
||||
#include "MQMessageQueue.h"
|
||||
#include "PullAPIWrapper.h"
|
||||
#include "SubscriptionData.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
|
||||
struct AsyncArg {
|
||||
MQMessageQueue mq;
|
||||
SubscriptionData subData;
|
||||
PullAPIWrapper* pPullWrapper;
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif //<! _AsyncArg_H_
|
||||
192
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/AsyncCallbackWrap.cpp
vendored
Normal file
192
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/AsyncCallbackWrap.cpp
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "AsyncCallbackWrap.h"
|
||||
#include "Logging.h"
|
||||
#include "MQClientAPIImpl.h"
|
||||
#include "MQDecoder.h"
|
||||
#include "MQMessageQueue.h"
|
||||
#include "PullAPIWrapper.h"
|
||||
#include "PullResultExt.h"
|
||||
#include "ResponseFuture.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
AsyncCallbackWrap::AsyncCallbackWrap(AsyncCallback* pAsyncCallback, MQClientAPIImpl* pclientAPI)
|
||||
: m_pAsyncCallBack(pAsyncCallback), m_pClientAPI(pclientAPI) {}
|
||||
|
||||
AsyncCallbackWrap::~AsyncCallbackWrap() {
|
||||
m_pAsyncCallBack = NULL;
|
||||
m_pClientAPI = NULL;
|
||||
}
|
||||
|
||||
//<!************************************************************************
|
||||
SendCallbackWrap::SendCallbackWrap(const string& brokerName,
|
||||
const MQMessage& msg,
|
||||
AsyncCallback* pAsyncCallback,
|
||||
MQClientAPIImpl* pclientAPI)
|
||||
: AsyncCallbackWrap(pAsyncCallback, pclientAPI), m_msg(msg), m_brokerName(brokerName) {}
|
||||
|
||||
void SendCallbackWrap::onException() {
|
||||
if (m_pAsyncCallBack == NULL)
|
||||
return;
|
||||
|
||||
SendCallback* pCallback = static_cast<SendCallback*>(m_pAsyncCallBack);
|
||||
if (pCallback) {
|
||||
unique_ptr<MQException> exception(
|
||||
new MQException("send msg failed due to wait response timeout or network error", -1, __FILE__, __LINE__));
|
||||
pCallback->onException(*exception);
|
||||
if (pCallback->getSendCallbackType() == autoDeleteSendCallback) {
|
||||
deleteAndZero(pCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SendCallbackWrap::operationComplete(ResponseFuture* pResponseFuture, bool bProducePullRequest) {
|
||||
unique_ptr<RemotingCommand> pResponse(pResponseFuture->getCommand());
|
||||
|
||||
if (m_pAsyncCallBack == NULL) {
|
||||
return;
|
||||
}
|
||||
int opaque = pResponseFuture->getOpaque();
|
||||
SendCallback* pCallback = static_cast<SendCallback*>(m_pAsyncCallBack);
|
||||
|
||||
if (!pResponse) {
|
||||
string err = "unknow reseaon";
|
||||
if (!pResponseFuture->isSendRequestOK()) {
|
||||
err = "send request failed";
|
||||
|
||||
} else if (pResponseFuture->isTimeOut()) {
|
||||
// pResponseFuture->setAsyncResponseFlag();
|
||||
err = "wait response timeout";
|
||||
}
|
||||
if (pCallback) {
|
||||
MQException exception(err, -1, __FILE__, __LINE__);
|
||||
pCallback->onException(exception);
|
||||
}
|
||||
LOG_ERROR("send failed of:%d", pResponseFuture->getOpaque());
|
||||
} else {
|
||||
try {
|
||||
SendResult ret = m_pClientAPI->processSendResponse(m_brokerName, m_msg, pResponse.get());
|
||||
if (pCallback) {
|
||||
LOG_DEBUG("operationComplete: processSendResponse success, opaque:%d, maxRetryTime:%d, retrySendTimes:%d",
|
||||
opaque, pResponseFuture->getMaxRetrySendTimes(), pResponseFuture->getRetrySendTimes());
|
||||
pCallback->onSuccess(ret);
|
||||
}
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("operationComplete: processSendResponse exception: %s", e.what());
|
||||
|
||||
// broker may return exception, need consider retry send
|
||||
int maxRetryTimes = pResponseFuture->getMaxRetrySendTimes();
|
||||
int retryTimes = pResponseFuture->getRetrySendTimes();
|
||||
if (pResponseFuture->getAsyncFlag() && retryTimes < maxRetryTimes && maxRetryTimes > 1) {
|
||||
int64 left_timeout_ms = pResponseFuture->leftTime();
|
||||
string brokerAddr = pResponseFuture->getBrokerAddr();
|
||||
const RemotingCommand& requestCommand = pResponseFuture->getRequestCommand();
|
||||
retryTimes += 1;
|
||||
LOG_WARN("retry send, opaque:%d, sendTimes:%d, maxRetryTimes:%d, left_timeout:%lld, brokerAddr:%s, msg:%s",
|
||||
opaque, retryTimes, maxRetryTimes, left_timeout_ms, brokerAddr.data(), m_msg.toString().data());
|
||||
|
||||
bool exception_flag = false;
|
||||
try {
|
||||
m_pClientAPI->sendMessageAsync(pResponseFuture->getBrokerAddr(), m_brokerName, m_msg,
|
||||
(RemotingCommand&)requestCommand, pCallback, left_timeout_ms, maxRetryTimes,
|
||||
retryTimes);
|
||||
} catch (MQClientException& e) {
|
||||
LOG_ERROR("retry send exception:%s, opaque:%d, retryTimes:%d, msg:%s, not retry send again", e.what(), opaque,
|
||||
retryTimes, m_msg.toString().data());
|
||||
exception_flag = true;
|
||||
}
|
||||
|
||||
if (exception_flag == false) {
|
||||
return; // send retry again, here need return
|
||||
}
|
||||
}
|
||||
|
||||
if (pCallback) {
|
||||
MQException exception("process send response error", -1, __FILE__, __LINE__);
|
||||
pCallback->onException(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pCallback && pCallback->getSendCallbackType() == autoDeleteSendCallback) {
|
||||
deleteAndZero(pCallback);
|
||||
}
|
||||
}
|
||||
|
||||
//<!************************************************************************
|
||||
PullCallbackWrap::PullCallbackWrap(AsyncCallback* pAsyncCallback, MQClientAPIImpl* pclientAPI, void* pArg)
|
||||
: AsyncCallbackWrap(pAsyncCallback, pclientAPI) {
|
||||
m_pArg = *static_cast<AsyncArg*>(pArg);
|
||||
}
|
||||
|
||||
PullCallbackWrap::~PullCallbackWrap() {}
|
||||
|
||||
void PullCallbackWrap::onException() {
|
||||
if (m_pAsyncCallBack == NULL)
|
||||
return;
|
||||
|
||||
PullCallback* pCallback = static_cast<PullCallback*>(m_pAsyncCallBack);
|
||||
if (pCallback) {
|
||||
MQException exception("wait response timeout", -1, __FILE__, __LINE__);
|
||||
pCallback->onException(exception);
|
||||
} else {
|
||||
LOG_ERROR("PullCallback is NULL, AsyncPull could not continue");
|
||||
}
|
||||
}
|
||||
|
||||
void PullCallbackWrap::operationComplete(ResponseFuture* pResponseFuture, bool bProducePullRequest) {
|
||||
unique_ptr<RemotingCommand> pResponse(pResponseFuture->getCommand());
|
||||
if (m_pAsyncCallBack == NULL) {
|
||||
LOG_ERROR("m_pAsyncCallBack is NULL, AsyncPull could not continue");
|
||||
return;
|
||||
}
|
||||
PullCallback* pCallback = static_cast<PullCallback*>(m_pAsyncCallBack);
|
||||
if (!pResponse) {
|
||||
string err = "unknow reseaon";
|
||||
if (!pResponseFuture->isSendRequestOK()) {
|
||||
err = "send request failed";
|
||||
|
||||
} else if (pResponseFuture->isTimeOut()) {
|
||||
// pResponseFuture->setAsyncResponseFlag();
|
||||
err = "wait response timeout";
|
||||
}
|
||||
MQException exception(err, -1, __FILE__, __LINE__);
|
||||
LOG_ERROR("Async pull exception of opaque:%d", pResponseFuture->getOpaque());
|
||||
if (pCallback && bProducePullRequest)
|
||||
pCallback->onException(exception);
|
||||
} else {
|
||||
try {
|
||||
if (m_pArg.pPullWrapper) {
|
||||
unique_ptr<PullResult> pullResult(m_pClientAPI->processPullResponse(pResponse.get()));
|
||||
PullResult result = m_pArg.pPullWrapper->processPullResult(m_pArg.mq, pullResult.get(), &m_pArg.subData);
|
||||
if (pCallback)
|
||||
pCallback->onSuccess(m_pArg.mq, result, bProducePullRequest);
|
||||
} else {
|
||||
LOG_ERROR("pPullWrapper had been destroyed with consumer");
|
||||
}
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("%s", e.what());
|
||||
MQException exception("pullResult error", -1, __FILE__, __LINE__);
|
||||
if (pCallback && bProducePullRequest)
|
||||
pCallback->onException(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
80
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/AsyncCallbackWrap.h
vendored
Normal file
80
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/AsyncCallbackWrap.h
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __ASYNCCALLBACKWRAP_H__
|
||||
#define __ASYNCCALLBACKWRAP_H__
|
||||
|
||||
#include "AsyncArg.h"
|
||||
#include "AsyncCallback.h"
|
||||
#include "MQMessage.h"
|
||||
#include "RemotingCommand.h"
|
||||
#include "UtilAll.h"
|
||||
|
||||
namespace rocketmq {
|
||||
|
||||
class ResponseFuture;
|
||||
class MQClientAPIImpl;
|
||||
// class DefaultMQProducer;
|
||||
//<!***************************************************************************
|
||||
enum asyncCallBackType { asyncCallbackWrap = 0, sendCallbackWrap = 1, pullCallbackWrap = 2 };
|
||||
|
||||
struct AsyncCallbackWrap {
|
||||
public:
|
||||
AsyncCallbackWrap(AsyncCallback* pAsyncCallback, MQClientAPIImpl* pclientAPI);
|
||||
virtual ~AsyncCallbackWrap();
|
||||
virtual void operationComplete(ResponseFuture* pResponseFuture, bool bProducePullRequest) = 0;
|
||||
virtual void onException() = 0;
|
||||
virtual asyncCallBackType getCallbackType() = 0;
|
||||
|
||||
protected:
|
||||
AsyncCallback* m_pAsyncCallBack;
|
||||
MQClientAPIImpl* m_pClientAPI;
|
||||
};
|
||||
|
||||
//<!************************************************************************
|
||||
class SendCallbackWrap : public AsyncCallbackWrap {
|
||||
public:
|
||||
SendCallbackWrap(const string& brokerName,
|
||||
const MQMessage& msg,
|
||||
AsyncCallback* pAsyncCallback,
|
||||
MQClientAPIImpl* pClientAPI);
|
||||
|
||||
virtual ~SendCallbackWrap(){};
|
||||
virtual void operationComplete(ResponseFuture* pResponseFuture, bool bProducePullRequest);
|
||||
virtual void onException();
|
||||
virtual asyncCallBackType getCallbackType() { return sendCallbackWrap; }
|
||||
|
||||
private:
|
||||
MQMessage m_msg;
|
||||
string m_brokerName;
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
class PullCallbackWrap : public AsyncCallbackWrap {
|
||||
public:
|
||||
PullCallbackWrap(AsyncCallback* pAsyncCallback, MQClientAPIImpl* pClientAPI, void* pArg);
|
||||
virtual ~PullCallbackWrap();
|
||||
virtual void operationComplete(ResponseFuture* pResponseFuture, bool bProducePullRequest);
|
||||
virtual void onException();
|
||||
virtual asyncCallBackType getCallbackType() { return pullCallbackWrap; }
|
||||
|
||||
private:
|
||||
AsyncArg m_pArg;
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif // __ASYNCCALLBACKWRAP_H__
|
||||
217
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/ByteOrder.h
vendored
Normal file
217
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/ByteOrder.h
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef BYTEORDER_H_INCLUDED
|
||||
#define BYTEORDER_H_INCLUDED
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <algorithm>
|
||||
#include <boost/detail/endian.hpp>
|
||||
#include "RocketMQClient.h"
|
||||
#include "UtilAll.h"
|
||||
//==============================================================================
|
||||
/** Contains static methods for converting the byte order between different
|
||||
endiannesses.
|
||||
*/
|
||||
namespace rocketmq {
|
||||
|
||||
class ROCKETMQCLIENT_API ByteOrder {
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Swaps the upper and lower bytes of a 16-bit integer. */
|
||||
static uint16 swap(uint16 value);
|
||||
|
||||
/** Reverses the order of the 4 bytes in a 32-bit integer. */
|
||||
static uint32 swap(uint32 value);
|
||||
|
||||
/** Reverses the order of the 8 bytes in a 64-bit integer. */
|
||||
static uint64 swap(uint64 value);
|
||||
|
||||
//==============================================================================
|
||||
/** Swaps the byte order of a 16-bit int if the CPU is big-endian */
|
||||
static uint16 swapIfBigEndian(uint16 value);
|
||||
|
||||
/** Swaps the byte order of a 32-bit int if the CPU is big-endian */
|
||||
static uint32 swapIfBigEndian(uint32 value);
|
||||
|
||||
/** Swaps the byte order of a 64-bit int if the CPU is big-endian */
|
||||
static uint64 swapIfBigEndian(uint64 value);
|
||||
|
||||
/** Swaps the byte order of a 16-bit int if the CPU is little-endian */
|
||||
static uint16 swapIfLittleEndian(uint16 value);
|
||||
|
||||
/** Swaps the byte order of a 32-bit int if the CPU is little-endian */
|
||||
static uint32 swapIfLittleEndian(uint32 value);
|
||||
|
||||
/** Swaps the byte order of a 64-bit int if the CPU is little-endian */
|
||||
static uint64 swapIfLittleEndian(uint64 value);
|
||||
|
||||
//==============================================================================
|
||||
/** Turns 4 bytes into a little-endian integer. */
|
||||
static uint32 littleEndianInt(const void* bytes);
|
||||
|
||||
/** Turns 8 bytes into a little-endian integer. */
|
||||
static uint64 littleEndianInt64(const void* bytes);
|
||||
|
||||
/** Turns 2 bytes into a little-endian integer. */
|
||||
static uint16 littleEndianShort(const void* bytes);
|
||||
|
||||
/** Turns 4 bytes into a big-endian integer. */
|
||||
static uint32 bigEndianInt(const void* bytes);
|
||||
|
||||
/** Turns 8 bytes into a big-endian integer. */
|
||||
static uint64 bigEndianInt64(const void* bytes);
|
||||
|
||||
/** Turns 2 bytes into a big-endian integer. */
|
||||
static uint16 bigEndianShort(const void* bytes);
|
||||
|
||||
//==============================================================================
|
||||
/** Converts 3 little-endian bytes into a signed 24-bit value (which is
|
||||
* sign-extended to 32 bits). */
|
||||
static int littleEndian24Bit(const void* bytes);
|
||||
|
||||
/** Converts 3 big-endian bytes into a signed 24-bit value (which is
|
||||
* sign-extended to 32 bits). */
|
||||
static int bigEndian24Bit(const void* bytes);
|
||||
|
||||
/** Copies a 24-bit number to 3 little-endian bytes. */
|
||||
static void littleEndian24BitToChars(int value, void* destBytes);
|
||||
|
||||
/** Copies a 24-bit number to 3 big-endian bytes. */
|
||||
static void bigEndian24BitToChars(int value, void* destBytes);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if the current CPU is big-endian. */
|
||||
static bool isBigEndian();
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
|
||||
inline uint16 ByteOrder::swap(uint16 n) {
|
||||
return static_cast<uint16>((n << 8) | (n >> 8));
|
||||
}
|
||||
|
||||
inline uint32 ByteOrder::swap(uint32 n) {
|
||||
return (n << 24) | (n >> 24) | ((n & 0xff00) << 8) | ((n & 0xff0000) >> 8);
|
||||
}
|
||||
|
||||
inline uint64 ByteOrder::swap(uint64 value) {
|
||||
return (((uint64)swap((uint32)value)) << 32) | swap((uint32)(value >> 32));
|
||||
}
|
||||
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ //__BYTE_ORDER__ is defined by GCC
|
||||
inline uint16 ByteOrder::swapIfBigEndian(const uint16 v) {
|
||||
return v;
|
||||
}
|
||||
inline uint32 ByteOrder::swapIfBigEndian(const uint32 v) {
|
||||
return v;
|
||||
}
|
||||
inline uint64 ByteOrder::swapIfBigEndian(const uint64 v) {
|
||||
return v;
|
||||
}
|
||||
inline uint16 ByteOrder::swapIfLittleEndian(const uint16 v) {
|
||||
return swap(v);
|
||||
}
|
||||
inline uint32 ByteOrder::swapIfLittleEndian(const uint32 v) {
|
||||
return swap(v);
|
||||
}
|
||||
inline uint64 ByteOrder::swapIfLittleEndian(const uint64 v) {
|
||||
return swap(v);
|
||||
}
|
||||
inline uint32 ByteOrder::littleEndianInt(const void* const bytes) {
|
||||
return *static_cast<const uint32*>(bytes);
|
||||
}
|
||||
inline uint64 ByteOrder::littleEndianInt64(const void* const bytes) {
|
||||
return *static_cast<const uint64*>(bytes);
|
||||
}
|
||||
inline uint16 ByteOrder::littleEndianShort(const void* const bytes) {
|
||||
return *static_cast<const uint16*>(bytes);
|
||||
}
|
||||
inline uint32 ByteOrder::bigEndianInt(const void* const bytes) {
|
||||
return swap(*static_cast<const uint32*>(bytes));
|
||||
}
|
||||
inline uint64 ByteOrder::bigEndianInt64(const void* const bytes) {
|
||||
return swap(*static_cast<const uint64*>(bytes));
|
||||
}
|
||||
inline uint16 ByteOrder::bigEndianShort(const void* const bytes) {
|
||||
return swap(*static_cast<const uint16*>(bytes));
|
||||
}
|
||||
inline bool ByteOrder::isBigEndian() {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
inline uint16 ByteOrder::swapIfBigEndian(const uint16 v) {
|
||||
return swap(v);
|
||||
}
|
||||
inline uint32 ByteOrder::swapIfBigEndian(const uint32 v) {
|
||||
return swap(v);
|
||||
}
|
||||
inline uint64 ByteOrder::swapIfBigEndian(const uint64 v) {
|
||||
return swap(v);
|
||||
}
|
||||
inline uint16 ByteOrder::swapIfLittleEndian(const uint16 v) {
|
||||
return v;
|
||||
}
|
||||
inline uint32 ByteOrder::swapIfLittleEndian(const uint32 v) {
|
||||
return v;
|
||||
}
|
||||
inline uint64 ByteOrder::swapIfLittleEndian(const uint64 v) {
|
||||
return v;
|
||||
}
|
||||
inline uint32 ByteOrder::littleEndianInt(const void* const bytes) {
|
||||
return swap(*static_cast<const uint32*>(bytes));
|
||||
}
|
||||
inline uint64 ByteOrder::littleEndianInt64(const void* const bytes) {
|
||||
return swap(*static_cast<const uint64*>(bytes));
|
||||
}
|
||||
inline uint16 ByteOrder::littleEndianShort(const void* const bytes) {
|
||||
return swap(*static_cast<const uint16*>(bytes));
|
||||
}
|
||||
inline uint32 ByteOrder::bigEndianInt(const void* const bytes) {
|
||||
return *static_cast<const uint32*>(bytes);
|
||||
}
|
||||
inline uint64 ByteOrder::bigEndianInt64(const void* const bytes) {
|
||||
return *static_cast<const uint64*>(bytes);
|
||||
}
|
||||
inline uint16 ByteOrder::bigEndianShort(const void* const bytes) {
|
||||
return *static_cast<const uint16*>(bytes);
|
||||
}
|
||||
inline bool ByteOrder::isBigEndian() {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline int ByteOrder::littleEndian24Bit(const void* const bytes) {
|
||||
return (((int)static_cast<const int8*>(bytes)[2]) << 16) | (((int)static_cast<const uint8*>(bytes)[1]) << 8) |
|
||||
((int)static_cast<const uint8*>(bytes)[0]);
|
||||
}
|
||||
inline int ByteOrder::bigEndian24Bit(const void* const bytes) {
|
||||
return (((int)static_cast<const int8*>(bytes)[0]) << 16) | (((int)static_cast<const uint8*>(bytes)[1]) << 8) |
|
||||
((int)static_cast<const uint8*>(bytes)[2]);
|
||||
}
|
||||
inline void ByteOrder::littleEndian24BitToChars(const int value, void* const destBytes) {
|
||||
static_cast<uint8*>(destBytes)[0] = (uint8)value;
|
||||
static_cast<uint8*>(destBytes)[1] = (uint8)(value >> 8);
|
||||
static_cast<uint8*>(destBytes)[2] = (uint8)(value >> 16);
|
||||
}
|
||||
inline void ByteOrder::bigEndian24BitToChars(const int value, void* const destBytes) {
|
||||
static_cast<uint8*>(destBytes)[0] = (uint8)(value >> 16);
|
||||
static_cast<uint8*>(destBytes)[1] = (uint8)(value >> 8);
|
||||
static_cast<uint8*>(destBytes)[2] = (uint8)value;
|
||||
}
|
||||
} // namespace rocketmq
|
||||
#endif // BYTEORDER_H_INCLUDED
|
||||
75
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/ClientRPCHook.cpp
vendored
Normal file
75
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/ClientRPCHook.cpp
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ClientRPCHook.h"
|
||||
#include "CommandHeader.h"
|
||||
#include "Logging.h"
|
||||
extern "C" {
|
||||
#include "spas_client.h"
|
||||
}
|
||||
#include "string"
|
||||
|
||||
namespace rocketmq {
|
||||
|
||||
const string SessionCredentials::AccessKey = "AccessKey";
|
||||
const string SessionCredentials::SecretKey = "SecretKey";
|
||||
const string SessionCredentials::Signature = "Signature";
|
||||
const string SessionCredentials::SignatureMethod = "SignatureMethod";
|
||||
const string SessionCredentials::ONSChannelKey = "OnsChannel";
|
||||
|
||||
void ClientRPCHook::doBeforeRequest(const string& remoteAddr, RemotingCommand& request) {
|
||||
CommandHeader* header = request.getCommandHeader();
|
||||
|
||||
map<string, string> requestMap;
|
||||
string totalMsg;
|
||||
|
||||
requestMap.insert(pair<string, string>(SessionCredentials::AccessKey, sessionCredentials.getAccessKey()));
|
||||
requestMap.insert(pair<string, string>(SessionCredentials::ONSChannelKey, sessionCredentials.getAuthChannel()));
|
||||
|
||||
LOG_DEBUG("before insert declared filed,MAP SIZE is:" SIZET_FMT "", requestMap.size());
|
||||
if (header != NULL) {
|
||||
header->SetDeclaredFieldOfCommandHeader(requestMap);
|
||||
}
|
||||
LOG_DEBUG("after insert declared filed, MAP SIZE is:" SIZET_FMT "", requestMap.size());
|
||||
|
||||
map<string, string>::iterator it = requestMap.begin();
|
||||
for (; it != requestMap.end(); ++it) {
|
||||
totalMsg.append(it->second);
|
||||
}
|
||||
if (request.getMsgBody().length() > 0) {
|
||||
LOG_DEBUG("msgBody is:%s, msgBody length is:" SIZET_FMT "", request.getMsgBody().c_str(),
|
||||
request.getMsgBody().length());
|
||||
|
||||
totalMsg.append(request.getMsgBody());
|
||||
}
|
||||
LOG_DEBUG("total msg info are:%s, size is:" SIZET_FMT "", totalMsg.c_str(), totalMsg.size());
|
||||
char* pSignature =
|
||||
rocketmqSignature::spas_sign(totalMsg.c_str(), totalMsg.size(), sessionCredentials.getSecretKey().c_str());
|
||||
// char *pSignature = spas_sign(totalMsg.c_str(),
|
||||
// sessionCredentials.getSecretKey().c_str());
|
||||
|
||||
if (pSignature != NULL) {
|
||||
string signature(static_cast<const char*>(pSignature));
|
||||
request.addExtField(SessionCredentials::Signature, signature);
|
||||
request.addExtField(SessionCredentials::AccessKey, sessionCredentials.getAccessKey());
|
||||
request.addExtField(SessionCredentials::ONSChannelKey, sessionCredentials.getAuthChannel());
|
||||
rocketmqSignature::spas_mem_free(pSignature);
|
||||
} else {
|
||||
LOG_ERROR("signature for request failed");
|
||||
}
|
||||
}
|
||||
} // namespace rocketmq
|
||||
45
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/ClientRPCHook.h
vendored
Normal file
45
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/ClientRPCHook.h
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CLIENTRPCHOOK_H__
|
||||
#define __CLIENTRPCHOOK_H__
|
||||
|
||||
#include "RemotingCommand.h"
|
||||
#include "SessionCredentials.h"
|
||||
namespace rocketmq {
|
||||
class RPCHook {
|
||||
public:
|
||||
RPCHook() {}
|
||||
virtual ~RPCHook() {}
|
||||
virtual void doBeforeRequest(const string& remoteAddr, RemotingCommand& request) = 0;
|
||||
virtual void doAfterResponse(RemotingCommand& request, RemotingCommand& response) = 0;
|
||||
};
|
||||
|
||||
class ClientRPCHook : public RPCHook {
|
||||
private:
|
||||
SessionCredentials sessionCredentials;
|
||||
|
||||
public:
|
||||
ClientRPCHook(const SessionCredentials& session_credentials) : sessionCredentials(session_credentials) {}
|
||||
virtual ~ClientRPCHook() {}
|
||||
|
||||
virtual void doBeforeRequest(const string& remoteAddr, RemotingCommand& request);
|
||||
|
||||
virtual void doAfterResponse(RemotingCommand& request, RemotingCommand& response) {}
|
||||
};
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
27
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/CommunicationMode.h
vendored
Normal file
27
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/CommunicationMode.h
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __COMMUNICATIONMODE_H__
|
||||
#define __COMMUNICATIONMODE_H__
|
||||
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
enum CommunicationMode { ComMode_SYNC, ComMode_ASYNC, ComMode_ONEWAY };
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
275
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/DefaultMQClient.cpp
vendored
Normal file
275
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/DefaultMQClient.cpp
vendored
Normal file
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "DefaultMQClient.h"
|
||||
#include "Logging.h"
|
||||
#include "MQClientFactory.h"
|
||||
#include "MQClientManager.h"
|
||||
#include "NameSpaceUtil.h"
|
||||
#include "TopicPublishInfo.h"
|
||||
#include "UtilAll.h"
|
||||
|
||||
namespace rocketmq {
|
||||
// hard code first.
|
||||
#define ROCKETMQCPP_VERSION "2.2.0"
|
||||
#define BUILD_DATE "17:30:34 03-26-2020"
|
||||
// display version: strings bin/librocketmq.so |grep VERSION
|
||||
const char* rocketmq_build_time = "CPP CORE VERSION: " ROCKETMQCPP_VERSION ", BUILD TIME: " BUILD_DATE;
|
||||
|
||||
//<!************************************************************************
|
||||
DefaultMQClient::DefaultMQClient() {
|
||||
string NAMESRV_ADDR_ENV = "NAMESRV_ADDR";
|
||||
if (const char* addr = getenv(NAMESRV_ADDR_ENV.c_str()))
|
||||
m_namesrvAddr = addr;
|
||||
else
|
||||
m_namesrvAddr = "";
|
||||
|
||||
m_instanceName = "DEFAULT";
|
||||
m_nameSpace = "";
|
||||
m_clientFactory = NULL;
|
||||
m_serviceState = CREATE_JUST;
|
||||
m_pullThreadNum = std::thread::hardware_concurrency();
|
||||
m_tcpConnectTimeout = 3000; // 3s
|
||||
m_tcpTransportTryLockTimeout = 3; // 3s
|
||||
m_unitName = "";
|
||||
m_messageTrace = false;
|
||||
}
|
||||
|
||||
DefaultMQClient::~DefaultMQClient() {}
|
||||
|
||||
string DefaultMQClient::getMQClientId() const {
|
||||
string clientIP = UtilAll::getLocalAddress();
|
||||
string processId = UtilAll::to_string(getpid());
|
||||
// return processId + "-" + clientIP + "@" + m_instanceName;
|
||||
return clientIP + "@" + processId + "#" + m_instanceName;
|
||||
}
|
||||
// version
|
||||
string DefaultMQClient::getClientVersionString() const {
|
||||
string version(rocketmq_build_time);
|
||||
return version;
|
||||
}
|
||||
|
||||
//<!groupName;
|
||||
const string& DefaultMQClient::getGroupName() const {
|
||||
return m_GroupName;
|
||||
}
|
||||
|
||||
void DefaultMQClient::setGroupName(const string& groupname) {
|
||||
m_GroupName = groupname;
|
||||
}
|
||||
|
||||
const string& DefaultMQClient::getNamesrvAddr() const {
|
||||
return m_namesrvAddr;
|
||||
}
|
||||
|
||||
void DefaultMQClient::setNamesrvAddr(const string& namesrvAddr) {
|
||||
m_namesrvAddr = NameSpaceUtil::formatNameServerURL(namesrvAddr);
|
||||
}
|
||||
|
||||
const string& DefaultMQClient::getNamesrvDomain() const {
|
||||
return m_namesrvDomain;
|
||||
}
|
||||
|
||||
void DefaultMQClient::setNamesrvDomain(const string& namesrvDomain) {
|
||||
m_namesrvDomain = namesrvDomain;
|
||||
}
|
||||
|
||||
const string& DefaultMQClient::getInstanceName() const {
|
||||
return m_instanceName;
|
||||
}
|
||||
|
||||
void DefaultMQClient::setInstanceName(const string& instanceName) {
|
||||
m_instanceName = instanceName;
|
||||
}
|
||||
const string& DefaultMQClient::getNameSpace() const {
|
||||
return m_nameSpace;
|
||||
}
|
||||
|
||||
void DefaultMQClient::setNameSpace(const string& nameSpace) {
|
||||
m_nameSpace = nameSpace;
|
||||
}
|
||||
void DefaultMQClient::createTopic(const string& key, const string& newTopic, int queueNum) {
|
||||
try {
|
||||
getFactory()->createTopic(key, newTopic, queueNum, m_SessionCredentials);
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
int64 DefaultMQClient::earliestMsgStoreTime(const MQMessageQueue& mq) {
|
||||
return getFactory()->earliestMsgStoreTime(mq, m_SessionCredentials);
|
||||
}
|
||||
|
||||
QueryResult DefaultMQClient::queryMessage(const string& topic, const string& key, int maxNum, int64 begin, int64 end) {
|
||||
return getFactory()->queryMessage(topic, key, maxNum, begin, end, m_SessionCredentials);
|
||||
}
|
||||
|
||||
int64 DefaultMQClient::minOffset(const MQMessageQueue& mq) {
|
||||
return getFactory()->minOffset(mq, m_SessionCredentials);
|
||||
}
|
||||
|
||||
int64 DefaultMQClient::maxOffset(const MQMessageQueue& mq) {
|
||||
return getFactory()->maxOffset(mq, m_SessionCredentials);
|
||||
}
|
||||
|
||||
int64 DefaultMQClient::searchOffset(const MQMessageQueue& mq, uint64_t timestamp) {
|
||||
return getFactory()->searchOffset(mq, timestamp, m_SessionCredentials);
|
||||
}
|
||||
|
||||
MQMessageExt* DefaultMQClient::viewMessage(const string& msgId) {
|
||||
return getFactory()->viewMessage(msgId, m_SessionCredentials);
|
||||
}
|
||||
|
||||
vector<MQMessageQueue> DefaultMQClient::getTopicMessageQueueInfo(const string& topic) {
|
||||
boost::weak_ptr<TopicPublishInfo> weak_topicPublishInfo(
|
||||
getFactory()->tryToFindTopicPublishInfo(topic, m_SessionCredentials));
|
||||
boost::shared_ptr<TopicPublishInfo> topicPublishInfo(weak_topicPublishInfo.lock());
|
||||
if (topicPublishInfo) {
|
||||
return topicPublishInfo->getMessageQueueList();
|
||||
}
|
||||
THROW_MQEXCEPTION(MQClientException, "could not find MessageQueue Info of topic: [" + topic + "].", -1);
|
||||
}
|
||||
|
||||
void DefaultMQClient::start() {
|
||||
if (getFactory() == NULL) {
|
||||
m_clientFactory = MQClientManager::getInstance()->getMQClientFactory(
|
||||
getMQClientId(), m_pullThreadNum, m_tcpConnectTimeout, m_tcpTransportTryLockTimeout, m_unitName, m_enableSsl,
|
||||
m_sslPropertyFile);
|
||||
}
|
||||
LOG_INFO(
|
||||
"MQClient "
|
||||
"start,groupname:%s,clientID:%s,instanceName:%s,nameserveraddr:%s",
|
||||
getGroupName().c_str(), getMQClientId().c_str(), getInstanceName().c_str(), getNamesrvAddr().c_str());
|
||||
}
|
||||
|
||||
void DefaultMQClient::shutdown() {
|
||||
m_clientFactory->shutdown();
|
||||
m_clientFactory = NULL;
|
||||
}
|
||||
|
||||
MQClientFactory* DefaultMQClient::getFactory() const {
|
||||
return m_clientFactory;
|
||||
}
|
||||
void DefaultMQClient::setFactory(MQClientFactory* factory) {
|
||||
m_clientFactory = factory;
|
||||
}
|
||||
|
||||
bool DefaultMQClient::isServiceStateOk() {
|
||||
return m_serviceState == RUNNING;
|
||||
}
|
||||
|
||||
void DefaultMQClient::setLogLevel(elogLevel inputLevel) {
|
||||
ALOG_ADAPTER->setLogLevel(inputLevel);
|
||||
}
|
||||
|
||||
elogLevel DefaultMQClient::getLogLevel() {
|
||||
return ALOG_ADAPTER->getLogLevel();
|
||||
}
|
||||
|
||||
void DefaultMQClient::setLogFileSizeAndNum(int fileNum, long perFileSize) {
|
||||
ALOG_ADAPTER->setLogFileNumAndSize(fileNum, perFileSize);
|
||||
}
|
||||
|
||||
void DefaultMQClient::setTcpTransportPullThreadNum(int num) {
|
||||
if (num > m_pullThreadNum) {
|
||||
m_pullThreadNum = num;
|
||||
}
|
||||
}
|
||||
|
||||
int DefaultMQClient::getTcpTransportPullThreadNum() const {
|
||||
return m_pullThreadNum;
|
||||
}
|
||||
|
||||
void DefaultMQClient::setTcpTransportConnectTimeout(uint64_t timeout) {
|
||||
m_tcpConnectTimeout = timeout;
|
||||
}
|
||||
uint64_t DefaultMQClient::getTcpTransportConnectTimeout() const {
|
||||
return m_tcpConnectTimeout;
|
||||
}
|
||||
|
||||
void DefaultMQClient::setTcpTransportTryLockTimeout(uint64_t timeout) {
|
||||
if (timeout < 1000) {
|
||||
timeout = 1000;
|
||||
}
|
||||
m_tcpTransportTryLockTimeout = timeout / 1000;
|
||||
}
|
||||
uint64_t DefaultMQClient::getTcpTransportTryLockTimeout() const {
|
||||
return m_tcpTransportTryLockTimeout;
|
||||
}
|
||||
|
||||
void DefaultMQClient::setUnitName(string unitName) {
|
||||
m_unitName = unitName;
|
||||
}
|
||||
const string& DefaultMQClient::getUnitName() const {
|
||||
return m_unitName;
|
||||
}
|
||||
|
||||
bool DefaultMQClient::getMessageTrace() const {
|
||||
return m_messageTrace;
|
||||
}
|
||||
|
||||
void DefaultMQClient::setMessageTrace(bool mMessageTrace) {
|
||||
m_messageTrace = mMessageTrace;
|
||||
}
|
||||
|
||||
void DefaultMQClient::setSessionCredentials(const string& input_accessKey,
|
||||
const string& input_secretKey,
|
||||
const string& input_onsChannel) {
|
||||
m_SessionCredentials.setAccessKey(input_accessKey);
|
||||
m_SessionCredentials.setSecretKey(input_secretKey);
|
||||
m_SessionCredentials.setAuthChannel(input_onsChannel);
|
||||
}
|
||||
|
||||
const SessionCredentials& DefaultMQClient::getSessionCredentials() const {
|
||||
return m_SessionCredentials;
|
||||
}
|
||||
|
||||
void DefaultMQClient::setEnableSsl(bool enableSsl) {
|
||||
m_enableSsl = enableSsl;
|
||||
}
|
||||
|
||||
bool DefaultMQClient::getEnableSsl() const {
|
||||
return m_enableSsl;
|
||||
}
|
||||
|
||||
void DefaultMQClient::setSslPropertyFile(const std::string& sslPropertyFile) {
|
||||
m_sslPropertyFile = sslPropertyFile;
|
||||
}
|
||||
|
||||
const std::string& DefaultMQClient::getSslPropertyFile() const {
|
||||
return m_sslPropertyFile;
|
||||
}
|
||||
|
||||
void DefaultMQClient::showClientConfigs() {
|
||||
// LOG_WARN("*****************************************************************************");
|
||||
LOG_WARN("ClientID:%s", getMQClientId().c_str());
|
||||
LOG_WARN("GroupName:%s", m_GroupName.c_str());
|
||||
LOG_WARN("NameServer:%s", m_namesrvAddr.c_str());
|
||||
LOG_WARN("NameServerDomain:%s", m_namesrvDomain.c_str());
|
||||
LOG_WARN("NameSpace:%s", m_nameSpace.c_str());
|
||||
LOG_WARN("InstanceName:%s", m_instanceName.c_str());
|
||||
LOG_WARN("UnitName:%s", m_unitName.c_str());
|
||||
LOG_WARN("PullThreadNum:%d", m_pullThreadNum);
|
||||
LOG_WARN("TcpConnectTimeout:%lld ms", m_tcpConnectTimeout);
|
||||
LOG_WARN("TcpTransportTryLockTimeout:%lld s", m_tcpTransportTryLockTimeout);
|
||||
LOG_WARN("EnableSsl:%s", m_enableSsl ? "true" : "false");
|
||||
LOG_WARN("SslPropertyFile:%s", m_sslPropertyFile.c_str());
|
||||
LOG_WARN("OpenMessageTrace:%s", m_messageTrace ? "true" : "false");
|
||||
// LOG_WARN("*****************************************************************************");
|
||||
}
|
||||
//<!************************************************************************
|
||||
} // namespace rocketmq
|
||||
61
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/FilterAPI.h
vendored
Normal file
61
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/FilterAPI.h
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __FILTERAPI_H__
|
||||
#define __FILTERAPI_H__
|
||||
|
||||
#include <string>
|
||||
#include "MQClientException.h"
|
||||
#include "SubscriptionData.h"
|
||||
#include "UtilAll.h"
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
class FilterAPI {
|
||||
public:
|
||||
static SubscriptionData* buildSubscriptionData(const string topic, const string& subString) {
|
||||
//<!delete in balance;
|
||||
SubscriptionData* subscriptionData = new SubscriptionData(topic, subString);
|
||||
|
||||
if (subString.empty() || !subString.compare(SUB_ALL)) {
|
||||
subscriptionData->setSubString(SUB_ALL);
|
||||
} else {
|
||||
vector<string> out;
|
||||
UtilAll::Split(out, subString, "||");
|
||||
|
||||
if (out.empty()) {
|
||||
THROW_MQEXCEPTION(MQClientException, "FilterAPI subString split error", -1);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < out.size(); i++) {
|
||||
string tag = out[i];
|
||||
if (!tag.empty()) {
|
||||
UtilAll::Trim(tag);
|
||||
if (!tag.empty()) {
|
||||
subscriptionData->putTagsSet(tag);
|
||||
subscriptionData->putCodeSet(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return subscriptionData;
|
||||
}
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
111
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/InputStream.cpp
vendored
Normal file
111
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/InputStream.cpp
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "InputStream.h"
|
||||
#include <algorithm>
|
||||
#include "MemoryOutputStream.h"
|
||||
#include "big_endian.h"
|
||||
|
||||
namespace rocketmq {
|
||||
int64 InputStream::getNumBytesRemaining() {
|
||||
int64 len = getTotalLength();
|
||||
|
||||
if (len >= 0)
|
||||
len -= getPosition();
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
char InputStream::readByte() {
|
||||
char temp = 0;
|
||||
read(&temp, 1);
|
||||
return temp;
|
||||
}
|
||||
|
||||
bool InputStream::readBool() {
|
||||
return readByte() != 0;
|
||||
}
|
||||
|
||||
short InputStream::readShortBigEndian() {
|
||||
char temp[2];
|
||||
|
||||
if (read(temp, 2) == 2) {
|
||||
short int v;
|
||||
ReadBigEndian(temp, &v);
|
||||
return v;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int InputStream::readIntBigEndian() {
|
||||
char temp[4];
|
||||
|
||||
if (read(temp, 4) == 4) {
|
||||
int v;
|
||||
ReadBigEndian(temp, &v);
|
||||
return v;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64 InputStream::readInt64BigEndian() {
|
||||
char asBytes[8];
|
||||
uint64 asInt64;
|
||||
|
||||
if (read(asBytes, 8) == 8) {
|
||||
ReadBigEndian(asBytes, &asInt64);
|
||||
return asInt64;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
float InputStream::readFloatBigEndian() {
|
||||
union {
|
||||
int32 asInt;
|
||||
float asFloat;
|
||||
} n;
|
||||
n.asInt = (int32)readIntBigEndian();
|
||||
return n.asFloat;
|
||||
}
|
||||
|
||||
double InputStream::readDoubleBigEndian() {
|
||||
union {
|
||||
int64 asInt;
|
||||
double asDouble;
|
||||
} n;
|
||||
n.asInt = readInt64BigEndian();
|
||||
return n.asDouble;
|
||||
}
|
||||
|
||||
size_t InputStream::readIntoMemoryBlock(MemoryBlock& block, size_t numBytes) {
|
||||
MemoryOutputStream mo(block, true);
|
||||
return (size_t)mo.writeFromInputStream(*this, numBytes);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void InputStream::skipNextBytes(int64 numBytesToSkip) {
|
||||
if (numBytesToSkip > 0) {
|
||||
const int skipBufferSize = (int)std::min(numBytesToSkip, (int64)16384);
|
||||
char* temp = static_cast<char*>(std::malloc(skipBufferSize * sizeof(char)));
|
||||
|
||||
while (numBytesToSkip > 0 && !isExhausted())
|
||||
numBytesToSkip -= read(temp, (int)std::min(numBytesToSkip, (int64)skipBufferSize));
|
||||
|
||||
std::free(temp);
|
||||
}
|
||||
}
|
||||
} // namespace rocketmq
|
||||
194
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/InputStream.h
vendored
Normal file
194
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/InputStream.h
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef INPUTSTREAM_H_INCLUDED
|
||||
#define INPUTSTREAM_H_INCLUDED
|
||||
|
||||
#include "dataBlock.h"
|
||||
//==============================================================================
|
||||
/** The base class for streams that read data.
|
||||
|
||||
Input and output streams are used throughout the library - subclasses can
|
||||
override
|
||||
some or all of the virtual functions to implement their behaviour.
|
||||
|
||||
@see OutputStream, MemoryInputStream, BufferedInputStream, FileInputStream
|
||||
*/
|
||||
namespace rocketmq {
|
||||
class ROCKETMQCLIENT_API InputStream {
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~InputStream() {}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the total number of bytes available for reading in this stream.
|
||||
|
||||
Note that this is the number of bytes available from the start of the
|
||||
stream, not from the current position.
|
||||
|
||||
If the size of the stream isn't actually known, this will return -1.
|
||||
|
||||
@see getNumBytesRemaining
|
||||
*/
|
||||
virtual int64 getTotalLength() = 0;
|
||||
|
||||
/** Returns the number of bytes available for reading, or a negative value if
|
||||
the remaining length is not known.
|
||||
@see getTotalLength
|
||||
*/
|
||||
int64 getNumBytesRemaining();
|
||||
|
||||
/** Returns true if the stream has no more data to read. */
|
||||
virtual bool isExhausted() = 0;
|
||||
|
||||
//==============================================================================
|
||||
/** Reads some data from the stream into a memory buffer.
|
||||
|
||||
This is the only read method that subclasses actually need to implement,
|
||||
as the
|
||||
InputStream base class implements the other read methods in terms of this
|
||||
one (although
|
||||
it's often more efficient for subclasses to implement them directly).
|
||||
|
||||
@param destBuffer the destination buffer for the data. This must not
|
||||
be null.
|
||||
@param maxBytesToRead the maximum number of bytes to read - make sure
|
||||
the
|
||||
memory block passed in is big enough to contain
|
||||
this
|
||||
many bytes. This value must not be negative.
|
||||
|
||||
@returns the actual number of bytes that were read, which may be less
|
||||
than
|
||||
maxBytesToRead if the stream is exhausted before it gets that
|
||||
far
|
||||
*/
|
||||
virtual int read(void* destBuffer, int maxBytesToRead) = 0;
|
||||
|
||||
/** Reads a byte from the stream.
|
||||
If the stream is exhausted, this will return zero.
|
||||
@see OutputStream::writeByte
|
||||
*/
|
||||
virtual char readByte();
|
||||
|
||||
/** Reads a boolean from the stream.
|
||||
The bool is encoded as a single byte - non-zero for true, 0 for false.
|
||||
If the stream is exhausted, this will return false.
|
||||
@see OutputStream::writeBool
|
||||
*/
|
||||
virtual bool readBool();
|
||||
|
||||
/** Reads two bytes from the stream as a little-endian 16-bit value.
|
||||
If the next two bytes read are byte1 and byte2, this returns (byte2 |
|
||||
(byte1 << 8)).
|
||||
If the stream is exhausted partway through reading the bytes, this will
|
||||
return zero.
|
||||
@see OutputStream::writeShortBigEndian, readShort
|
||||
*/
|
||||
virtual short readShortBigEndian();
|
||||
|
||||
/** Reads four bytes from the stream as a big-endian 32-bit value.
|
||||
|
||||
If the next four bytes are byte1 to byte4, this returns
|
||||
(byte4 | (byte3 << 8) | (byte2 << 16) | (byte1 << 24)).
|
||||
|
||||
If the stream is exhausted partway through reading the bytes, this will
|
||||
return zero.
|
||||
|
||||
@see OutputStream::writeIntBigEndian, readInt
|
||||
*/
|
||||
virtual int readIntBigEndian();
|
||||
|
||||
/** Reads eight bytes from the stream as a big-endian 64-bit value.
|
||||
|
||||
If the next eight bytes are byte1 to byte8, this returns
|
||||
(byte8 | (byte7 << 8) | (byte6 << 16) | (byte5 << 24) | (byte4 << 32) |
|
||||
(byte3 << 40) | (byte2 << 48) | (byte1 << 56)).
|
||||
|
||||
If the stream is exhausted partway through reading the bytes, this will
|
||||
return zero.
|
||||
|
||||
@see OutputStream::writeInt64BigEndian, readInt64
|
||||
*/
|
||||
virtual int64 readInt64BigEndian();
|
||||
|
||||
/** Reads four bytes as a 32-bit floating point value.
|
||||
The raw 32-bit encoding of the float is read from the stream as a
|
||||
big-endian int.
|
||||
If the stream is exhausted partway through reading the bytes, this will
|
||||
return zero.
|
||||
@see OutputStream::writeFloatBigEndian, readDoubleBigEndian
|
||||
*/
|
||||
virtual float readFloatBigEndian();
|
||||
|
||||
/** Reads eight bytes as a 64-bit floating point value.
|
||||
The raw 64-bit encoding of the double is read from the stream as a
|
||||
big-endian int64.
|
||||
If the stream is exhausted partway through reading the bytes, this will
|
||||
return zero.
|
||||
@see OutputStream::writeDoubleBigEndian, readFloatBigEndian
|
||||
*/
|
||||
virtual double readDoubleBigEndian();
|
||||
|
||||
//==============================================================================whole
|
||||
// stream and turn it into a string.
|
||||
/** Reads from the stream and appends the data to a MemoryBlock.
|
||||
|
||||
@param destBlock the block to append the data onto
|
||||
@param maxNumBytesToRead if this is a positive value, it sets a limit
|
||||
to the number
|
||||
of bytes that will be read - if it's negative,
|
||||
data
|
||||
will be read until the stream is exhausted.
|
||||
@returns the number of bytes that were added to the memory block
|
||||
*/
|
||||
virtual size_t readIntoMemoryBlock(MemoryBlock& destBlock, size_t maxNumBytesToRead = -1);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the offset of the next byte that will be read from the stream.
|
||||
@see setPosition
|
||||
*/
|
||||
virtual int64 getPosition() = 0;
|
||||
|
||||
/** Tries to move the current read position of the stream.
|
||||
|
||||
The position is an absolute number of bytes from the stream's start.
|
||||
|
||||
Some streams might not be able to do this, in which case they should do
|
||||
nothing and return false. Others might be able to manage it by resetting
|
||||
themselves and skipping to the correct position, although this is
|
||||
obviously a bit slow.
|
||||
|
||||
@returns true if the stream manages to reposition itself correctly
|
||||
@see getPosition
|
||||
*/
|
||||
virtual bool setPosition(int64 newPosition) = 0;
|
||||
|
||||
/** Reads and discards a number of bytes from the stream.
|
||||
|
||||
Some input streams might implement this efficiently, but the base
|
||||
class will just keep reading data until the requisite number of bytes
|
||||
have been done.
|
||||
*/
|
||||
virtual void skipNextBytes(int64 numBytesToSkip);
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
InputStream() {}
|
||||
};
|
||||
} // namespace rocketmq
|
||||
#endif // INPUTSTREAM_H_INCLUDED
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "MQClientErrorContainer.h"
|
||||
|
||||
namespace rocketmq {
|
||||
|
||||
thread_local std::string MQClientErrorContainer::t_err;
|
||||
|
||||
void MQClientErrorContainer::setErr(const std::string& str) {
|
||||
t_err = str;
|
||||
}
|
||||
|
||||
const std::string& MQClientErrorContainer::getErr() {
|
||||
return t_err;
|
||||
}
|
||||
|
||||
} // namespace rocketmq
|
||||
36
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MQClientErrorContainer.h
vendored
Normal file
36
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MQClientErrorContainer.h
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __MQ_CLIENT_ERROR_CONTAINER_H__
|
||||
#define __MQ_CLIENT_ERROR_CONTAINER_H__
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
namespace rocketmq {
|
||||
|
||||
class MQClientErrorContainer {
|
||||
public:
|
||||
static void setErr(const std::string& str);
|
||||
static const std::string& getErr();
|
||||
|
||||
private:
|
||||
static thread_local std::string t_err;
|
||||
};
|
||||
|
||||
} // namespace rocketmq
|
||||
|
||||
#endif // __MQ_CLIENT_ERROR_CONTAINER_H__
|
||||
35
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MQVersion.cpp
vendored
Normal file
35
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MQVersion.cpp
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "MQVersion.h"
|
||||
|
||||
namespace rocketmq {
|
||||
int MQVersion::s_CurrentVersion = MQVersion::V4_6_0;
|
||||
std::string MQVersion::s_CurrentLanguage = "CPP";
|
||||
|
||||
//<!************************************************************************
|
||||
const char* MQVersion::GetVersionDesc(int value) {
|
||||
int currentVersion = value;
|
||||
if (value <= V3_0_0_SNAPSHOT) {
|
||||
currentVersion = V3_0_0_SNAPSHOT;
|
||||
}
|
||||
if (value >= HIGHER_VERSION) {
|
||||
currentVersion = HIGHER_VERSION;
|
||||
}
|
||||
return RocketMQCPPClientVersion[currentVersion];
|
||||
}
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
1535
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MQVersion.h
vendored
Normal file
1535
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MQVersion.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
75
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MemoryInputStream.cpp
vendored
Normal file
75
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MemoryInputStream.cpp
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "MemoryInputStream.h"
|
||||
|
||||
namespace rocketmq {
|
||||
MemoryInputStream::MemoryInputStream(const void* const sourceData,
|
||||
const size_t sourceDataSize,
|
||||
const bool keepInternalCopy)
|
||||
: data(sourceData), dataSize(sourceDataSize), position(0), internalCopy(NULL) {
|
||||
if (keepInternalCopy)
|
||||
createInternalCopy();
|
||||
}
|
||||
|
||||
MemoryInputStream::MemoryInputStream(const MemoryBlock& sourceData, const bool keepInternalCopy)
|
||||
: data(sourceData.getData()), dataSize(sourceData.getSize()), position(0), internalCopy(NULL) {
|
||||
if (keepInternalCopy)
|
||||
createInternalCopy();
|
||||
}
|
||||
|
||||
void MemoryInputStream::createInternalCopy() {
|
||||
std::free(internalCopy);
|
||||
internalCopy = static_cast<char*>(std::malloc(dataSize));
|
||||
memcpy(internalCopy, data, dataSize);
|
||||
data = internalCopy;
|
||||
}
|
||||
|
||||
MemoryInputStream::~MemoryInputStream() {
|
||||
std::free(internalCopy);
|
||||
}
|
||||
|
||||
int64 MemoryInputStream::getTotalLength() {
|
||||
return (int64)dataSize;
|
||||
}
|
||||
|
||||
int MemoryInputStream::read(void* const buffer, const int howMany) {
|
||||
const int num = std::min(howMany, (int)(dataSize - position));
|
||||
if (num <= 0)
|
||||
return 0;
|
||||
|
||||
memcpy((char*)buffer, (char*)data + position, (size_t)num);
|
||||
position += (unsigned int)num;
|
||||
return num;
|
||||
}
|
||||
|
||||
bool MemoryInputStream::isExhausted() {
|
||||
return position >= dataSize;
|
||||
}
|
||||
|
||||
bool MemoryInputStream::setPosition(const int64 pos) {
|
||||
if (pos < 0)
|
||||
position = 0;
|
||||
else
|
||||
position = (int64)dataSize < pos ? (int64)dataSize : pos;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int64 MemoryInputStream::getPosition() {
|
||||
return (int64)position;
|
||||
}
|
||||
} // namespace rocketmq
|
||||
96
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MemoryInputStream.h
vendored
Normal file
96
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MemoryInputStream.h
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MEMORYINPUTSTREAM_H_INCLUDED
|
||||
#define MEMORYINPUTSTREAM_H_INCLUDED
|
||||
|
||||
#include "InputStream.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//==============================================================================
|
||||
/**
|
||||
Allows a block of data to be accessed as a stream.
|
||||
|
||||
This can either be used to refer to a shared block of memory, or can make
|
||||
its
|
||||
own internal copy of the data when the MemoryInputStream is created.
|
||||
*/
|
||||
class ROCKETMQCLIENT_API MemoryInputStream : public InputStream {
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a MemoryInputStream.
|
||||
|
||||
@param sourceData the block of data to use as the stream's
|
||||
source
|
||||
@param sourceDataSize the number of bytes in the source data
|
||||
block
|
||||
@param keepInternalCopyOfData if false, the stream will just keep a
|
||||
pointer to
|
||||
the source data, so this data shouldn't be
|
||||
changed
|
||||
for the lifetime of the stream; if this
|
||||
parameter is
|
||||
true, the stream will make its own copy of
|
||||
the
|
||||
data and use that.
|
||||
*/
|
||||
MemoryInputStream(const void* sourceData, size_t sourceDataSize, bool keepInternalCopyOfData);
|
||||
|
||||
/** Creates a MemoryInputStream.
|
||||
|
||||
@param data a block of data to use as the stream's
|
||||
source
|
||||
@param keepInternalCopyOfData if false, the stream will just keep a
|
||||
reference to
|
||||
the source data, so this data shouldn't be
|
||||
changed
|
||||
for the lifetime of the stream; if this
|
||||
parameter is
|
||||
true, the stream will make its own copy of
|
||||
the
|
||||
data and use that.
|
||||
*/
|
||||
MemoryInputStream(const MemoryBlock& data, bool keepInternalCopyOfData);
|
||||
|
||||
/** Destructor. */
|
||||
~MemoryInputStream();
|
||||
|
||||
/** Returns a pointer to the source data block from which this stream is
|
||||
* reading. */
|
||||
const void* getData() const { return data; }
|
||||
|
||||
/** Returns the number of bytes of source data in the block from which this
|
||||
* stream is reading. */
|
||||
size_t getDataSize() const { return dataSize; }
|
||||
|
||||
//==============================================================================
|
||||
int64 getPosition();
|
||||
bool setPosition(int64 pos);
|
||||
int64 getTotalLength();
|
||||
bool isExhausted();
|
||||
int read(void* destBuffer, int maxBytesToRead);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
const void* data;
|
||||
size_t dataSize, position;
|
||||
char* internalCopy;
|
||||
|
||||
void createInternalCopy();
|
||||
};
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
156
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MemoryOutputStream.cpp
vendored
Normal file
156
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MemoryOutputStream.cpp
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "MemoryOutputStream.h"
|
||||
|
||||
namespace rocketmq {
|
||||
MemoryOutputStream::MemoryOutputStream(const size_t initialSize)
|
||||
: blockToUse(&internalBlock), externalData(NULL), position(0), size(0), availableSize(0) {
|
||||
internalBlock.setSize(initialSize, false);
|
||||
}
|
||||
|
||||
MemoryOutputStream::MemoryOutputStream(MemoryBlock& memoryBlockToWriteTo, const bool appendToExistingBlockContent)
|
||||
: blockToUse(&memoryBlockToWriteTo), externalData(NULL), position(0), size(0), availableSize(0) {
|
||||
if (appendToExistingBlockContent)
|
||||
position = size = memoryBlockToWriteTo.getSize();
|
||||
}
|
||||
|
||||
MemoryOutputStream::MemoryOutputStream(void* destBuffer, size_t destBufferSize)
|
||||
: blockToUse(NULL), externalData(destBuffer), position(0), size(0), availableSize(destBufferSize) {}
|
||||
|
||||
MemoryOutputStream::~MemoryOutputStream() {
|
||||
trimExternalBlockSize();
|
||||
}
|
||||
|
||||
void MemoryOutputStream::flush() {
|
||||
trimExternalBlockSize();
|
||||
}
|
||||
|
||||
void MemoryOutputStream::trimExternalBlockSize() {
|
||||
if (blockToUse != &internalBlock && blockToUse != NULL)
|
||||
blockToUse->setSize(size, false);
|
||||
}
|
||||
|
||||
void MemoryOutputStream::preallocate(const size_t bytesToPreallocate) {
|
||||
if (blockToUse != NULL)
|
||||
blockToUse->ensureSize(bytesToPreallocate + 1);
|
||||
}
|
||||
|
||||
void MemoryOutputStream::reset() {
|
||||
position = 0;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
char* MemoryOutputStream::prepareToWrite(size_t numBytes) {
|
||||
size_t storageNeeded = position + numBytes;
|
||||
|
||||
char* data;
|
||||
|
||||
if (blockToUse != NULL) {
|
||||
if (storageNeeded >= (unsigned int)(blockToUse->getSize()))
|
||||
blockToUse->ensureSize((storageNeeded + std::min(storageNeeded / 2, (size_t)(1024 * 1024)) + 32) & ~31u);
|
||||
|
||||
data = static_cast<char*>(blockToUse->getData());
|
||||
} else {
|
||||
if (storageNeeded > availableSize)
|
||||
return NULL;
|
||||
|
||||
data = static_cast<char*>(externalData);
|
||||
}
|
||||
|
||||
char* const writePointer = data + position;
|
||||
position += numBytes;
|
||||
size = std::max(size, position);
|
||||
return writePointer;
|
||||
}
|
||||
|
||||
bool MemoryOutputStream::write(const void* const buffer, size_t howMany) {
|
||||
if (howMany == 0)
|
||||
return true;
|
||||
|
||||
if (char* dest = prepareToWrite(howMany)) {
|
||||
memcpy(dest, buffer, howMany);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MemoryOutputStream::writeRepeatedByte(uint8 byte, size_t howMany) {
|
||||
if (howMany == 0)
|
||||
return true;
|
||||
|
||||
if (char* dest = prepareToWrite(howMany)) {
|
||||
memset(dest, byte, howMany);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
MemoryBlock MemoryOutputStream::getMemoryBlock() const {
|
||||
return MemoryBlock(getData(), getDataSize());
|
||||
}
|
||||
|
||||
const void* MemoryOutputStream::getData() const {
|
||||
if (blockToUse == NULL)
|
||||
return externalData;
|
||||
|
||||
if ((unsigned int)blockToUse->getSize() > size)
|
||||
static_cast<char*>(blockToUse->getData())[size] = 0;
|
||||
|
||||
return blockToUse->getData();
|
||||
}
|
||||
|
||||
bool MemoryOutputStream::setPosition(int64 newPosition) {
|
||||
if (newPosition <= (int64)size) {
|
||||
// ok to seek backwards
|
||||
if (newPosition < 0)
|
||||
position = 0;
|
||||
else
|
||||
position = (int64)size < newPosition ? size : newPosition;
|
||||
return true;
|
||||
}
|
||||
|
||||
// can't move beyond the end of the stream..
|
||||
return false;
|
||||
}
|
||||
|
||||
int64 MemoryOutputStream::writeFromInputStream(InputStream& source, int64 maxNumBytesToWrite) {
|
||||
// before writing from an input, see if we can preallocate to make it more
|
||||
// efficient..
|
||||
int64 availableData = source.getTotalLength() - source.getPosition();
|
||||
|
||||
if (availableData > 0) {
|
||||
if (maxNumBytesToWrite > availableData || maxNumBytesToWrite < 0)
|
||||
maxNumBytesToWrite = availableData;
|
||||
|
||||
if (blockToUse != NULL)
|
||||
preallocate(blockToUse->getSize() + (size_t)maxNumBytesToWrite);
|
||||
}
|
||||
|
||||
return OutputStream::writeFromInputStream(source, maxNumBytesToWrite);
|
||||
}
|
||||
|
||||
OutputStream& operator<<(OutputStream& stream, const MemoryOutputStream& streamToRead) {
|
||||
const size_t dataSize = streamToRead.getDataSize();
|
||||
|
||||
if (dataSize > 0)
|
||||
stream.write(streamToRead.getData(), dataSize);
|
||||
|
||||
return stream;
|
||||
}
|
||||
} // namespace rocketmq
|
||||
130
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MemoryOutputStream.h
vendored
Normal file
130
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MemoryOutputStream.h
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MEMORYOUTPUTSTREAM_H_INCLUDED
|
||||
#define MEMORYOUTPUTSTREAM_H_INCLUDED
|
||||
|
||||
#include "OutputStream.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//==============================================================================
|
||||
/**
|
||||
Writes data to an internal memory buffer, which grows as required.
|
||||
|
||||
The data that was written into the stream can then be accessed later as
|
||||
a contiguous block of memory.
|
||||
*/
|
||||
class ROCKETMQCLIENT_API MemoryOutputStream : public OutputStream {
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty memory stream, ready to be written into.
|
||||
@param initialSize the intial amount of capacity to allocate for writing
|
||||
into
|
||||
*/
|
||||
MemoryOutputStream(size_t initialSize = 256);
|
||||
|
||||
/** Creates a memory stream for writing into into a pre-existing MemoryBlock
|
||||
object.
|
||||
|
||||
Note that the destination block will always be larger than the amount of
|
||||
data
|
||||
that has been written to the stream, because the MemoryOutputStream keeps
|
||||
some
|
||||
spare capactity at its end. To trim the block's size down to fit the
|
||||
actual
|
||||
data, call flush(), or delete the MemoryOutputStream.
|
||||
|
||||
@param memoryBlockToWriteTo the block into which new data will
|
||||
be written.
|
||||
@param appendToExistingBlockContent if this is true, the contents of
|
||||
the block will be
|
||||
kept, and new data will be
|
||||
appended to it. If false,
|
||||
the block will be cleared before
|
||||
use
|
||||
*/
|
||||
MemoryOutputStream(MemoryBlock& memoryBlockToWriteTo, bool appendToExistingBlockContent);
|
||||
|
||||
/** Creates a MemoryOutputStream that will write into a user-supplied,
|
||||
fixed-size
|
||||
block of memory.
|
||||
When using this mode, the stream will write directly into this memory area
|
||||
until
|
||||
it's full, at which point write operations will fail.
|
||||
*/
|
||||
MemoryOutputStream(void* destBuffer, size_t destBufferSize);
|
||||
|
||||
/** Destructor.
|
||||
This will free any data that was written to it.
|
||||
*/
|
||||
~MemoryOutputStream();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a pointer to the data that has been written to the stream.
|
||||
@see getDataSize
|
||||
*/
|
||||
const void* getData() const;
|
||||
|
||||
/** Returns the number of bytes of data that have been written to the stream.
|
||||
@see getData
|
||||
*/
|
||||
size_t getDataSize() const { return size; }
|
||||
|
||||
/** Resets the stream, clearing any data that has been written to it so far.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/** Increases the internal storage capacity to be able to contain at least the
|
||||
specified
|
||||
amount of data without needing to be resized.
|
||||
*/
|
||||
void preallocate(size_t bytesToPreallocate);
|
||||
|
||||
/** Returns a copy of the stream's data as a memory block. */
|
||||
MemoryBlock getMemoryBlock() const;
|
||||
|
||||
//==============================================================================
|
||||
/** If the stream is writing to a user-supplied MemoryBlock, this will trim
|
||||
any excess
|
||||
capacity off the block, so that its length matches the amount of actual
|
||||
data that
|
||||
has been written so far.
|
||||
*/
|
||||
void flush();
|
||||
|
||||
bool write(const void*, size_t);
|
||||
int64 getPosition() { return (int64)position; }
|
||||
bool setPosition(int64);
|
||||
int64 writeFromInputStream(InputStream&, int64 maxNumBytesToWrite);
|
||||
bool writeRepeatedByte(uint8 byte, size_t numTimesToRepeat);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
MemoryBlock* const blockToUse;
|
||||
MemoryBlock internalBlock;
|
||||
void* externalData;
|
||||
size_t position, size, availableSize;
|
||||
|
||||
void trimExternalBlockSize();
|
||||
char* prepareToWrite(size_t);
|
||||
};
|
||||
|
||||
/** Copies all the data that has been written to a MemoryOutputStream into
|
||||
* another stream. */
|
||||
OutputStream& operator<<(OutputStream& stream, const MemoryOutputStream& streamToRead);
|
||||
} // namespace rocketmq
|
||||
#endif // MEMORYOUTPUTSTREAM_H_INCLUDED
|
||||
56
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MessageAccessor.cpp
vendored
Normal file
56
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MessageAccessor.cpp
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "MessageAccessor.h"
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include "Logging.h"
|
||||
#include "NameSpaceUtil.h"
|
||||
|
||||
using namespace std;
|
||||
namespace rocketmq {
|
||||
|
||||
void MessageAccessor::withNameSpace(MQMessage& msg, const string nameSpace) {
|
||||
if (!nameSpace.empty()) {
|
||||
string originTopic = msg.getTopic();
|
||||
string newTopic = nameSpace + NAMESPACE_SPLIT_FLAG + originTopic;
|
||||
msg.setTopic(newTopic);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageAccessor::withoutNameSpaceSingle(MQMessageExt& msg, const string nameSpace) {
|
||||
if (!nameSpace.empty()) {
|
||||
string originTopic = msg.getTopic();
|
||||
auto index = originTopic.find(nameSpace);
|
||||
if (index != string::npos) {
|
||||
string newTopic =
|
||||
originTopic.substr(index + nameSpace.length() + NAMESPACE_SPLIT_FLAG.length(), originTopic.length());
|
||||
msg.setTopic(newTopic);
|
||||
LOG_DEBUG("Find Name Space Prefix in MessageID[%s], OriginTopic[%s], NewTopic[%s]", msg.getMsgId().c_str(),
|
||||
originTopic.c_str(), newTopic.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
void MessageAccessor::withoutNameSpace(vector<MQMessageExt>& msgs, const string nameSpace) {
|
||||
if (!nameSpace.empty()) {
|
||||
// for_each(msgs.cbegin(), msgs.cend(), bind2nd(&MessageAccessor::withoutNameSpaceSingle, nameSpace));
|
||||
for (auto iter = msgs.begin(); iter != msgs.end(); iter++) {
|
||||
withoutNameSpaceSingle(*iter, nameSpace);
|
||||
}
|
||||
}
|
||||
}
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
35
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MessageAccessor.h
vendored
Normal file
35
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MessageAccessor.h
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __MESSAGE_ACCESSOR_H__
|
||||
#define __MESSAGE_ACCESSOR_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "MQMessage.h"
|
||||
#include "MQMessageExt.h"
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
class MessageAccessor {
|
||||
public:
|
||||
static void withNameSpace(MQMessage& msg, const std::string nameSpace);
|
||||
static void withoutNameSpaceSingle(MQMessageExt& msg, const std::string nameSpace);
|
||||
static void withoutNameSpace(std::vector<MQMessageExt>& msgs, const std::string nameSpace);
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
37
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MessageSysFlag.cpp
vendored
Normal file
37
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MessageSysFlag.cpp
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "MessageSysFlag.h"
|
||||
|
||||
namespace rocketmq {
|
||||
int MessageSysFlag::CompressedFlag = (0x1 << 0);
|
||||
int MessageSysFlag::MultiTagsFlag = (0x1 << 1);
|
||||
|
||||
int MessageSysFlag::TransactionNotType = (0x0 << 2);
|
||||
int MessageSysFlag::TransactionPreparedType = (0x1 << 2);
|
||||
int MessageSysFlag::TransactionCommitType = (0x2 << 2);
|
||||
int MessageSysFlag::TransactionRollbackType = (0x3 << 2);
|
||||
|
||||
int MessageSysFlag::getTransactionValue(int flag) {
|
||||
return flag & TransactionRollbackType;
|
||||
}
|
||||
|
||||
int MessageSysFlag::resetTransactionValue(int flag, int type) {
|
||||
return (flag & (~TransactionRollbackType)) | type;
|
||||
}
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
38
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MessageSysFlag.h
vendored
Normal file
38
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/MessageSysFlag.h
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __MESSAGESYSFLAG_H__
|
||||
#define __MESSAGESYSFLAG_H__
|
||||
|
||||
namespace rocketmq {
|
||||
//<!************************************************************************
|
||||
class MessageSysFlag {
|
||||
public:
|
||||
static int getTransactionValue(int flag);
|
||||
static int resetTransactionValue(int flag, int type);
|
||||
|
||||
public:
|
||||
static int CompressedFlag;
|
||||
static int MultiTagsFlag;
|
||||
static int TransactionNotType;
|
||||
static int TransactionPreparedType;
|
||||
static int TransactionCommitType;
|
||||
static int TransactionRollbackType;
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
105
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/NameSpaceUtil.cpp
vendored
Normal file
105
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/NameSpaceUtil.cpp
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "NameSpaceUtil.h"
|
||||
#include "Logging.h"
|
||||
#include "TraceContant.h"
|
||||
|
||||
namespace rocketmq {
|
||||
|
||||
bool NameSpaceUtil::isEndPointURL(string nameServerAddr) {
|
||||
if (nameServerAddr.length() >= ENDPOINT_PREFIX_LENGTH && nameServerAddr.find(ENDPOINT_PREFIX) != string::npos) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
string NameSpaceUtil::formatNameServerURL(string nameServerAddr) {
|
||||
auto index = nameServerAddr.find(ENDPOINT_PREFIX);
|
||||
if (index != string::npos) {
|
||||
LOG_DEBUG("Get Name Server from endpoint [%s]",
|
||||
nameServerAddr.substr(ENDPOINT_PREFIX_LENGTH, nameServerAddr.length() - ENDPOINT_PREFIX_LENGTH).c_str());
|
||||
return nameServerAddr.substr(ENDPOINT_PREFIX_LENGTH, nameServerAddr.length() - ENDPOINT_PREFIX_LENGTH);
|
||||
}
|
||||
return nameServerAddr;
|
||||
}
|
||||
|
||||
string NameSpaceUtil::getNameSpaceFromNsURL(string nameServerAddr) {
|
||||
LOG_DEBUG("Try to get Name Space from nameServerAddr [%s]", nameServerAddr.c_str());
|
||||
string nsAddr = formatNameServerURL(nameServerAddr);
|
||||
string nameSpace;
|
||||
auto index = nsAddr.find(NAMESPACE_PREFIX);
|
||||
if (index != string::npos) {
|
||||
auto indexDot = nsAddr.find('.');
|
||||
if (indexDot != string::npos && indexDot > index) {
|
||||
nameSpace = nsAddr.substr(index, indexDot - index);
|
||||
LOG_INFO("Get Name Space [%s] from nameServerAddr [%s]", nameSpace.c_str(), nameServerAddr.c_str());
|
||||
return nameSpace;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool NameSpaceUtil::checkNameSpaceExistInNsURL(string nameServerAddr) {
|
||||
if (!isEndPointURL(nameServerAddr)) {
|
||||
LOG_DEBUG("This nameServerAddr [%s] is not a endpoint. should not get Name Space.", nameServerAddr.c_str());
|
||||
return false;
|
||||
}
|
||||
auto index = nameServerAddr.find(NAMESPACE_PREFIX);
|
||||
if (index != string::npos) {
|
||||
LOG_INFO("Find Name Space Prefix in nameServerAddr [%s]", nameServerAddr.c_str());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NameSpaceUtil::checkNameSpaceExistInNameServer(string nameServerAddr) {
|
||||
auto index = nameServerAddr.find(NAMESPACE_PREFIX);
|
||||
if (index != string::npos) {
|
||||
LOG_INFO("Find Name Space Prefix in nameServerAddr [%s]", nameServerAddr.c_str());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
string NameSpaceUtil::withoutNameSpace(string source, string nameSpace) {
|
||||
if (!nameSpace.empty()) {
|
||||
auto index = source.find(nameSpace);
|
||||
if (index != string::npos) {
|
||||
return source.substr(index + nameSpace.length() + NAMESPACE_SPLIT_FLAG.length(), source.length());
|
||||
}
|
||||
}
|
||||
return source;
|
||||
}
|
||||
string NameSpaceUtil::withNameSpace(string source, string ns) {
|
||||
if (!ns.empty()) {
|
||||
return ns + NAMESPACE_SPLIT_FLAG + source;
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
bool NameSpaceUtil::hasNameSpace(string source, string ns) {
|
||||
if (source.find(TraceContant::TRACE_TOPIC) != string::npos) {
|
||||
LOG_DEBUG("Find Trace Topic [%s]", source.c_str());
|
||||
return true;
|
||||
}
|
||||
if (!ns.empty() && source.length() >= ns.length() && source.find(ns) != string::npos) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace rocketmq
|
||||
52
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/NameSpaceUtil.h
vendored
Normal file
52
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/NameSpaceUtil.h
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __NAMESPACEUTIL_H__
|
||||
#define __NAMESPACEUTIL_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const string ENDPOINT_PREFIX = "http://";
|
||||
static const unsigned int ENDPOINT_PREFIX_LENGTH = ENDPOINT_PREFIX.length();
|
||||
static const string NAMESPACE_PREFIX = "MQ_INST_";
|
||||
static const int NAMESPACE_PREFIX_LENGTH = NAMESPACE_PREFIX.length();
|
||||
static const string NAMESPACE_SPLIT_FLAG = "%";
|
||||
|
||||
namespace rocketmq {
|
||||
class NameSpaceUtil {
|
||||
public:
|
||||
static bool isEndPointURL(string nameServerAddr);
|
||||
|
||||
static string formatNameServerURL(string nameServerAddr);
|
||||
|
||||
static string getNameSpaceFromNsURL(string nameServerAddr);
|
||||
|
||||
static bool checkNameSpaceExistInNsURL(string nameServerAddr);
|
||||
|
||||
static bool checkNameSpaceExistInNameServer(string nameServerAddr);
|
||||
|
||||
static string withNameSpace(string source, string ns);
|
||||
|
||||
static string withoutNameSpace(string source, string ns);
|
||||
|
||||
static bool hasNameSpace(string source, string ns);
|
||||
};
|
||||
|
||||
} // namespace rocketmq
|
||||
#endif //__NAMESPACEUTIL_H__
|
||||
54
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/NamesrvConfig.h
vendored
Normal file
54
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/NamesrvConfig.h
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __NAMESRVCONFIG_H__
|
||||
#define __NAMESRVCONFIG_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include "UtilAll.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
class NamesrvConfig {
|
||||
public:
|
||||
NamesrvConfig() {
|
||||
m_kvConfigPath = "";
|
||||
|
||||
char* home = getenv(rocketmq::ROCKETMQ_HOME_ENV.c_str());
|
||||
if (home) {
|
||||
m_rocketmqHome = home;
|
||||
} else {
|
||||
m_rocketmqHome = "";
|
||||
}
|
||||
}
|
||||
|
||||
const string& getRocketmqHome() const { return m_rocketmqHome; }
|
||||
|
||||
void setRocketmqHome(const string& rocketmqHome) { m_rocketmqHome = rocketmqHome; }
|
||||
|
||||
const string& getKvConfigPath() const { return m_kvConfigPath; }
|
||||
|
||||
void setKvConfigPath(const string& kvConfigPath) { m_kvConfigPath = kvConfigPath; }
|
||||
|
||||
private:
|
||||
string m_rocketmqHome;
|
||||
string m_kvConfigPath;
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
104
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/OutputStream.cpp
vendored
Normal file
104
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/OutputStream.cpp
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "OutputStream.h"
|
||||
#include <limits>
|
||||
#include "big_endian.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//==============================================================================
|
||||
OutputStream::OutputStream() {}
|
||||
|
||||
OutputStream::~OutputStream() {}
|
||||
|
||||
//==============================================================================
|
||||
bool OutputStream::writeBool(const bool b) {
|
||||
return writeByte(b ? (char)1 : (char)0);
|
||||
}
|
||||
|
||||
bool OutputStream::writeByte(char byte) {
|
||||
return write(&byte, 1);
|
||||
}
|
||||
|
||||
bool OutputStream::writeRepeatedByte(uint8 byte, size_t numTimesToRepeat) {
|
||||
for (size_t i = 0; i < numTimesToRepeat; ++i)
|
||||
if (!writeByte((char)byte))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OutputStream::writeShortBigEndian(short value) {
|
||||
unsigned short v;
|
||||
char pShort[sizeof(v)];
|
||||
WriteBigEndian(pShort, (unsigned short)value);
|
||||
return write(pShort, 2);
|
||||
}
|
||||
|
||||
bool OutputStream::writeIntBigEndian(int value) {
|
||||
unsigned int v;
|
||||
char pInt[sizeof(v)];
|
||||
WriteBigEndian(pInt, (unsigned int)value);
|
||||
return write(pInt, 4);
|
||||
}
|
||||
|
||||
bool OutputStream::writeInt64BigEndian(int64 value) {
|
||||
uint64 v;
|
||||
char pUint64[sizeof(v)];
|
||||
WriteBigEndian(pUint64, (uint64)value);
|
||||
return write(pUint64, 8);
|
||||
}
|
||||
|
||||
bool OutputStream::writeFloatBigEndian(float value) {
|
||||
union {
|
||||
int asInt;
|
||||
float asFloat;
|
||||
} n;
|
||||
n.asFloat = value;
|
||||
return writeIntBigEndian(n.asInt);
|
||||
}
|
||||
|
||||
bool OutputStream::writeDoubleBigEndian(double value) {
|
||||
union {
|
||||
int64 asInt;
|
||||
double asDouble;
|
||||
} n;
|
||||
n.asDouble = value;
|
||||
return writeInt64BigEndian(n.asInt);
|
||||
}
|
||||
|
||||
int64 OutputStream::writeFromInputStream(InputStream& source, int64 numBytesToWrite) {
|
||||
if (numBytesToWrite < 0)
|
||||
numBytesToWrite = std::numeric_limits<int64>::max();
|
||||
|
||||
int64 numWritten = 0;
|
||||
|
||||
while (numBytesToWrite > 0) {
|
||||
char buffer[8192];
|
||||
const int num = source.read(buffer, (int)std::min(numBytesToWrite, (int64)sizeof(buffer)));
|
||||
|
||||
if (num <= 0)
|
||||
break;
|
||||
|
||||
write(buffer, (size_t)num);
|
||||
|
||||
numBytesToWrite -= num;
|
||||
numWritten += num;
|
||||
}
|
||||
|
||||
return numWritten;
|
||||
}
|
||||
} // namespace rocketmq
|
||||
148
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/OutputStream.h
vendored
Normal file
148
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/OutputStream.h
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OUTPUTSTREAM_H_INCLUDED
|
||||
#define OUTPUTSTREAM_H_INCLUDED
|
||||
|
||||
#include "InputStream.h"
|
||||
namespace rocketmq {
|
||||
//==============================================================================
|
||||
/**
|
||||
The base class for streams that write data to some kind of destination.
|
||||
|
||||
Input and output streams are used throughout the library - subclasses can
|
||||
override
|
||||
some or all of the virtual functions to implement their behaviour.
|
||||
|
||||
@see InputStream, MemoryOutputStream, FileOutputStream
|
||||
*/
|
||||
class ROCKETMQCLIENT_API OutputStream {
|
||||
protected:
|
||||
//==============================================================================
|
||||
OutputStream();
|
||||
|
||||
public:
|
||||
/** Destructor.
|
||||
|
||||
Some subclasses might want to do things like call flush() during their
|
||||
destructors.
|
||||
*/
|
||||
virtual ~OutputStream();
|
||||
|
||||
//==============================================================================
|
||||
/** If the stream is using a buffer, this will ensure it gets written
|
||||
out to the destination. */
|
||||
virtual void flush() = 0;
|
||||
|
||||
/** Tries to move the stream's output position.
|
||||
|
||||
Not all streams will be able to seek to a new position - this will return
|
||||
false if it fails to work.
|
||||
|
||||
@see getPosition
|
||||
*/
|
||||
virtual bool setPosition(int64 newPosition) = 0;
|
||||
|
||||
/** Returns the stream's current position.
|
||||
|
||||
@see setPosition
|
||||
*/
|
||||
virtual int64 getPosition() = 0;
|
||||
|
||||
//==============================================================================
|
||||
/** Writes a block of data to the stream.
|
||||
|
||||
When creating a subclass of OutputStream, this is the only write method
|
||||
that needs to be overloaded - the base class has methods for writing other
|
||||
types of data which use this to do the work.
|
||||
|
||||
@param dataToWrite the target buffer to receive the data. This must
|
||||
not be null.
|
||||
@param numberOfBytes the number of bytes to write.
|
||||
@returns false if the write operation fails for some reason
|
||||
*/
|
||||
virtual bool write(const void* dataToWrite, size_t numberOfBytes) = 0;
|
||||
|
||||
//==============================================================================
|
||||
/** Writes a single byte to the stream.
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readByte
|
||||
*/
|
||||
virtual bool writeByte(char byte);
|
||||
|
||||
/** Writes a boolean to the stream as a single byte.
|
||||
This is encoded as a binary byte (not as text) with a value of 1 or 0.
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readBool
|
||||
*/
|
||||
virtual bool writeBool(bool boolValue);
|
||||
|
||||
/** Writes a 16-bit integer to the stream in a big-endian byte order.
|
||||
This will write two bytes to the stream: (value >> 8), then (value &
|
||||
0xff).
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readShortBigEndian
|
||||
*/
|
||||
virtual bool writeShortBigEndian(short value);
|
||||
|
||||
/** Writes a 32-bit integer to the stream in a big-endian byte order.
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readIntBigEndian
|
||||
*/
|
||||
virtual bool writeIntBigEndian(int value);
|
||||
|
||||
/** Writes a 64-bit integer to the stream in a big-endian byte order.
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readInt64BigEndian
|
||||
*/
|
||||
virtual bool writeInt64BigEndian(int64 value);
|
||||
|
||||
/** Writes a 32-bit floating point value to the stream in a binary format.
|
||||
The binary 32-bit encoding of the float is written as a big-endian int.
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readFloatBigEndian
|
||||
*/
|
||||
virtual bool writeFloatBigEndian(float value);
|
||||
|
||||
/** Writes a 64-bit floating point value to the stream in a binary format.
|
||||
The eight raw bytes of the double value are written out as a big-endian
|
||||
64-bit int.
|
||||
@see InputStream::readDoubleBigEndian
|
||||
@returns false if the write operation fails for some reason
|
||||
*/
|
||||
virtual bool writeDoubleBigEndian(double value);
|
||||
|
||||
/** Writes a byte to the output stream a given number of times.
|
||||
@returns false if the write operation fails for some reason
|
||||
*/
|
||||
virtual bool writeRepeatedByte(uint8 byte, size_t numTimesToRepeat);
|
||||
|
||||
/** Reads data from an input stream and writes it to this stream.
|
||||
|
||||
@param source the stream to read from
|
||||
@param maxNumBytesToWrite the number of bytes to read from the stream
|
||||
(if this is
|
||||
less than zero, it will keep reading until the
|
||||
input
|
||||
is exhausted)
|
||||
@returns the number of bytes written
|
||||
*/
|
||||
virtual int64 writeFromInputStream(InputStream& source, int64 maxNumBytesToWrite);
|
||||
};
|
||||
} // namespace rocketmq
|
||||
|
||||
#endif // OUTPUTSTREAM_H_INCLUDED
|
||||
57
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/PermName.cpp
vendored
Normal file
57
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/PermName.cpp
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "PermName.h"
|
||||
#include "UtilAll.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
int PermName::PERM_PRIORITY = 0x1 << 3;
|
||||
int PermName::PERM_READ = 0x1 << 2;
|
||||
int PermName::PERM_WRITE = 0x1 << 1;
|
||||
int PermName::PERM_INHERIT = 0x1 << 0;
|
||||
|
||||
bool PermName::isReadable(int perm) {
|
||||
return (perm & PERM_READ) == PERM_READ;
|
||||
}
|
||||
|
||||
bool PermName::isWriteable(int perm) {
|
||||
return (perm & PERM_WRITE) == PERM_WRITE;
|
||||
}
|
||||
|
||||
bool PermName::isInherited(int perm) {
|
||||
return (perm & PERM_INHERIT) == PERM_INHERIT;
|
||||
}
|
||||
|
||||
string PermName::perm2String(int perm) {
|
||||
string pm("---");
|
||||
if (isReadable(perm)) {
|
||||
pm.replace(0, 1, "R");
|
||||
}
|
||||
|
||||
if (isWriteable(perm)) {
|
||||
pm.replace(1, 2, "W");
|
||||
}
|
||||
|
||||
if (isInherited(perm)) {
|
||||
pm.replace(2, 3, "X");
|
||||
}
|
||||
|
||||
return pm;
|
||||
}
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
39
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/PermName.h
vendored
Normal file
39
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/PermName.h
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __PERMNAME_H__
|
||||
#define __PERMNAME_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
class PermName {
|
||||
public:
|
||||
static int PERM_PRIORITY;
|
||||
static int PERM_READ;
|
||||
static int PERM_WRITE;
|
||||
static int PERM_INHERIT;
|
||||
|
||||
static bool isReadable(int perm);
|
||||
static bool isWriteable(int perm);
|
||||
static bool isInherited(int perm);
|
||||
static std::string perm2String(int perm);
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
69
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/PullSysFlag.cpp
vendored
Normal file
69
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/PullSysFlag.cpp
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "PullSysFlag.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!************************************************************************
|
||||
int PullSysFlag::FLAG_COMMIT_OFFSET = 0x1 << 0;
|
||||
int PullSysFlag::FLAG_SUSPEND = 0x1 << 1;
|
||||
int PullSysFlag::FLAG_SUBSCRIPTION = 0x1 << 2;
|
||||
int PullSysFlag::FLAG_CLASS_FILTER = 0x1 << 3;
|
||||
|
||||
int PullSysFlag::buildSysFlag(bool commitOffset, bool suspend, bool subscription, bool classFilter) {
|
||||
int flag = 0;
|
||||
|
||||
if (commitOffset) {
|
||||
flag |= FLAG_COMMIT_OFFSET;
|
||||
}
|
||||
|
||||
if (suspend) {
|
||||
flag |= FLAG_SUSPEND;
|
||||
}
|
||||
|
||||
if (subscription) {
|
||||
flag |= FLAG_SUBSCRIPTION;
|
||||
}
|
||||
|
||||
if (classFilter) {
|
||||
flag |= FLAG_CLASS_FILTER;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
int PullSysFlag::clearCommitOffsetFlag(int sysFlag) {
|
||||
return sysFlag & (~FLAG_COMMIT_OFFSET);
|
||||
}
|
||||
|
||||
bool PullSysFlag::hasCommitOffsetFlag(int sysFlag) {
|
||||
return (sysFlag & FLAG_COMMIT_OFFSET) == FLAG_COMMIT_OFFSET;
|
||||
}
|
||||
|
||||
bool PullSysFlag::hasSuspendFlag(int sysFlag) {
|
||||
return (sysFlag & FLAG_SUSPEND) == FLAG_SUSPEND;
|
||||
}
|
||||
|
||||
bool PullSysFlag::hasSubscriptionFlag(int sysFlag) {
|
||||
return (sysFlag & FLAG_SUBSCRIPTION) == FLAG_SUBSCRIPTION;
|
||||
}
|
||||
|
||||
bool PullSysFlag::hasClassFilterFlag(int sysFlag) {
|
||||
return (sysFlag & FLAG_CLASS_FILTER) == FLAG_CLASS_FILTER;
|
||||
}
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
40
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/PullSysFlag.h
vendored
Normal file
40
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/PullSysFlag.h
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __PULLSYSFLAG_H__
|
||||
#define __PULLSYSFLAG_H__
|
||||
namespace rocketmq {
|
||||
//<!************************************************************************
|
||||
class PullSysFlag {
|
||||
public:
|
||||
static int buildSysFlag(bool commitOffset, bool suspend, bool subscription, bool classFilter);
|
||||
|
||||
static int clearCommitOffsetFlag(int sysFlag);
|
||||
static bool hasCommitOffsetFlag(int sysFlag);
|
||||
static bool hasSuspendFlag(int sysFlag);
|
||||
static bool hasSubscriptionFlag(int sysFlag);
|
||||
static bool hasClassFilterFlag(int sysFlag);
|
||||
|
||||
private:
|
||||
static int FLAG_COMMIT_OFFSET;
|
||||
static int FLAG_SUSPEND;
|
||||
static int FLAG_SUBSCRIPTION;
|
||||
static int FLAG_CLASS_FILTER;
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
25
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/ServiceState.h
vendored
Normal file
25
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/ServiceState.h
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __SERVICESTATE_H__
|
||||
#define __SERVICESTATE_H__
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
enum ServiceState { CREATE_JUST, RUNNING, SHUTDOWN_ALREADY, START_FAILED };
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
49
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/SubscriptionGroupConfig.h
vendored
Normal file
49
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/SubscriptionGroupConfig.h
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __SUBSCRIPTIONGROUPCONFIG_H__
|
||||
#define __SUBSCRIPTIONGROUPCONFIG_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
class SubscriptionGroupConfig {
|
||||
public:
|
||||
SubscriptionGroupConfig(const string& groupName) {
|
||||
this->groupName = groupName;
|
||||
consumeEnable = true;
|
||||
consumeFromMinEnable = true;
|
||||
consumeBroadcastEnable = true;
|
||||
retryQueueNums = 1;
|
||||
retryMaxTimes = 5;
|
||||
brokerId = MASTER_ID;
|
||||
whichBrokerWhenConsumeSlowly = 1;
|
||||
}
|
||||
|
||||
string groupName;
|
||||
bool consumeEnable;
|
||||
bool consumeFromMinEnable;
|
||||
bool consumeBroadcastEnable;
|
||||
int retryQueueNums;
|
||||
int retryMaxTimes;
|
||||
int brokerId;
|
||||
int whichBrokerWhenConsumeSlowly;
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
105
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/TopAddressing.cpp
vendored
Normal file
105
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/TopAddressing.cpp
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "TopAddressing.h"
|
||||
#include <vector>
|
||||
#include "UtilAll.h"
|
||||
#include "sync_http_client.h"
|
||||
#include "url.h"
|
||||
|
||||
namespace rocketmq {
|
||||
TopAddressing::TopAddressing(string unitName) : m_unitName(unitName) {}
|
||||
|
||||
TopAddressing::~TopAddressing() {}
|
||||
|
||||
int TopAddressing::IsIPAddr(const char* sValue) {
|
||||
if (NULL == sValue)
|
||||
return -1;
|
||||
|
||||
while (*sValue != '\0') {
|
||||
if ((*sValue < '0' || *sValue > '9') && (*sValue != '.'))
|
||||
return -1;
|
||||
sValue++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TopAddressing::updateNameServerAddressList(const string& adds) {
|
||||
boost::lock_guard<boost::mutex> lock(m_addrLock);
|
||||
vector<string> out;
|
||||
UtilAll::Split(out, adds, ";");
|
||||
if (out.size() > 0)
|
||||
m_addrs.clear();
|
||||
for (size_t i = 0; i < out.size(); i++) {
|
||||
string addr = out[i];
|
||||
UtilAll::Trim(addr);
|
||||
|
||||
list<string>::iterator findit = find(m_addrs.begin(), m_addrs.end(), addr);
|
||||
if (findit == m_addrs.end()) {
|
||||
string hostName;
|
||||
short portNumber;
|
||||
if (UtilAll::SplitURL(addr, hostName, portNumber)) {
|
||||
LOG_INFO("updateNameServerAddressList:%s", addr.c_str());
|
||||
m_addrs.push_back(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string TopAddressing::fetchNSAddr(const string& NSDomain) {
|
||||
LOG_DEBUG("fetchNSAddr begin");
|
||||
string nsAddr = NSDomain.empty() ? WS_ADDR : NSDomain;
|
||||
if (!m_unitName.empty()) {
|
||||
nsAddr = nsAddr + "-" + m_unitName + "?nofix=1";
|
||||
LOG_INFO("NSAddr is:%s", nsAddr.c_str());
|
||||
}
|
||||
|
||||
std::string tmp_nameservers;
|
||||
std::string nameservers;
|
||||
Url url_s(nsAddr);
|
||||
LOG_INFO("fetchNSAddr protocol: %s, port: %s, host:%s, path:%s, ", url_s.protocol_.c_str(), url_s.port_.c_str(),
|
||||
url_s.host_.c_str(), url_s.path_.c_str());
|
||||
|
||||
bool ret = SyncfetchNsAddr(url_s, tmp_nameservers);
|
||||
if (ret) {
|
||||
nameservers = clearNewLine(tmp_nameservers);
|
||||
if (nameservers.empty()) {
|
||||
LOG_ERROR("fetchNSAddr with domain is empty");
|
||||
} else {
|
||||
updateNameServerAddressList(nameservers);
|
||||
}
|
||||
} else {
|
||||
LOG_ERROR("fetchNSAddr with domain failed, connect failure or wrong response");
|
||||
}
|
||||
|
||||
return nameservers;
|
||||
}
|
||||
|
||||
string TopAddressing::clearNewLine(const string& str) {
|
||||
string newString = str;
|
||||
size_t index = newString.find("\r");
|
||||
if (index != string::npos) {
|
||||
return newString.substr(0, index);
|
||||
}
|
||||
|
||||
index = newString.find("\n");
|
||||
if (index != string::npos) {
|
||||
return newString.substr(0, index);
|
||||
}
|
||||
|
||||
return newString;
|
||||
}
|
||||
} // namespace rocketmq
|
||||
47
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/TopAddressing.h
vendored
Normal file
47
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/TopAddressing.h
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __TOPADDRESSING_H__
|
||||
#define __TOPADDRESSING_H__
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "Logging.h"
|
||||
#include "UtilAll.h"
|
||||
|
||||
namespace rocketmq {
|
||||
class TopAddressing {
|
||||
public:
|
||||
TopAddressing(string unitName);
|
||||
virtual ~TopAddressing();
|
||||
|
||||
public:
|
||||
virtual string fetchNSAddr(const string& NSDomain);
|
||||
|
||||
private:
|
||||
string clearNewLine(const string& str);
|
||||
void updateNameServerAddressList(const string& adds);
|
||||
int IsIPAddr(const char* sValue);
|
||||
|
||||
private:
|
||||
boost::mutex m_addrLock;
|
||||
list<string> m_addrs;
|
||||
string m_unitName;
|
||||
};
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
114
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/TopicConfig.cpp
vendored
Normal file
114
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/TopicConfig.cpp
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "TopicConfig.h"
|
||||
#include <stdlib.h>
|
||||
#include <sstream>
|
||||
#include "PermName.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
int TopicConfig::DefaultReadQueueNums = 16;
|
||||
int TopicConfig::DefaultWriteQueueNums = 16;
|
||||
string TopicConfig::SEPARATOR = " ";
|
||||
|
||||
TopicConfig::TopicConfig()
|
||||
: m_topicName(""),
|
||||
m_readQueueNums(DefaultReadQueueNums),
|
||||
m_writeQueueNums(DefaultWriteQueueNums),
|
||||
m_perm(PermName::PERM_READ | PermName::PERM_WRITE),
|
||||
m_topicFilterType(SINGLE_TAG) {}
|
||||
|
||||
TopicConfig::TopicConfig(const string& topicName)
|
||||
: m_topicName(topicName),
|
||||
m_readQueueNums(DefaultReadQueueNums),
|
||||
m_writeQueueNums(DefaultWriteQueueNums),
|
||||
m_perm(PermName::PERM_READ | PermName::PERM_WRITE),
|
||||
m_topicFilterType(SINGLE_TAG) {}
|
||||
|
||||
TopicConfig::TopicConfig(const string& topicName, int readQueueNums, int writeQueueNums, int perm)
|
||||
: m_topicName(topicName),
|
||||
m_readQueueNums(readQueueNums),
|
||||
m_writeQueueNums(writeQueueNums),
|
||||
m_perm(perm),
|
||||
m_topicFilterType(SINGLE_TAG) {}
|
||||
|
||||
TopicConfig::~TopicConfig() {}
|
||||
|
||||
string TopicConfig::encode() {
|
||||
stringstream ss;
|
||||
ss << m_topicName << SEPARATOR << m_readQueueNums << SEPARATOR << m_writeQueueNums << SEPARATOR << m_perm << SEPARATOR
|
||||
<< m_topicFilterType;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
bool TopicConfig::decode(const string& in) {
|
||||
stringstream ss(in);
|
||||
|
||||
ss >> m_topicName;
|
||||
ss >> m_readQueueNums;
|
||||
ss >> m_writeQueueNums;
|
||||
ss >> m_perm;
|
||||
|
||||
int type;
|
||||
ss >> type;
|
||||
m_topicFilterType = (TopicFilterType)type;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const string& TopicConfig::getTopicName() {
|
||||
return m_topicName;
|
||||
}
|
||||
|
||||
void TopicConfig::setTopicName(const string& topicName) {
|
||||
m_topicName = topicName;
|
||||
}
|
||||
|
||||
int TopicConfig::getReadQueueNums() {
|
||||
return m_readQueueNums;
|
||||
}
|
||||
|
||||
void TopicConfig::setReadQueueNums(int readQueueNums) {
|
||||
m_readQueueNums = readQueueNums;
|
||||
}
|
||||
|
||||
int TopicConfig::getWriteQueueNums() {
|
||||
return m_writeQueueNums;
|
||||
}
|
||||
|
||||
void TopicConfig::setWriteQueueNums(int writeQueueNums) {
|
||||
m_writeQueueNums = writeQueueNums;
|
||||
}
|
||||
|
||||
int TopicConfig::getPerm() {
|
||||
return m_perm;
|
||||
}
|
||||
|
||||
void TopicConfig::setPerm(int perm) {
|
||||
m_perm = perm;
|
||||
}
|
||||
|
||||
TopicFilterType TopicConfig::getTopicFilterType() {
|
||||
return m_topicFilterType;
|
||||
}
|
||||
|
||||
void TopicConfig::setTopicFilterType(TopicFilterType topicFilterType) {
|
||||
m_topicFilterType = topicFilterType;
|
||||
}
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
60
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/TopicConfig.h
vendored
Normal file
60
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/TopicConfig.h
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __TOPICCONFIG_H__
|
||||
#define __TOPICCONFIG_H__
|
||||
|
||||
#include <string>
|
||||
#include "TopicFilterType.h"
|
||||
#include "UtilAll.h"
|
||||
namespace rocketmq {
|
||||
//<!************************************************************************
|
||||
class TopicConfig {
|
||||
public:
|
||||
TopicConfig();
|
||||
TopicConfig(const string& topicName);
|
||||
TopicConfig(const string& topicName, int readQueueNums, int writeQueueNums, int perm);
|
||||
~TopicConfig();
|
||||
|
||||
string encode();
|
||||
bool decode(const string& in);
|
||||
const string& getTopicName();
|
||||
void setTopicName(const string& topicName);
|
||||
int getReadQueueNums();
|
||||
void setReadQueueNums(int readQueueNums);
|
||||
int getWriteQueueNums();
|
||||
void setWriteQueueNums(int writeQueueNums);
|
||||
int getPerm();
|
||||
void setPerm(int perm);
|
||||
TopicFilterType getTopicFilterType();
|
||||
void setTopicFilterType(TopicFilterType topicFilterType);
|
||||
|
||||
public:
|
||||
static int DefaultReadQueueNums;
|
||||
static int DefaultWriteQueueNums;
|
||||
|
||||
private:
|
||||
static string SEPARATOR;
|
||||
|
||||
string m_topicName;
|
||||
int m_readQueueNums;
|
||||
int m_writeQueueNums;
|
||||
int m_perm;
|
||||
TopicFilterType m_topicFilterType;
|
||||
};
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
34
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/TopicFilterType.h
vendored
Normal file
34
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/TopicFilterType.h
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __TOPICFILTERTYPE_H__
|
||||
#define __TOPICFILTERTYPE_H__
|
||||
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
enum TopicFilterType {
|
||||
/**
|
||||
* each msg could only have one tag
|
||||
*/
|
||||
SINGLE_TAG,
|
||||
/**
|
||||
* not support now
|
||||
*/
|
||||
MULTI_TAG
|
||||
};
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
386
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/UtilAll.cpp
vendored
Normal file
386
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/UtilAll.cpp
vendored
Normal file
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "UtilAll.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace rocketmq {
|
||||
//<!************************************************************************
|
||||
std::string UtilAll::s_localHostName;
|
||||
std::string UtilAll::s_localIpAddress;
|
||||
|
||||
bool UtilAll::startsWith_retry(const string& topic) {
|
||||
return topic.find(RETRY_GROUP_TOPIC_PREFIX) == 0;
|
||||
}
|
||||
|
||||
string UtilAll::getRetryTopic(const string& consumerGroup) {
|
||||
return RETRY_GROUP_TOPIC_PREFIX + consumerGroup;
|
||||
}
|
||||
|
||||
void UtilAll::Trim(string& str) {
|
||||
str.erase(0, str.find_first_not_of(' ')); // prefixing spaces
|
||||
str.erase(str.find_last_not_of(' ') + 1); // surfixing spaces
|
||||
}
|
||||
|
||||
bool UtilAll::isBlank(const string& str) {
|
||||
if (str.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
string::size_type left = str.find_first_not_of(WHITESPACE);
|
||||
|
||||
if (left == string::npos) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const int hex2int[256] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
-1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
|
||||
|
||||
uint64 UtilAll::hexstr2ull(const char* str) {
|
||||
uint64 num = 0;
|
||||
unsigned char* ch = (unsigned char*)str;
|
||||
while (*ch != '\0') {
|
||||
num = (num << 4) + hex2int[*ch];
|
||||
ch++;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
int64 UtilAll::str2ll(const char* str) {
|
||||
return boost::lexical_cast<int64>(str);
|
||||
}
|
||||
|
||||
string UtilAll::bytes2string(const char* bytes, int len) {
|
||||
if (bytes == NULL || len <= 0) {
|
||||
return string();
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
string buffer;
|
||||
for (int i = 0; i < len; i++) {
|
||||
char tmp[3];
|
||||
sprintf(tmp, "%02X", (unsigned char)bytes[i]);
|
||||
buffer.append(tmp);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
#else
|
||||
static const char hex_str[] = "0123456789ABCDEF";
|
||||
|
||||
char result[len * 2 + 1];
|
||||
|
||||
result[len * 2] = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
result[i * 2 + 0] = hex_str[(bytes[i] >> 4) & 0x0F];
|
||||
result[i * 2 + 1] = hex_str[(bytes[i]) & 0x0F];
|
||||
}
|
||||
|
||||
string buffer(result);
|
||||
return buffer;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool UtilAll::SplitURL(const string& serverURL, string& addr, short& nPort) {
|
||||
size_t pos = serverURL.find(':');
|
||||
if (pos == string::npos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
addr = serverURL.substr(0, pos);
|
||||
if (0 == addr.compare("localhost")) {
|
||||
addr = "127.0.0.1";
|
||||
}
|
||||
|
||||
pos++;
|
||||
string port = serverURL.substr(pos, serverURL.length() - pos);
|
||||
nPort = atoi(port.c_str());
|
||||
if (nPort == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int UtilAll::Split(vector<string>& ret_, const string& strIn, const char sep) {
|
||||
if (strIn.empty())
|
||||
return 0;
|
||||
|
||||
string tmp;
|
||||
string::size_type pos_begin = strIn.find_first_not_of(sep);
|
||||
string::size_type comma_pos = 0;
|
||||
|
||||
while (pos_begin != string::npos) {
|
||||
comma_pos = strIn.find(sep, pos_begin);
|
||||
if (comma_pos != string::npos) {
|
||||
tmp = strIn.substr(pos_begin, comma_pos - pos_begin);
|
||||
pos_begin = comma_pos + 1;
|
||||
} else {
|
||||
tmp = strIn.substr(pos_begin);
|
||||
pos_begin = comma_pos;
|
||||
}
|
||||
|
||||
if (!tmp.empty()) {
|
||||
ret_.push_back(tmp);
|
||||
tmp.clear();
|
||||
}
|
||||
}
|
||||
return ret_.size();
|
||||
}
|
||||
int UtilAll::Split(vector<string>& ret_, const string& strIn, const string& sep) {
|
||||
if (strIn.empty())
|
||||
return 0;
|
||||
|
||||
string tmp;
|
||||
string::size_type pos_begin = strIn.find_first_not_of(sep);
|
||||
string::size_type comma_pos = 0;
|
||||
|
||||
while (pos_begin != string::npos) {
|
||||
comma_pos = strIn.find(sep, pos_begin);
|
||||
if (comma_pos != string::npos) {
|
||||
tmp = strIn.substr(pos_begin, comma_pos - pos_begin);
|
||||
pos_begin = comma_pos + sep.length();
|
||||
} else {
|
||||
tmp = strIn.substr(pos_begin);
|
||||
pos_begin = comma_pos;
|
||||
}
|
||||
|
||||
if (!tmp.empty()) {
|
||||
ret_.push_back(tmp);
|
||||
tmp.clear();
|
||||
}
|
||||
}
|
||||
return ret_.size();
|
||||
}
|
||||
|
||||
bool UtilAll::StringToInt32(const std::string& str, int32_t& out) {
|
||||
out = 0;
|
||||
if (str.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char* end = NULL;
|
||||
errno = 0;
|
||||
long l = strtol(str.c_str(), &end, 10);
|
||||
/* Both checks are needed because INT_MAX == LONG_MAX is possible. */
|
||||
if (l > INT_MAX || (errno == ERANGE && l == LONG_MAX))
|
||||
return false;
|
||||
if (l < INT_MIN || (errno == ERANGE && l == LONG_MIN))
|
||||
return false;
|
||||
if (*end != '\0')
|
||||
return false;
|
||||
out = l;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UtilAll::StringToInt64(const std::string& str, int64_t& val) {
|
||||
char* endptr = NULL;
|
||||
errno = 0; /* To distinguish success/failure after call */
|
||||
val = strtoll(str.c_str(), &endptr, 10);
|
||||
|
||||
/* Check for various possible errors */
|
||||
if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0)) {
|
||||
return false;
|
||||
}
|
||||
/*no digit was found Or Further characters after number*/
|
||||
if (endptr == str.c_str()) {
|
||||
return false;
|
||||
}
|
||||
/*no digit was found Or Further characters after number*/
|
||||
if (*endptr != '\0') {
|
||||
return false;
|
||||
}
|
||||
/* If we got here, strtol() successfully parsed a number */
|
||||
return true;
|
||||
}
|
||||
|
||||
string UtilAll::getLocalHostName() {
|
||||
if (s_localHostName.empty()) {
|
||||
// boost::system::error_code error;
|
||||
// s_localHostName = boost::asio::ip::host_name(error);
|
||||
|
||||
char name[1024];
|
||||
boost::system::error_code ec;
|
||||
if (boost::asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0) {
|
||||
return std::string();
|
||||
}
|
||||
s_localHostName.append(name, strlen(name));
|
||||
}
|
||||
return s_localHostName;
|
||||
}
|
||||
|
||||
string UtilAll::getLocalAddress() {
|
||||
if (s_localIpAddress.empty()) {
|
||||
boost::asio::io_service io_service;
|
||||
boost::asio::ip::tcp::resolver resolver(io_service);
|
||||
boost::asio::ip::tcp::resolver::query query(getLocalHostName(), "");
|
||||
boost::system::error_code error;
|
||||
boost::asio::ip::tcp::resolver::iterator iter = resolver.resolve(query, error);
|
||||
if (error) {
|
||||
return "";
|
||||
}
|
||||
boost::asio::ip::tcp::resolver::iterator end; // End marker.
|
||||
boost::asio::ip::tcp::endpoint ep;
|
||||
while (iter != end) {
|
||||
ep = *iter++;
|
||||
}
|
||||
s_localIpAddress = ep.address().to_string();
|
||||
}
|
||||
return s_localIpAddress;
|
||||
}
|
||||
|
||||
string UtilAll::getHomeDirectory() {
|
||||
#ifndef WIN32
|
||||
char* homeEnv = getenv("HOME");
|
||||
string homeDir;
|
||||
if (homeEnv == NULL) {
|
||||
homeDir.append(getpwuid(getuid())->pw_dir);
|
||||
} else {
|
||||
homeDir.append(homeEnv);
|
||||
}
|
||||
#else
|
||||
string homeDir(getenv("USERPROFILE"));
|
||||
#endif
|
||||
return homeDir;
|
||||
}
|
||||
|
||||
string UtilAll::getProcessName() {
|
||||
#ifndef WIN32
|
||||
char buf[PATH_MAX + 1] = {0};
|
||||
int count = PATH_MAX + 1;
|
||||
char procpath[PATH_MAX + 1] = {0};
|
||||
sprintf(procpath, "/proc/%d/exe", getpid());
|
||||
|
||||
if (access(procpath, F_OK) == -1) {
|
||||
return "";
|
||||
}
|
||||
|
||||
int retval = readlink(procpath, buf, count - 1);
|
||||
if ((retval < 0 || retval >= count - 1)) {
|
||||
return "";
|
||||
}
|
||||
if (!strcmp(buf + retval - 10, " (deleted)"))
|
||||
buf[retval - 10] = '\0'; // remove last " (deleted)"
|
||||
else
|
||||
buf[retval] = '\0';
|
||||
|
||||
char* process_name = strrchr(buf, '/');
|
||||
if (process_name) {
|
||||
return std::string(process_name + 1);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
#else
|
||||
TCHAR szFileName[MAX_PATH + 1];
|
||||
GetModuleFileName(NULL, szFileName, MAX_PATH + 1);
|
||||
return std::string(szFileName);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t UtilAll::currentTimeMillis() {
|
||||
auto since_epoch =
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||
return static_cast<uint64_t>(since_epoch.count());
|
||||
}
|
||||
|
||||
uint64_t UtilAll::currentTimeSeconds() {
|
||||
auto since_epoch =
|
||||
std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||
return static_cast<uint64_t>(since_epoch.count());
|
||||
}
|
||||
|
||||
bool UtilAll::deflate(std::string& input, std::string& out, int level) {
|
||||
boost::iostreams::zlib_params zlibParams(level, boost::iostreams::zlib::deflated);
|
||||
boost::iostreams::filtering_ostream compressingStream;
|
||||
compressingStream.push(boost::iostreams::zlib_compressor(zlibParams));
|
||||
compressingStream.push(boost::iostreams::back_inserter(out));
|
||||
compressingStream << input;
|
||||
boost::iostreams::close(compressingStream);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UtilAll::inflate(std::string& input, std::string& out) {
|
||||
boost::iostreams::filtering_ostream decompressingStream;
|
||||
decompressingStream.push(boost::iostreams::zlib_decompressor());
|
||||
decompressingStream.push(boost::iostreams::back_inserter(out));
|
||||
decompressingStream << input;
|
||||
boost::iostreams::close(decompressingStream);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UtilAll::ReplaceFile(const std::string& from_path, const std::string& to_path) {
|
||||
#ifdef WIN32
|
||||
// Try a simple move first. It will only succeed when |to_path| doesn't
|
||||
// already exist.
|
||||
if (::MoveFile(from_path.c_str(), to_path.c_str()))
|
||||
return true;
|
||||
// Try the full-blown replace if the move fails, as ReplaceFile will only
|
||||
// succeed when |to_path| does exist. When writing to a network share, we may
|
||||
// not be able to change the ACLs. Ignore ACL errors then
|
||||
// (REPLACEFILE_IGNORE_MERGE_ERRORS).
|
||||
if (::ReplaceFile(to_path.c_str(), from_path.c_str(), NULL, REPLACEFILE_IGNORE_MERGE_ERRORS, NULL, NULL)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
if (rename(from_path.c_str(), to_path.c_str()) == 0)
|
||||
return true;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> UtilAll::ReadProperties(const std::string& path) {
|
||||
std::map<std::string, std::string> property_map;
|
||||
std::ifstream property_file;
|
||||
property_file.open(path);
|
||||
std::string line_buffer;
|
||||
|
||||
if (property_file.is_open()) {
|
||||
while (!property_file.eof()) {
|
||||
std::getline(property_file, line_buffer);
|
||||
std::size_t pos{0};
|
||||
pos = line_buffer.find('#');
|
||||
if (pos != string::npos) {
|
||||
line_buffer = line_buffer.substr(0, pos);
|
||||
}
|
||||
if (line_buffer.empty()) {
|
||||
continue;
|
||||
}
|
||||
pos = line_buffer.find('=');
|
||||
if (pos != string::npos) {
|
||||
std::string key = boost::trim_copy(line_buffer.substr(0, pos));
|
||||
std::string value = boost::trim_copy(line_buffer.substr(pos + 1));
|
||||
property_map[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return property_map;
|
||||
}
|
||||
|
||||
} // namespace rocketmq
|
||||
151
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/UtilAll.h
vendored
Normal file
151
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/UtilAll.h
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __UTILALL_H__
|
||||
#define __UTILALL_H__
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef WIN32
|
||||
#include <pwd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/iostreams/copy.hpp>
|
||||
#include <boost/iostreams/device/back_inserter.hpp>
|
||||
#include <boost/iostreams/filter/gzip.hpp>
|
||||
#include <boost/iostreams/filter/zlib.hpp>
|
||||
#include <boost/iostreams/filtering_stream.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/locale/conversion.hpp>
|
||||
#include <boost/locale/encoding.hpp>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include "RocketMQClient.h"
|
||||
|
||||
using namespace std;
|
||||
namespace rocketmq {
|
||||
//<!************************************************************************
|
||||
const string null = "";
|
||||
const string WHITESPACE = " \t\r\n";
|
||||
const string SUB_ALL = "*";
|
||||
const string DEFAULT_TOPIC = "TBW102";
|
||||
const string BENCHMARK_TOPIC = "BenchmarkTest";
|
||||
const string DEFAULT_PRODUCER_GROUP = "DEFAULT_PRODUCER";
|
||||
const string DEFAULT_CONSUMER_GROUP = "DEFAULT_CONSUMER";
|
||||
const string TOOLS_CONSUMER_GROUP = "TOOLS_CONSUMER";
|
||||
const string CLIENT_INNER_PRODUCER_GROUP = "CLIENT_INNER_PRODUCER";
|
||||
const string SELF_TEST_TOPIC = "SELF_TEST_TOPIC";
|
||||
const string RETRY_GROUP_TOPIC_PREFIX = "%RETRY%";
|
||||
const string DLQ_GROUP_TOPIC_PREFIX = "%DLQ%";
|
||||
const string ROCKETMQ_HOME_ENV = "ROCKETMQ_HOME";
|
||||
const string ROCKETMQ_HOME_PROPERTY = "rocketmq.home.dir";
|
||||
const string MESSAGE_COMPRESS_LEVEL = "rocketmq.message.compressLevel";
|
||||
const string DEFAULT_SSL_PROPERTY_FILE = "/etc/rocketmq/tls.properties";
|
||||
const string DEFAULT_CLIENT_KEY_PASSWD = null;
|
||||
const string DEFAULT_CLIENT_KEY_FILE = "/etc/rocketmq/client.key";
|
||||
const string DEFAULT_CLIENT_CERT_FILE = "/etc/rocketmq/client.pem";
|
||||
const string DEFAULT_CA_CERT_FILE = "/etc/rocketmq/ca.pem";
|
||||
const string WS_ADDR =
|
||||
"please set nameserver domain by setDomainName, there is no default "
|
||||
"nameserver domain";
|
||||
const int POLL_NAMESERVER_INTEVAL = 1000 * 30;
|
||||
const int HEARTBEAT_BROKER_INTERVAL = 1000 * 30;
|
||||
const int PERSIST_CONSUMER_OFFSET_INTERVAL = 1000 * 5;
|
||||
const int LINE_SEPARATOR = 1; // rocketmq::UtilAll::charToString((char) 1);
|
||||
const int WORD_SEPARATOR = 2; // rocketmq::UtilAll::charToString((char) 2);
|
||||
const int HTTP_TIMEOUT = 3000; // 3S
|
||||
const int HTTP_CONFLICT = 409;
|
||||
const int HTTP_OK = 200;
|
||||
const int HTTP_NOTFOUND = 404;
|
||||
const int CONNETERROR = -1;
|
||||
const int MASTER_ID = 0;
|
||||
|
||||
template <typename Type>
|
||||
inline void deleteAndZero(Type& pointer) {
|
||||
delete pointer;
|
||||
pointer = NULL;
|
||||
}
|
||||
#define EMPTY_STR_PTR(ptr) (ptr == NULL || ptr[0] == '\0')
|
||||
#ifdef WIN32
|
||||
#define SIZET_FMT "%lu"
|
||||
#else
|
||||
#define SIZET_FMT "%zu"
|
||||
#endif
|
||||
|
||||
//<!************************************************************************
|
||||
class UtilAll {
|
||||
public:
|
||||
static bool startsWith_retry(const string& topic);
|
||||
static string getRetryTopic(const string& consumerGroup);
|
||||
|
||||
static void Trim(string& str);
|
||||
static bool isBlank(const string& str);
|
||||
static uint64 hexstr2ull(const char* str);
|
||||
static int64 str2ll(const char* str);
|
||||
static string bytes2string(const char* bytes, int len);
|
||||
|
||||
template <typename T>
|
||||
static string to_string(const T& n) {
|
||||
std::ostringstream stm;
|
||||
stm << n;
|
||||
return stm.str();
|
||||
}
|
||||
|
||||
static bool to_bool(std::string const& s) { return atoi(s.c_str()); }
|
||||
|
||||
static bool SplitURL(const string& serverURL, string& addr, short& nPort);
|
||||
static int Split(vector<string>& ret_, const string& strIn, const char sep);
|
||||
static int Split(vector<string>& ret_, const string& strIn, const string& sep);
|
||||
|
||||
static bool StringToInt32(const std::string& str, int32_t& out);
|
||||
static bool StringToInt64(const std::string& str, int64_t& val);
|
||||
|
||||
static string getLocalHostName();
|
||||
static string getLocalAddress();
|
||||
static string getHomeDirectory();
|
||||
|
||||
static string getProcessName();
|
||||
|
||||
static uint64_t currentTimeMillis();
|
||||
static uint64_t currentTimeSeconds();
|
||||
|
||||
static bool deflate(std::string& input, std::string& out, int level);
|
||||
static bool inflate(std::string& input, std::string& out);
|
||||
// Renames file |from_path| to |to_path|. Both paths must be on the same
|
||||
// volume, or the function will fail. Destination file will be created
|
||||
// if it doesn't exist. Prefer this function over Move when dealing with
|
||||
// temporary files. On Windows it preserves attributes of the target file.
|
||||
// Returns true on success.
|
||||
// Returns false on failure..
|
||||
static bool ReplaceFile(const std::string& from_path, const std::string& to_path);
|
||||
|
||||
static std::map<std::string, std::string> ReadProperties(const std::string& path);
|
||||
|
||||
private:
|
||||
static std::string s_localHostName;
|
||||
static std::string s_localIpAddress;
|
||||
};
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
104
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/Validators.cpp
vendored
Normal file
104
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/Validators.cpp
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "Validators.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
namespace rocketmq {
|
||||
|
||||
const string Validators::validPatternStr = "^[a-zA-Z0-9_-]+$";
|
||||
const int Validators::CHARACTER_MAX_LENGTH = 255;
|
||||
//<!***************************************************************************
|
||||
bool Validators::regularExpressionMatcher(const string& origin, const string& patternStr) {
|
||||
if (UtilAll::isBlank(origin)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (UtilAll::isBlank(patternStr)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Pattern pattern = Pattern.compile(patternStr);
|
||||
// Matcher matcher = pattern.matcher(origin);
|
||||
|
||||
// return matcher.matches();
|
||||
return true;
|
||||
}
|
||||
|
||||
string Validators::getGroupWithRegularExpression(const string& origin, const string& patternStr) {
|
||||
/*Pattern pattern = Pattern.compile(patternStr);
|
||||
Matcher matcher = pattern.matcher(origin);
|
||||
while (matcher.find()) {
|
||||
return matcher.group(0);
|
||||
}*/
|
||||
return "";
|
||||
}
|
||||
|
||||
void Validators::checkTopic(const string& topic) {
|
||||
if (UtilAll::isBlank(topic)) {
|
||||
THROW_MQEXCEPTION(MQClientException, "the specified topic is blank", -1);
|
||||
}
|
||||
|
||||
if ((int)topic.length() > CHARACTER_MAX_LENGTH) {
|
||||
THROW_MQEXCEPTION(MQClientException, "the specified topic is longer than topic max length 255.", -1);
|
||||
}
|
||||
|
||||
if (topic == DEFAULT_TOPIC) {
|
||||
THROW_MQEXCEPTION(MQClientException, "the topic[" + topic + "] is conflict with default topic.", -1);
|
||||
}
|
||||
|
||||
if (!regularExpressionMatcher(topic, validPatternStr)) {
|
||||
string str;
|
||||
str = "the specified topic[" + topic + "] contains illegal characters, allowing only" + validPatternStr;
|
||||
|
||||
THROW_MQEXCEPTION(MQClientException, str.c_str(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
void Validators::checkGroup(const string& group) {
|
||||
if (UtilAll::isBlank(group)) {
|
||||
THROW_MQEXCEPTION(MQClientException, "the specified group is blank", -1);
|
||||
}
|
||||
|
||||
if (!regularExpressionMatcher(group, validPatternStr)) {
|
||||
string str;
|
||||
str = "the specified group[" + group + "] contains illegal characters, allowing only" + validPatternStr;
|
||||
|
||||
THROW_MQEXCEPTION(MQClientException, str.c_str(), -1);
|
||||
}
|
||||
if ((int)group.length() > CHARACTER_MAX_LENGTH) {
|
||||
THROW_MQEXCEPTION(MQClientException, "the specified group is longer than group max length 255.", -1);
|
||||
}
|
||||
}
|
||||
|
||||
void Validators::checkMessage(const MQMessage& msg, int maxMessageSize) {
|
||||
checkTopic(msg.getTopic());
|
||||
|
||||
string body = msg.getBody();
|
||||
//<!body;
|
||||
if (body.empty()) {
|
||||
THROW_MQEXCEPTION(MQClientException, "the message body is empty", -1);
|
||||
}
|
||||
|
||||
if ((int)body.length() > maxMessageSize) {
|
||||
char info[256];
|
||||
sprintf(info, "the message body size over max value, MAX: %d", maxMessageSize);
|
||||
THROW_MQEXCEPTION(MQClientException, info, -1);
|
||||
}
|
||||
}
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
41
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/Validators.h
vendored
Normal file
41
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/Validators.h
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __VALIDATORST_H__
|
||||
#define __VALIDATORST_H__
|
||||
|
||||
#include <string>
|
||||
#include "MQClientException.h"
|
||||
#include "MQMessage.h"
|
||||
#include "UtilAll.h"
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
class Validators {
|
||||
public:
|
||||
static bool regularExpressionMatcher(const string& origin, const string& patternStr);
|
||||
static string getGroupWithRegularExpression(const string& origin, const string& patternStr);
|
||||
static void checkTopic(const string& topic);
|
||||
static void checkGroup(const string& group);
|
||||
static void checkMessage(const MQMessage& msg, int maxMessageSize);
|
||||
|
||||
public:
|
||||
static const string validPatternStr;
|
||||
static const int CHARACTER_MAX_LENGTH;
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
54
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/VirtualEnvUtil.cpp
vendored
Normal file
54
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/VirtualEnvUtil.cpp
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "VirtualEnvUtil.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "UtilAll.h"
|
||||
|
||||
namespace rocketmq {
|
||||
const char* VirtualEnvUtil::VIRTUAL_APPGROUP_PREFIX = "%%PROJECT_%s%%";
|
||||
|
||||
//<!***************************************************************************
|
||||
string VirtualEnvUtil::buildWithProjectGroup(const string& origin, const string& projectGroup) {
|
||||
if (!UtilAll::isBlank(projectGroup)) {
|
||||
char prefix[1024];
|
||||
sprintf(prefix, VIRTUAL_APPGROUP_PREFIX, projectGroup.c_str());
|
||||
|
||||
if (origin.find(prefix) == string::npos) {
|
||||
return origin + prefix;
|
||||
} else {
|
||||
return origin;
|
||||
}
|
||||
} else {
|
||||
return origin;
|
||||
}
|
||||
}
|
||||
|
||||
string VirtualEnvUtil::clearProjectGroup(const string& origin, const string& projectGroup) {
|
||||
char prefix[1024];
|
||||
sprintf(prefix, VIRTUAL_APPGROUP_PREFIX, projectGroup.c_str());
|
||||
auto pos = origin.find(prefix);
|
||||
|
||||
if (!UtilAll::isBlank(prefix) && pos != string::npos) {
|
||||
return origin.substr(0, pos);
|
||||
} else {
|
||||
return origin;
|
||||
}
|
||||
}
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
34
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/VirtualEnvUtil.h
vendored
Normal file
34
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/VirtualEnvUtil.h
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __VIRTUALENVUTIL_H__
|
||||
#define __VIRTUALENVUTIL_H__
|
||||
|
||||
#include <string>
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
class VirtualEnvUtil {
|
||||
public:
|
||||
static std::string buildWithProjectGroup(const std::string& origin, const std::string& projectGroup);
|
||||
static std::string clearProjectGroup(const std::string& origin, const std::string& projectGroup);
|
||||
|
||||
public:
|
||||
static const char* VIRTUAL_APPGROUP_PREFIX;
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
96
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/big_endian.cpp
vendored
Normal file
96
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/big_endian.cpp
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "big_endian.h"
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
namespace rocketmq {
|
||||
|
||||
BigEndianReader::BigEndianReader(const char* buf, size_t len) : ptr_(buf), end_(ptr_ + len) {}
|
||||
|
||||
bool BigEndianReader::Skip(size_t len) {
|
||||
if (ptr_ + len > end_)
|
||||
return false;
|
||||
ptr_ += len;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BigEndianReader::ReadBytes(void* out, size_t len) {
|
||||
if (ptr_ + len > end_)
|
||||
return false;
|
||||
memcpy(out, ptr_, len);
|
||||
ptr_ += len;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool BigEndianReader::Read(T* value) {
|
||||
if (ptr_ + sizeof(T) > end_)
|
||||
return false;
|
||||
ReadBigEndian<T>(ptr_, value);
|
||||
ptr_ += sizeof(T);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BigEndianReader::ReadU8(uint8_t* value) {
|
||||
return Read(value);
|
||||
}
|
||||
|
||||
bool BigEndianReader::ReadU16(uint16_t* value) {
|
||||
return Read(value);
|
||||
}
|
||||
|
||||
bool BigEndianReader::ReadU32(uint32_t* value) {
|
||||
return Read(value);
|
||||
}
|
||||
|
||||
bool BigEndianReader::ReadU64(uint64_t* value) {
|
||||
return Read(value);
|
||||
}
|
||||
|
||||
BigEndianWriter::BigEndianWriter(char* buf, size_t len) : ptr_(buf), end_(ptr_ + len) {}
|
||||
|
||||
bool BigEndianWriter::Skip(size_t len) {
|
||||
if (ptr_ + len > end_)
|
||||
return false;
|
||||
ptr_ += len;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BigEndianWriter::WriteBytes(const void* buf, size_t len) {
|
||||
if (ptr_ + len > end_)
|
||||
return false;
|
||||
memcpy(ptr_, buf, len);
|
||||
ptr_ += len;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool BigEndianWriter::Write(T value) {
|
||||
if (ptr_ + sizeof(T) > end_)
|
||||
return false;
|
||||
WriteBigEndian<T>(ptr_, value);
|
||||
ptr_ += sizeof(T);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BigEndianWriter::WriteU8(uint8_t value) {
|
||||
return Write(value);
|
||||
}
|
||||
|
||||
bool BigEndianWriter::WriteU16(uint16_t value) {
|
||||
return Write(value);
|
||||
}
|
||||
|
||||
bool BigEndianWriter::WriteU32(uint32_t value) {
|
||||
return Write(value);
|
||||
}
|
||||
|
||||
bool BigEndianWriter::WriteU64(uint64_t value) {
|
||||
return Write(value);
|
||||
}
|
||||
|
||||
} // namespace rocketmq
|
||||
102
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/big_endian.h
vendored
Normal file
102
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/big_endian.h
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef BASE_BIG_ENDIAN_H_
|
||||
#define BASE_BIG_ENDIAN_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace rocketmq {
|
||||
|
||||
// Read an integer (signed or unsigned) from |buf| in Big Endian order.
|
||||
// Note: this loop is unrolled with -O1 and above.
|
||||
// NOTE(szym): glibc dns-canon.c use ntohs(*(uint16_t*)ptr) which is
|
||||
// potentially unaligned.
|
||||
// This would cause SIGBUS on ARMv5 or earlier and ARMv6-M.
|
||||
template <typename T>
|
||||
inline void ReadBigEndian(const char buf[], T* out) {
|
||||
*out = buf[0];
|
||||
for (size_t i = 1; i < sizeof(T); ++i) {
|
||||
*out <<= 8;
|
||||
// Must cast to uint8_t to avoid clobbering by sign extension.
|
||||
*out |= static_cast<uint8_t>(buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Write an integer (signed or unsigned) |val| to |buf| in Big Endian order.
|
||||
// Note: this loop is unrolled with -O1 and above.
|
||||
template <typename T>
|
||||
inline void WriteBigEndian(char buf[], T val) {
|
||||
for (size_t i = 0; i < sizeof(T); ++i) {
|
||||
buf[sizeof(T) - i - 1] = static_cast<char>(val & 0xFF);
|
||||
val >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
// Specializations to make clang happy about the (dead code) shifts above.
|
||||
template <>
|
||||
inline void ReadBigEndian<uint8_t>(const char buf[], uint8_t* out) {
|
||||
*out = buf[0];
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void WriteBigEndian<uint8_t>(char buf[], uint8_t val) {
|
||||
buf[0] = static_cast<char>(val);
|
||||
}
|
||||
|
||||
// Allows reading integers in network order (big endian) while iterating over
|
||||
// an underlying buffer. All the reading functions advance the internal pointer.
|
||||
class BigEndianReader {
|
||||
public:
|
||||
BigEndianReader(const char* buf, size_t len);
|
||||
|
||||
const char* ptr() const { return ptr_; }
|
||||
int remaining() const { return end_ - ptr_; }
|
||||
|
||||
bool Skip(size_t len);
|
||||
bool ReadBytes(void* out, size_t len);
|
||||
bool ReadU8(uint8_t* value);
|
||||
bool ReadU16(uint16_t* value);
|
||||
bool ReadU32(uint32_t* value);
|
||||
bool ReadU64(uint64_t* value);
|
||||
|
||||
private:
|
||||
// Hidden to promote type safety.
|
||||
template <typename T>
|
||||
bool Read(T* v);
|
||||
|
||||
const char* ptr_;
|
||||
const char* end_;
|
||||
};
|
||||
|
||||
// Allows writing integers in network order (big endian) while iterating over
|
||||
// an underlying buffer. All the writing functions advance the internal pointer.
|
||||
class BigEndianWriter {
|
||||
public:
|
||||
BigEndianWriter(char* buf, size_t len);
|
||||
|
||||
char* ptr() const { return ptr_; }
|
||||
int remaining() const { return end_ - ptr_; }
|
||||
|
||||
bool Skip(size_t len);
|
||||
bool WriteBytes(const void* buf, size_t len);
|
||||
bool WriteU8(uint8_t value);
|
||||
bool WriteU16(uint16_t value);
|
||||
bool WriteU32(uint32_t value);
|
||||
bool WriteU64(uint64_t value);
|
||||
|
||||
private:
|
||||
// Hidden to promote type safety.
|
||||
template <typename T>
|
||||
bool Write(T v);
|
||||
|
||||
char* ptr_;
|
||||
char* end_;
|
||||
};
|
||||
|
||||
} // namespace rocketmq
|
||||
|
||||
#endif // BASE_BIG_ENDIAN_H_
|
||||
207
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/dataBlock.cpp
vendored
Normal file
207
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/dataBlock.cpp
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "dataBlock.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace rocketmq {
|
||||
|
||||
MemoryBlock::MemoryBlock() : size(0), data(NULL) {}
|
||||
|
||||
MemoryBlock::MemoryBlock(const int initialSize, const bool initialiseToZero) : size(0), data(NULL) {
|
||||
if (initialSize > 0) {
|
||||
size = initialSize;
|
||||
data = static_cast<char*>(initialiseToZero ? std::calloc(initialSize, sizeof(char))
|
||||
: std::malloc(initialSize * sizeof(char)));
|
||||
}
|
||||
}
|
||||
|
||||
MemoryBlock::MemoryBlock(const void* const dataToInitialiseFrom, const size_t sizeInBytes)
|
||||
: size(sizeInBytes), data(NULL) {
|
||||
if (size > 0) {
|
||||
data = static_cast<char*>(std::malloc(size * sizeof(char)));
|
||||
|
||||
if (dataToInitialiseFrom != NULL)
|
||||
memcpy(data, dataToInitialiseFrom, size);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryBlock::MemoryBlock(const MemoryBlock& other) : size(other.size), data(NULL) {
|
||||
if (size > 0) {
|
||||
data = static_cast<char*>(std::malloc(size * sizeof(char)));
|
||||
memcpy(data, other.data, size);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryBlock::MemoryBlock(MemoryBlock&& other) : size(other.size), data(other.data) {
|
||||
other.size = 0;
|
||||
other.data = NULL;
|
||||
}
|
||||
|
||||
MemoryBlock::~MemoryBlock() {
|
||||
std::free(data);
|
||||
}
|
||||
|
||||
MemoryBlock& MemoryBlock::operator=(const MemoryBlock& other) {
|
||||
if (this != &other) {
|
||||
setSize(other.size, false);
|
||||
memcpy(data, other.data, size);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
MemoryBlock& MemoryBlock::operator=(MemoryBlock&& other) {
|
||||
if (this != &other) {
|
||||
std::free(data);
|
||||
|
||||
size = other.size;
|
||||
data = other.data;
|
||||
|
||||
other.size = 0;
|
||||
other.data = NULL;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool MemoryBlock::operator==(const MemoryBlock& other) const {
|
||||
return matches(other.data, other.size);
|
||||
}
|
||||
|
||||
bool MemoryBlock::operator!=(const MemoryBlock& other) const {
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
bool MemoryBlock::matches(const void* dataToCompare, int dataSize) const {
|
||||
return size == dataSize && memcmp(data, dataToCompare, size) == 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// this will resize the block to this size
|
||||
void MemoryBlock::setSize(const int newSize, const bool initialiseToZero) {
|
||||
if (size != newSize) {
|
||||
if (newSize <= 0) {
|
||||
reset();
|
||||
} else {
|
||||
if (data != NULL) {
|
||||
data = static_cast<char*>(data == NULL ? std::malloc(newSize * sizeof(char))
|
||||
: std::realloc(data, newSize * sizeof(char)));
|
||||
|
||||
if (initialiseToZero && (newSize > size))
|
||||
memset(data + size, 0, newSize - size);
|
||||
} else {
|
||||
std::free(data);
|
||||
data = static_cast<char*>(initialiseToZero ? std::calloc(newSize, sizeof(char))
|
||||
: std::malloc(newSize * sizeof(char)));
|
||||
}
|
||||
|
||||
size = newSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBlock::reset() {
|
||||
std::free(data);
|
||||
data = NULL;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
void MemoryBlock::ensureSize(const int minimumSize, const bool initialiseToZero) {
|
||||
if (size < minimumSize)
|
||||
setSize(minimumSize, initialiseToZero);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void MemoryBlock::fillWith(const int value) {
|
||||
memset(data, (int)value, size);
|
||||
}
|
||||
|
||||
void MemoryBlock::append(const void* const srcData, const int numBytes) {
|
||||
if (numBytes > 0) {
|
||||
const int oldSize = size;
|
||||
setSize(size + numBytes);
|
||||
memcpy(data + oldSize, srcData, numBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBlock::replaceWith(const void* const srcData, const int numBytes) {
|
||||
if (numBytes > 0) {
|
||||
setSize(numBytes);
|
||||
memcpy(data, srcData, numBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBlock::insert(const void* const srcData, const int numBytes, int insertPosition) {
|
||||
if (numBytes > 0) {
|
||||
insertPosition = std::min(insertPosition, size);
|
||||
const int trailingDataSize = size - insertPosition;
|
||||
setSize(size + numBytes, false);
|
||||
|
||||
if (trailingDataSize > 0)
|
||||
memmove(data + insertPosition + numBytes, data + insertPosition, trailingDataSize);
|
||||
|
||||
memcpy(data + insertPosition, srcData, numBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBlock::removeSection(const int startByte, const int numBytesToRemove) {
|
||||
if (startByte + numBytesToRemove >= size) {
|
||||
setSize(startByte);
|
||||
} else if (numBytesToRemove > 0) {
|
||||
memmove(data + startByte, data + startByte + numBytesToRemove, size - (startByte + numBytesToRemove));
|
||||
|
||||
setSize(size - numBytesToRemove);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBlock::copyFrom(const void* const src, int offset, int num) {
|
||||
const char* d = static_cast<const char*>(src);
|
||||
|
||||
if (offset < 0) {
|
||||
d -= offset;
|
||||
num += (size_t)-offset;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
if ((size_t)offset + num > (unsigned int)size)
|
||||
num = size - (size_t)offset;
|
||||
|
||||
if (num > 0)
|
||||
memcpy(data + offset, d, num);
|
||||
}
|
||||
|
||||
void MemoryBlock::copyTo(void* const dst, int offset, int num) const {
|
||||
char* d = static_cast<char*>(dst);
|
||||
|
||||
if (offset < 0) {
|
||||
memset(d, 0, (size_t)-offset);
|
||||
d -= offset;
|
||||
num -= (size_t)-offset;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
if ((size_t)offset + num > (unsigned int)size) {
|
||||
const int newNum = (size_t)size - (size_t)offset;
|
||||
memset(d + newNum, 0, num - newNum);
|
||||
num = newNum;
|
||||
}
|
||||
|
||||
if (num > 0)
|
||||
memcpy(d, data + offset, num);
|
||||
}
|
||||
} // namespace rocketmq
|
||||
208
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/dataBlock.h
vendored
Normal file
208
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/dataBlock.h
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __DATABLOCK_H__
|
||||
#define __DATABLOCK_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "RocketMQClient.h"
|
||||
|
||||
namespace rocketmq {
|
||||
|
||||
class ROCKETMQCLIENT_API MemoryBlock {
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Create an uninitialised block with 0 size. */
|
||||
MemoryBlock();
|
||||
|
||||
/** Creates a memory block with a given initial size.
|
||||
|
||||
@param initialSize the size of block to create
|
||||
@param initialiseToZero whether to clear the memory or just leave it
|
||||
uninitialised
|
||||
*/
|
||||
MemoryBlock(const int initialSize, bool initialiseToZero = false);
|
||||
|
||||
/** Creates a memory block using a copy of a block of data.
|
||||
|
||||
@param dataToInitialiseFrom some data to copy into this block
|
||||
@param sizeInBytes how much space to use
|
||||
*/
|
||||
MemoryBlock(const void* dataToInitialiseFrom, size_t sizeInBytes);
|
||||
|
||||
/** Creates a copy of another memory block. */
|
||||
MemoryBlock(const MemoryBlock&);
|
||||
|
||||
MemoryBlock(MemoryBlock&&);
|
||||
|
||||
/** Destructor. */
|
||||
~MemoryBlock();
|
||||
|
||||
/** Copies another memory block onto this one.
|
||||
This block will be resized and copied to exactly match the other one.
|
||||
*/
|
||||
MemoryBlock& operator=(const MemoryBlock&);
|
||||
|
||||
MemoryBlock& operator=(MemoryBlock&&);
|
||||
|
||||
//==============================================================================
|
||||
/** Compares two memory blocks.
|
||||
@returns true only if the two blocks are the same size and have identical
|
||||
contents.
|
||||
*/
|
||||
bool operator==(const MemoryBlock& other) const;
|
||||
|
||||
/** Compares two memory blocks.
|
||||
@returns true if the two blocks are different sizes or have different
|
||||
contents.
|
||||
*/
|
||||
bool operator!=(const MemoryBlock& other) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a void pointer to the data.
|
||||
|
||||
Note that the pointer returned will probably become invalid when the
|
||||
block is resized.
|
||||
*/
|
||||
char* getData() const { return data; }
|
||||
|
||||
/** Returns a byte from the memory block.
|
||||
This returns a reference, so you can also use it to set a byte.
|
||||
*/
|
||||
template <typename Type>
|
||||
char& operator[](const Type offset) const {
|
||||
return data[offset];
|
||||
}
|
||||
|
||||
/** Returns true if the data in this MemoryBlock matches the raw bytes
|
||||
* passed-in. */
|
||||
bool matches(const void* data, int dataSize) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the block's current allocated size, in bytes. */
|
||||
int getSize() const { return size; }
|
||||
|
||||
/** Resizes the memory block.
|
||||
|
||||
Any data that is present in both the old and new sizes will be retained.
|
||||
When enlarging the block, the new space that is allocated at the end can
|
||||
either be
|
||||
cleared, or left uninitialised.
|
||||
|
||||
@param newSize the new desired size for the block
|
||||
@param initialiseNewSpaceToZero if the block gets enlarged, this
|
||||
determines
|
||||
whether to clear the new section or
|
||||
just leave it
|
||||
uninitialised
|
||||
@see ensureSize
|
||||
*/
|
||||
void setSize(const int newSize, bool initialiseNewSpaceToZero = false);
|
||||
|
||||
/** Increases the block's size only if it's smaller than a given size.
|
||||
|
||||
@param minimumSize if the block is already bigger than
|
||||
this size, no action
|
||||
will be taken; otherwise it will be
|
||||
increased to this size
|
||||
@param initialiseNewSpaceToZero if the block gets enlarged, this
|
||||
determines
|
||||
whether to clear the new section or
|
||||
just leave it
|
||||
uninitialised
|
||||
@see setSize
|
||||
*/
|
||||
void ensureSize(const int minimumSize, bool initialiseNewSpaceToZero = false);
|
||||
|
||||
/** Frees all the blocks data, setting its size to 0. */
|
||||
void reset();
|
||||
|
||||
//==============================================================================
|
||||
/** Fills the entire memory block with a repeated byte value.
|
||||
This is handy for clearing a block of memory to zero.
|
||||
*/
|
||||
void fillWith(int valueToUse);
|
||||
|
||||
/** Adds another block of data to the end of this one.
|
||||
The data pointer must not be null. This block's size will be increased
|
||||
accordingly.
|
||||
*/
|
||||
void append(const void* data, int numBytes);
|
||||
|
||||
/** Resizes this block to the given size and fills its contents from the
|
||||
supplied buffer.
|
||||
The data pointer must not be null.
|
||||
*/
|
||||
void replaceWith(const void* data, int numBytes);
|
||||
|
||||
/** Inserts some data into the block.
|
||||
The dataToInsert pointer must not be null. This block's size will be
|
||||
increased accordingly.
|
||||
If the insert position lies outside the valid range of the block, it will
|
||||
be clipped to
|
||||
within the range before being used.
|
||||
*/
|
||||
void insert(const void* dataToInsert, int numBytesToInsert, int insertPosition);
|
||||
|
||||
/** Chops out a section of the block.
|
||||
|
||||
This will remove a section of the memory block and close the gap around
|
||||
it,
|
||||
shifting any subsequent data downwards and reducing the size of the block.
|
||||
|
||||
If the range specified goes beyond the size of the block, it will be
|
||||
clipped.
|
||||
*/
|
||||
void removeSection(int startByte, int numBytesToRemove);
|
||||
|
||||
//==============================================================================
|
||||
/** Copies data into this MemoryBlock from a memory address.
|
||||
|
||||
@param srcData the memory location of the data to copy into
|
||||
this block
|
||||
@param destinationOffset the offset in this block at which the data
|
||||
being copied should begin
|
||||
@param numBytes how much to copy in (if this goes beyond the
|
||||
size of the memory block,
|
||||
it will be clipped so not to do anything
|
||||
nasty)
|
||||
*/
|
||||
void copyFrom(const void* srcData, int destinationOffset, int numBytes);
|
||||
|
||||
/** Copies data from this MemoryBlock to a memory address.
|
||||
|
||||
@param destData the memory location to write to
|
||||
@param sourceOffset the offset within this block from which the copied
|
||||
data will be read
|
||||
@param numBytes how much to copy (if this extends beyond the
|
||||
limits of the memory block,
|
||||
zeros will be used for that portion of the data)
|
||||
*/
|
||||
void copyTo(void* destData, int sourceOffset, int numBytes) const;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
int size;
|
||||
char* data;
|
||||
};
|
||||
} // namespace rocketmq
|
||||
|
||||
#endif
|
||||
33
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/noncopyable.h
vendored
Normal file
33
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/noncopyable.h
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __NONCOPYABLE_H__
|
||||
#define __NONCOPYABLE_H__
|
||||
|
||||
namespace rocketmq {
|
||||
|
||||
class noncopyable {
|
||||
protected:
|
||||
noncopyable() = default;
|
||||
~noncopyable() = default;
|
||||
|
||||
noncopyable(const noncopyable&) = delete;
|
||||
noncopyable& operator=(const noncopyable&) = delete;
|
||||
};
|
||||
|
||||
} // namespace rocketmq
|
||||
|
||||
#endif //__NONCOPYABLE_H__
|
||||
151
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/sync_http_client.cpp
vendored
Normal file
151
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/sync_http_client.cpp
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/lambda/bind.hpp>
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
#include <iostream>
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "Logging.h"
|
||||
#include "url.h"
|
||||
|
||||
using boost::asio::deadline_timer;
|
||||
using boost::asio::ip::tcp;
|
||||
using boost::lambda::var;
|
||||
|
||||
namespace {
|
||||
void check_deadline(deadline_timer* deadline, tcp::socket* socket, const boost::system::error_code& ec) {
|
||||
// Check whether the deadline has passed. We compare the deadline against
|
||||
// the current time since a new asynchronous operation may have moved the
|
||||
// deadline before this actor had a chance to run.
|
||||
if (deadline->expires_at() <= deadline_timer::traits_type::now()) {
|
||||
// The deadline has passed. The socket is closed so that any outstanding
|
||||
// asynchronous operations are cancelled. This allows the blocked
|
||||
// connect(), read_line() or write_line() functions to return.
|
||||
boost::system::error_code ignored_ec;
|
||||
socket->close(ignored_ec);
|
||||
|
||||
// There is no longer an active deadline. The expiry is set to positive
|
||||
// infinity so that the actor takes no action until a new deadline is set.
|
||||
deadline->expires_at(boost::posix_time::pos_infin);
|
||||
}
|
||||
|
||||
// Put the actor back to sleep.
|
||||
deadline->async_wait(boost::bind(&check_deadline, deadline, socket, boost::asio::placeholders::error));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace rocketmq {
|
||||
bool SyncfetchNsAddr(const Url& url_s, std::string& body) {
|
||||
bool ret = true;
|
||||
try {
|
||||
boost::asio::io_service io_service;
|
||||
// Get a list of endpoints corresponding to the server name.
|
||||
tcp::resolver resolver(io_service);
|
||||
tcp::resolver::query query(url_s.host_, url_s.port_);
|
||||
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
|
||||
boost::system::error_code ec = boost::asio::error::would_block;
|
||||
deadline_timer deadline(io_service);
|
||||
// TODO hardcode
|
||||
boost::posix_time::seconds timeout(3);
|
||||
deadline.expires_from_now(timeout);
|
||||
// Try each endpoint until we successfully establish a connection.
|
||||
tcp::socket socket(io_service);
|
||||
boost::system::error_code deadline_ec;
|
||||
check_deadline(&deadline, &socket, deadline_ec);
|
||||
|
||||
boost::asio::async_connect(socket, endpoint_iterator, boost::lambda::var(ec) = boost::lambda::_1);
|
||||
|
||||
do {
|
||||
io_service.run_one();
|
||||
} while (ec == boost::asio::error::would_block);
|
||||
|
||||
if (ec || !socket.is_open()) {
|
||||
LOG_ERROR("socket connect failure, connect timeout or connect failure");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Form the request. We specify the "Connection: close" header so that the
|
||||
// server will close the socket after transmitting the response. This will
|
||||
// allow us to treat all data up until the EOF as the content.
|
||||
boost::asio::streambuf request;
|
||||
std::ostream request_stream(&request);
|
||||
request_stream << "GET " << url_s.path_ << " HTTP/1.0\r\n";
|
||||
request_stream << "Host: " << url_s.host_ << "\r\n";
|
||||
request_stream << "Accept: */*\r\n";
|
||||
request_stream << "Connection: close\r\n\r\n";
|
||||
|
||||
// Send the request.
|
||||
boost::asio::write(socket, request);
|
||||
|
||||
// Read the response status line. The response streambuf will automatically
|
||||
// grow to accommodate the entire line. The growth may be limited by passing
|
||||
// a maximum size to the streambuf constructor.
|
||||
boost::asio::streambuf response;
|
||||
boost::asio::read_until(socket, response, "\r\n");
|
||||
|
||||
// Check that response is OK.
|
||||
std::istream response_stream(&response);
|
||||
std::string http_version;
|
||||
response_stream >> http_version;
|
||||
unsigned int status_code;
|
||||
response_stream >> status_code;
|
||||
std::string status_message;
|
||||
std::getline(response_stream, status_message);
|
||||
if (!response_stream || http_version.substr(0, 5) != "HTTP/") {
|
||||
LOG_INFO("Invalid response %s\n", status_message.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (status_code != 200) {
|
||||
LOG_INFO("Response returned with status code %d ", status_code);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the response headers, which are terminated by a blank line.
|
||||
boost::asio::read_until(socket, response, "\r\n\r\n");
|
||||
|
||||
// Process the response headers.
|
||||
std::string header;
|
||||
while (std::getline(response_stream, header) && header != "\r")
|
||||
;
|
||||
|
||||
// Write whatever content we already have to output.
|
||||
if (response.size() > 0) {
|
||||
boost::asio::streambuf::const_buffers_type cbt = response.data();
|
||||
body.clear();
|
||||
body.insert(body.begin(), boost::asio::buffers_begin(cbt), boost::asio::buffers_end(cbt));
|
||||
}
|
||||
|
||||
// Read until EOF, writing data to output as we go.
|
||||
boost::system::error_code error;
|
||||
while (boost::asio::read(socket, response, boost::asio::transfer_at_least(1), error))
|
||||
std::cout << &response;
|
||||
if (error != boost::asio::error::eof)
|
||||
throw boost::system::system_error(error);
|
||||
|
||||
} catch (std::exception& e) {
|
||||
LOG_ERROR("Exception: %s", e.what());
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace rocketmq
|
||||
29
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/sync_http_client.h
vendored
Normal file
29
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/sync_http_client.h
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef ROCKETMQ_CLIENT4CPP__SYNC_HTTP_CLIENT_H_
|
||||
#define ROCKETMQ_CLIENT4CPP__SYNC_HTTP_CLIENT_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace rocketmq {
|
||||
class Url;
|
||||
|
||||
extern bool SyncfetchNsAddr(const Url& url_s, std::string& body);
|
||||
|
||||
} // namespace rocketmq
|
||||
|
||||
#endif // ROCKETMQ_CLIENT4CPP__SYNC_HTTP_CLIENT_H_
|
||||
65
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/url.cpp
vendored
Normal file
65
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/url.cpp
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "url.h"
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
namespace rocketmq {
|
||||
|
||||
Url::Url(const std::string& url_s) {
|
||||
parse(url_s);
|
||||
}
|
||||
|
||||
void Url::parse(const std::string& url_s) {
|
||||
const std::string prot_end("://");
|
||||
auto prot_i = std::search(url_s.begin(), url_s.end(), prot_end.begin(), prot_end.end());
|
||||
protocol_.reserve(std::distance(url_s.begin(), prot_i));
|
||||
std::transform(url_s.begin(), prot_i, std::back_inserter(protocol_),
|
||||
std::ptr_fun<int, int>(tolower)); // protocol is icase
|
||||
|
||||
if (prot_i == url_s.end())
|
||||
return;
|
||||
|
||||
std::advance(prot_i, prot_end.length());
|
||||
|
||||
auto path_i = find(prot_i, url_s.end(), ':');
|
||||
std::string::const_iterator path_end_i;
|
||||
if (path_i == url_s.end()) {
|
||||
// not include port, use default port
|
||||
port_ = "80";
|
||||
path_i = std::find(prot_i, url_s.end(), '/');
|
||||
path_end_i = path_i;
|
||||
} else {
|
||||
auto port_i = find(path_i + 1, url_s.end(), '/');
|
||||
port_.insert(port_.begin(), path_i + 1, port_i);
|
||||
path_end_i = path_i + port_.length() + 1;
|
||||
}
|
||||
|
||||
host_.reserve(distance(prot_i, path_i));
|
||||
std::transform(prot_i, path_i, std::back_inserter(host_), std::ptr_fun<int, int>(tolower)); // host is icase}
|
||||
|
||||
auto query_i = find(path_end_i, url_s.end(), '?');
|
||||
path_.assign(path_end_i, query_i);
|
||||
if (query_i != url_s.end())
|
||||
++query_i;
|
||||
query_.assign(query_i, url_s.end());
|
||||
}
|
||||
|
||||
} // namespace rocketmq
|
||||
38
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/url.h
vendored
Normal file
38
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/common/url.h
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef ROCKETMQ_CLIENT4CPP_URL_HH_
|
||||
#define ROCKETMQ_CLIENT4CPP_URL_HH_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace rocketmq {
|
||||
class Url {
|
||||
public:
|
||||
Url(const std::string& url_s); // omitted copy, ==, accessors, ...
|
||||
|
||||
private:
|
||||
void parse(const std::string& url_s);
|
||||
|
||||
public:
|
||||
std::string protocol_;
|
||||
std::string host_;
|
||||
std::string port_;
|
||||
std::string path_;
|
||||
std::string query_;
|
||||
};
|
||||
} // namespace rocketmq
|
||||
#endif // ROCKETMQ_CLIENT4CPP_URL_HH_
|
||||
96
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/AllocateMQStrategy.h
vendored
Normal file
96
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/AllocateMQStrategy.h
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __ALLOCATEMESSAGEQUEUESTRATEGY_H__
|
||||
#define __ALLOCATEMESSAGEQUEUESTRATEGY_H__
|
||||
|
||||
#include "Logging.h"
|
||||
#include "MQClientException.h"
|
||||
#include "MQMessageQueue.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
class AllocateMQStrategy {
|
||||
public:
|
||||
virtual ~AllocateMQStrategy() {}
|
||||
virtual void allocate(const std::string& currentCID,
|
||||
std::vector<MQMessageQueue>& mqAll,
|
||||
std::vector<std::string>& cidAll,
|
||||
std::vector<MQMessageQueue>& outReuslt) = 0;
|
||||
};
|
||||
|
||||
//<!************************************************************************
|
||||
class AllocateMQAveragely : public AllocateMQStrategy {
|
||||
public:
|
||||
virtual ~AllocateMQAveragely() {}
|
||||
virtual void allocate(const std::string& currentCID,
|
||||
std::vector<MQMessageQueue>& mqAll,
|
||||
std::vector<std::string>& cidAll,
|
||||
std::vector<MQMessageQueue>& outReuslt) {
|
||||
outReuslt.clear();
|
||||
if (currentCID.empty()) {
|
||||
THROW_MQEXCEPTION(MQClientException, "currentCID is empty", -1);
|
||||
}
|
||||
|
||||
if (mqAll.empty()) {
|
||||
THROW_MQEXCEPTION(MQClientException, "mqAll is empty", -1);
|
||||
}
|
||||
|
||||
if (cidAll.empty()) {
|
||||
THROW_MQEXCEPTION(MQClientException, "cidAll is empty", -1);
|
||||
}
|
||||
|
||||
int index = -1;
|
||||
int cidAllSize = cidAll.size();
|
||||
for (int i = 0; i < cidAllSize; i++) {
|
||||
if (cidAll[i] == currentCID) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
LOG_ERROR("could not find clientId from Broker");
|
||||
return;
|
||||
}
|
||||
|
||||
int mqAllSize = mqAll.size();
|
||||
int mod = mqAllSize % cidAllSize;
|
||||
int averageSize =
|
||||
mqAllSize <= cidAllSize ? 1 : (mod > 0 && index < mod ? mqAllSize / cidAllSize + 1 : mqAllSize / cidAllSize);
|
||||
int startIndex = (mod > 0 && index < mod) ? index * averageSize : index * averageSize + mod;
|
||||
int range = (std::min)(averageSize, mqAllSize - startIndex);
|
||||
LOG_INFO(
|
||||
"range is:%d, index is:%d, mqAllSize is:%d, averageSize is:%d, "
|
||||
"startIndex is:%d",
|
||||
range, index, mqAllSize, averageSize, startIndex);
|
||||
//<!out;
|
||||
if (range >= 0) // example: range is:-1, index is:1, mqAllSize is:1,
|
||||
// averageSize is:1, startIndex is:2
|
||||
{
|
||||
for (int i = 0; i < range; i++) {
|
||||
if ((startIndex + i) >= 0) {
|
||||
outReuslt.push_back(mqAll.at((startIndex + i) % mqAllSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
@@ -0,0 +1,319 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#if !defined(WIN32) && !defined(__APPLE__)
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
|
||||
#include "ConsumeMsgService.h"
|
||||
#include "DefaultMQPushConsumer.h"
|
||||
#include "Logging.h"
|
||||
#include "MessageAccessor.h"
|
||||
#include "UtilAll.h"
|
||||
|
||||
namespace rocketmq {
|
||||
|
||||
//<!************************************************************************
|
||||
ConsumeMessageConcurrentlyService::ConsumeMessageConcurrentlyService(MQConsumer* consumer,
|
||||
int threadCount,
|
||||
MQMessageListener* msgListener)
|
||||
: m_pConsumer(consumer), m_pMessageListener(msgListener), m_ioServiceWork(m_ioService) {
|
||||
#if !defined(WIN32) && !defined(__APPLE__)
|
||||
string taskName = UtilAll::getProcessName();
|
||||
prctl(PR_SET_NAME, "ConsumeTP", 0, 0, 0);
|
||||
#endif
|
||||
for (int i = 0; i != threadCount; ++i) {
|
||||
m_threadpool.create_thread(boost::bind(&boost::asio::io_service::run, &m_ioService));
|
||||
}
|
||||
#if !defined(WIN32) && !defined(__APPLE__)
|
||||
prctl(PR_SET_NAME, taskName.c_str(), 0, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
ConsumeMessageConcurrentlyService::~ConsumeMessageConcurrentlyService(void) {
|
||||
m_pConsumer = NULL;
|
||||
m_pMessageListener = NULL;
|
||||
}
|
||||
|
||||
void ConsumeMessageConcurrentlyService::start() {}
|
||||
|
||||
void ConsumeMessageConcurrentlyService::shutdown() {
|
||||
stopThreadPool();
|
||||
}
|
||||
|
||||
void ConsumeMessageConcurrentlyService::stopThreadPool() {
|
||||
m_ioService.stop();
|
||||
m_threadpool.join_all();
|
||||
}
|
||||
|
||||
MessageListenerType ConsumeMessageConcurrentlyService::getConsumeMsgSerivceListenerType() {
|
||||
return m_pMessageListener->getMessageListenerType();
|
||||
}
|
||||
|
||||
void ConsumeMessageConcurrentlyService::submitConsumeRequest(boost::weak_ptr<PullRequest> pullRequest,
|
||||
vector<MQMessageExt>& msgs) {
|
||||
boost::shared_ptr<PullRequest> request = pullRequest.lock();
|
||||
if (!request) {
|
||||
LOG_WARN("Pull request has been released");
|
||||
return;
|
||||
}
|
||||
if (request->isDropped()) {
|
||||
LOG_INFO("Pull request for %s is dropped, which will be released in next re-balance.",
|
||||
request->m_messageQueue.toString().c_str());
|
||||
return;
|
||||
}
|
||||
if (!request->isDropped() && !m_ioService.stopped()) {
|
||||
m_ioService.post(boost::bind(&ConsumeMessageConcurrentlyService::ConsumeRequest, this, request, msgs));
|
||||
} else {
|
||||
LOG_INFO("IOService stopped or Pull request for %s is dropped, will not post ConsumeRequest.",
|
||||
request->m_messageQueue.toString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void ConsumeMessageConcurrentlyService::submitConsumeRequestLater(boost::weak_ptr<PullRequest> pullRequest,
|
||||
vector<MQMessageExt>& msgs,
|
||||
int millis) {
|
||||
if (msgs.empty()) {
|
||||
return;
|
||||
}
|
||||
boost::shared_ptr<PullRequest> request = pullRequest.lock();
|
||||
if (!request) {
|
||||
LOG_WARN("Pull request has been released");
|
||||
return;
|
||||
}
|
||||
if (request->isDropped()) {
|
||||
LOG_INFO("Pull request is set as dropped with mq:%s, need release in next rebalance.",
|
||||
(request->m_messageQueue).toString().c_str());
|
||||
return;
|
||||
}
|
||||
if (!request->isDropped() && !m_ioService.stopped()) {
|
||||
boost::asio::deadline_timer* t =
|
||||
new boost::asio::deadline_timer(m_ioService, boost::posix_time::milliseconds(millis));
|
||||
t->async_wait(
|
||||
boost::bind(&(ConsumeMessageConcurrentlyService::static_submitConsumeRequest), this, t, request, msgs));
|
||||
LOG_INFO("Submit Message to Consumer [%s] Later and Sleep [%d]ms.", (request->m_messageQueue).toString().c_str(),
|
||||
millis);
|
||||
} else {
|
||||
LOG_INFO("IOService stopped or Pull request for %s is dropped, will not post delay ConsumeRequest.",
|
||||
request->m_messageQueue.toString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void ConsumeMessageConcurrentlyService::static_submitConsumeRequest(void* context,
|
||||
boost::asio::deadline_timer* t,
|
||||
boost::weak_ptr<PullRequest> pullRequest,
|
||||
vector<MQMessageExt>& msgs) {
|
||||
boost::shared_ptr<PullRequest> request = pullRequest.lock();
|
||||
if (!request) {
|
||||
LOG_WARN("Pull request has been released");
|
||||
return;
|
||||
}
|
||||
ConsumeMessageConcurrentlyService* pService = (ConsumeMessageConcurrentlyService*)context;
|
||||
if (pService) {
|
||||
pService->triggersubmitConsumeRequestLater(t, request, msgs);
|
||||
}
|
||||
}
|
||||
|
||||
void ConsumeMessageConcurrentlyService::triggersubmitConsumeRequestLater(boost::asio::deadline_timer* t,
|
||||
boost::weak_ptr<PullRequest> pullRequest,
|
||||
vector<MQMessageExt>& msgs) {
|
||||
boost::shared_ptr<PullRequest> request = pullRequest.lock();
|
||||
if (!request) {
|
||||
LOG_WARN("Pull request has been released");
|
||||
return;
|
||||
}
|
||||
submitConsumeRequest(request, msgs);
|
||||
deleteAndZero(t);
|
||||
}
|
||||
|
||||
void ConsumeMessageConcurrentlyService::ConsumeRequest(boost::weak_ptr<PullRequest> pullRequest,
|
||||
vector<MQMessageExt>& msgs) {
|
||||
boost::shared_ptr<PullRequest> request = pullRequest.lock();
|
||||
if (!request) {
|
||||
LOG_WARN("Pull request has been released");
|
||||
return;
|
||||
}
|
||||
if (request->isDropped()) {
|
||||
LOG_WARN("the pull request for %s Had been dropped before", request->m_messageQueue.toString().c_str());
|
||||
request->clearAllMsgs(); // add clear operation to avoid bad state when
|
||||
// dropped pullRequest returns normal
|
||||
return;
|
||||
}
|
||||
if (msgs.empty()) {
|
||||
LOG_WARN("the msg of pull result is NULL,its mq:%s", (request->m_messageQueue).toString().c_str());
|
||||
return;
|
||||
}
|
||||
ConsumeMessageContext consumeMessageContext;
|
||||
DefaultMQPushConsumerImpl* pConsumer = dynamic_cast<DefaultMQPushConsumerImpl*>(m_pConsumer);
|
||||
if (pConsumer) {
|
||||
if (pConsumer->getMessageTrace() && pConsumer->hasConsumeMessageHook()) {
|
||||
consumeMessageContext.setDefaultMQPushConsumer(pConsumer);
|
||||
consumeMessageContext.setConsumerGroup(pConsumer->getGroupName());
|
||||
consumeMessageContext.setMessageQueue(request->m_messageQueue);
|
||||
consumeMessageContext.setMsgList(msgs);
|
||||
consumeMessageContext.setSuccess(false);
|
||||
consumeMessageContext.setNameSpace(pConsumer->getNameSpace());
|
||||
pConsumer->executeConsumeMessageHookBefore(&consumeMessageContext);
|
||||
}
|
||||
}
|
||||
ConsumeStatus status = CONSUME_SUCCESS;
|
||||
if (m_pMessageListener != NULL) {
|
||||
resetRetryTopic(msgs);
|
||||
request->setLastConsumeTimestamp(UtilAll::currentTimeMillis());
|
||||
LOG_DEBUG("=====Receive Messages,Topic[%s], MsgId[%s],Body[%s],RetryTimes[%d]", msgs[0].getTopic().c_str(),
|
||||
msgs[0].getMsgId().c_str(), msgs[0].getBody().c_str(), msgs[0].getReconsumeTimes());
|
||||
if (m_pConsumer->isUseNameSpaceMode()) {
|
||||
MessageAccessor::withoutNameSpace(msgs, m_pConsumer->getNameSpace());
|
||||
}
|
||||
|
||||
if (pConsumer->getMessageTrace() && pConsumer->hasConsumeMessageHook()) {
|
||||
// For open trace message, consume message one by one.
|
||||
for (size_t i = 0; i < msgs.size(); ++i) {
|
||||
LOG_DEBUG("=====Trace Receive Messages,Topic[%s], MsgId[%s],Body[%s],RetryTimes[%d]",
|
||||
msgs[i].getTopic().c_str(), msgs[i].getMsgId().c_str(), msgs[i].getBody().c_str(),
|
||||
msgs[i].getReconsumeTimes());
|
||||
std::vector<MQMessageExt> msgInner;
|
||||
msgInner.push_back(msgs[i]);
|
||||
if (status != CONSUME_SUCCESS) {
|
||||
// all the Messages behind should be set to failed.
|
||||
status = RECONSUME_LATER;
|
||||
consumeMessageContext.setMsgIndex(i);
|
||||
consumeMessageContext.setStatus("RECONSUME_LATER");
|
||||
consumeMessageContext.setSuccess(false);
|
||||
pConsumer->executeConsumeMessageHookAfter(&consumeMessageContext);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
status = m_pMessageListener->consumeMessage(msgInner);
|
||||
} catch (...) {
|
||||
status = RECONSUME_LATER;
|
||||
LOG_ERROR("Consumer's code is buggy. Un-caught exception raised");
|
||||
}
|
||||
consumeMessageContext.setMsgIndex(i); // indicate message position,not support batch consumer
|
||||
if (status == CONSUME_SUCCESS) {
|
||||
consumeMessageContext.setStatus("CONSUME_SUCCESS");
|
||||
consumeMessageContext.setSuccess(true);
|
||||
} else {
|
||||
status = RECONSUME_LATER;
|
||||
consumeMessageContext.setStatus("RECONSUME_LATER");
|
||||
consumeMessageContext.setSuccess(false);
|
||||
}
|
||||
pConsumer->executeConsumeMessageHookAfter(&consumeMessageContext);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
status = m_pMessageListener->consumeMessage(msgs);
|
||||
} catch (...) {
|
||||
status = RECONSUME_LATER;
|
||||
LOG_ERROR("Consumer's code is buggy. Un-caught exception raised");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ackIndex = -1;
|
||||
switch (status) {
|
||||
case CONSUME_SUCCESS:
|
||||
ackIndex = msgs.size();
|
||||
break;
|
||||
case RECONSUME_LATER:
|
||||
ackIndex = -1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
std::vector<MQMessageExt> localRetryMsgs;
|
||||
switch (m_pConsumer->getMessageModel()) {
|
||||
case BROADCASTING: {
|
||||
// Note: broadcasting reconsume should do by application, as it has big
|
||||
// affect to broker cluster
|
||||
if (ackIndex != (int)msgs.size())
|
||||
LOG_WARN("BROADCASTING, the message consume failed, drop it:%s", (request->m_messageQueue).toString().c_str());
|
||||
break;
|
||||
}
|
||||
case CLUSTERING: {
|
||||
// send back msg to broker;
|
||||
for (size_t i = ackIndex + 1; i < msgs.size(); i++) {
|
||||
LOG_DEBUG("consume fail, MQ is:%s, its msgId is:%s, index is:" SIZET_FMT ", reconsume times is:%d",
|
||||
(request->m_messageQueue).toString().c_str(), msgs[i].getMsgId().c_str(), i,
|
||||
msgs[i].getReconsumeTimes());
|
||||
if (m_pConsumer->getConsumeType() == CONSUME_PASSIVELY) {
|
||||
string brokerName = request->m_messageQueue.getBrokerName();
|
||||
if (m_pConsumer->isUseNameSpaceMode()) {
|
||||
MessageAccessor::withNameSpace(msgs[i], m_pConsumer->getNameSpace());
|
||||
}
|
||||
if (!m_pConsumer->sendMessageBack(msgs[i], 0, brokerName)) {
|
||||
LOG_WARN("Send message back fail, MQ is:%s, its msgId is:%s, index is:%d, re-consume times is:%d",
|
||||
(request->m_messageQueue).toString().c_str(), msgs[i].getMsgId().c_str(), i,
|
||||
msgs[i].getReconsumeTimes());
|
||||
msgs[i].setReconsumeTimes(msgs[i].getReconsumeTimes() + 1);
|
||||
localRetryMsgs.push_back(msgs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!localRetryMsgs.empty()) {
|
||||
LOG_ERROR("Client side re-consume launched due to both message consuming and SDK send-back retry failure");
|
||||
for (std::vector<MQMessageExt>::iterator itOrigin = msgs.begin(); itOrigin != msgs.end();) {
|
||||
bool remove = false;
|
||||
for (std::vector<MQMessageExt>::iterator itRetry = localRetryMsgs.begin(); itRetry != localRetryMsgs.end();
|
||||
itRetry++) {
|
||||
if (itRetry->getQueueOffset() == itOrigin->getQueueOffset()) {
|
||||
remove = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (remove) {
|
||||
itOrigin = msgs.erase(itOrigin);
|
||||
} else {
|
||||
itOrigin++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// update offset
|
||||
int64 offset = request->removeMessage(msgs);
|
||||
if (offset >= 0) {
|
||||
m_pConsumer->updateConsumeOffset(request->m_messageQueue, offset);
|
||||
} else {
|
||||
LOG_WARN("Note: Get local offset for mq:%s failed, may be it is updated before. skip..",
|
||||
(request->m_messageQueue).toString().c_str());
|
||||
}
|
||||
if (!localRetryMsgs.empty()) {
|
||||
// submitConsumeRequest(request, localTryMsgs);
|
||||
LOG_INFO("Send [%d ]messages back to mq:%s failed, call reconsume again after 1s.", localRetryMsgs.size(),
|
||||
(request->m_messageQueue).toString().c_str());
|
||||
submitConsumeRequestLater(request, localRetryMsgs, 1000);
|
||||
}
|
||||
} // namespace rocketmq
|
||||
|
||||
void ConsumeMessageConcurrentlyService::resetRetryTopic(vector<MQMessageExt>& msgs) {
|
||||
string groupTopic = UtilAll::getRetryTopic(m_pConsumer->getGroupName());
|
||||
for (size_t i = 0; i < msgs.size(); i++) {
|
||||
MQMessageExt& msg = msgs[i];
|
||||
string retryTopic = msg.getProperty(MQMessage::PROPERTY_RETRY_TOPIC);
|
||||
if (!retryTopic.empty() && groupTopic.compare(msg.getTopic()) == 0) {
|
||||
msg.setTopic(retryTopic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
114
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/ConsumeMessageHookImpl.cpp
vendored
Normal file
114
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/ConsumeMessageHookImpl.cpp
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ConsumeMessageHookImpl.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "ConsumeMessageContext.h"
|
||||
#include "DefaultMQPushConsumerImpl.h"
|
||||
#include "Logging.h"
|
||||
#include "MQClientException.h"
|
||||
#include "NameSpaceUtil.h"
|
||||
#include "TraceContant.h"
|
||||
#include "TraceContext.h"
|
||||
#include "TraceTransferBean.h"
|
||||
#include "TraceUtil.h"
|
||||
#include "UtilAll.h"
|
||||
namespace rocketmq {
|
||||
|
||||
class TraceMessageConsumeCallback : public SendCallback {
|
||||
virtual void onSuccess(SendResult& sendResult) {
|
||||
LOG_DEBUG("TraceMessageConsumeCallback, MsgId:[%s],OffsetMsgId[%s]", sendResult.getMsgId().c_str(),
|
||||
sendResult.getOffsetMsgId().c_str());
|
||||
}
|
||||
virtual void onException(MQException& e) {}
|
||||
};
|
||||
static TraceMessageConsumeCallback* consumeTraceCallback = new TraceMessageConsumeCallback();
|
||||
std::string ConsumeMessageHookImpl::getHookName() {
|
||||
return "RocketMQConsumeMessageHookImpl";
|
||||
}
|
||||
|
||||
void ConsumeMessageHookImpl::executeHookBefore(ConsumeMessageContext* context) {
|
||||
if (context == NULL || context->getMsgList().empty()) {
|
||||
return;
|
||||
}
|
||||
TraceContext* traceContext = new TraceContext();
|
||||
context->setTraceContext(traceContext);
|
||||
traceContext->setTraceType(SubBefore);
|
||||
traceContext->setGroupName(NameSpaceUtil::withoutNameSpace(context->getConsumerGroup(), context->getNameSpace()));
|
||||
std::vector<TraceBean> beans;
|
||||
|
||||
std::vector<MQMessageExt> msgs = context->getMsgList();
|
||||
std::vector<MQMessageExt>::iterator it = msgs.begin();
|
||||
for (; it != msgs.end(); ++it) {
|
||||
TraceBean bean;
|
||||
bean.setTopic((*it).getTopic());
|
||||
bean.setMsgId((*it).getMsgId());
|
||||
bean.setTags((*it).getTags());
|
||||
bean.setKeys((*it).getKeys());
|
||||
bean.setStoreHost((*it).getStoreHostString());
|
||||
bean.setStoreTime((*it).getStoreTimestamp());
|
||||
bean.setBodyLength((*it).getStoreSize());
|
||||
bean.setRetryTimes((*it).getReconsumeTimes());
|
||||
std::string regionId = (*it).getProperty(MQMessage::PROPERTY_MSG_REGION);
|
||||
if (regionId.empty()) {
|
||||
regionId = TraceContant::DEFAULT_REDION;
|
||||
}
|
||||
traceContext->setRegionId(regionId);
|
||||
traceContext->setTraceBean(bean);
|
||||
}
|
||||
traceContext->setTimeStamp(UtilAll::currentTimeMillis());
|
||||
|
||||
std::string topic = TraceContant::TRACE_TOPIC + traceContext->getRegionId();
|
||||
|
||||
TraceTransferBean ben = TraceUtil::CovertTraceContextToTransferBean(traceContext);
|
||||
MQMessage message(topic, ben.getTransData());
|
||||
message.setKeys(ben.getTransKey());
|
||||
|
||||
// send trace message async.
|
||||
context->getDefaultMQPushConsumer()->submitSendTraceRequest(message, consumeTraceCallback);
|
||||
return;
|
||||
}
|
||||
|
||||
void ConsumeMessageHookImpl::executeHookAfter(ConsumeMessageContext* context) {
|
||||
if (context == NULL || context->getMsgList().empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<TraceContext> subBeforeContext = context->getTraceContext();
|
||||
TraceContext subAfterContext;
|
||||
subAfterContext.setTraceType(SubAfter);
|
||||
subAfterContext.setRegionId(subBeforeContext->getRegionId());
|
||||
subAfterContext.setGroupName(subBeforeContext->getGroupName());
|
||||
subAfterContext.setRequestId(subBeforeContext->getRequestId());
|
||||
subAfterContext.setStatus(context->getSuccess());
|
||||
int costTime = static_cast<int>(UtilAll::currentTimeMillis() - subBeforeContext->getTimeStamp());
|
||||
subAfterContext.setCostTime(costTime);
|
||||
subAfterContext.setTraceBeanIndex(context->getMsgIndex());
|
||||
TraceBean bean = subBeforeContext->getTraceBeans()[subAfterContext.getTraceBeanIndex()];
|
||||
subAfterContext.setTraceBean(bean);
|
||||
|
||||
std::string topic = TraceContant::TRACE_TOPIC + subAfterContext.getRegionId();
|
||||
TraceTransferBean ben = TraceUtil::CovertTraceContextToTransferBean(&subAfterContext);
|
||||
MQMessage message(topic, ben.getTransData());
|
||||
message.setKeys(ben.getTransKey());
|
||||
|
||||
// send trace message async.
|
||||
context->getDefaultMQPushConsumer()->submitSendTraceRequest(message, consumeTraceCallback);
|
||||
return;
|
||||
}
|
||||
} // namespace rocketmq
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __ROCKETMQ_CONSUME_MESSAGE_RPC_HOOK_IMPL_H__
|
||||
#define __ROCKETMQ_CONSUME_MESSAGE_RPC_HOOK_IMPL_H__
|
||||
|
||||
#include <string>
|
||||
#include "ConsumeMessageContext.h"
|
||||
#include "ConsumeMessageHook.h"
|
||||
namespace rocketmq {
|
||||
class ConsumeMessageHookImpl : public ConsumeMessageHook {
|
||||
public:
|
||||
virtual ~ConsumeMessageHookImpl() {}
|
||||
virtual std::string getHookName();
|
||||
virtual void executeHookBefore(ConsumeMessageContext* context);
|
||||
virtual void executeHookAfter(ConsumeMessageContext* context);
|
||||
};
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#if !defined(WIN32) && !defined(__APPLE__)
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
|
||||
#include <MessageAccessor.h>
|
||||
#include "ConsumeMsgService.h"
|
||||
#include "DefaultMQPushConsumer.h"
|
||||
#include "Logging.h"
|
||||
#include "Rebalance.h"
|
||||
#include "UtilAll.h"
|
||||
|
||||
namespace rocketmq {
|
||||
|
||||
//<!***************************************************************************
|
||||
ConsumeMessageOrderlyService::ConsumeMessageOrderlyService(MQConsumer* consumer,
|
||||
int threadCount,
|
||||
MQMessageListener* msgListener)
|
||||
: m_pConsumer(consumer),
|
||||
m_shutdownInprogress(false),
|
||||
m_pMessageListener(msgListener),
|
||||
m_MaxTimeConsumeContinuously(60 * 1000),
|
||||
m_ioServiceWork(m_ioService),
|
||||
m_async_service_thread(NULL) {
|
||||
#if !defined(WIN32) && !defined(__APPLE__)
|
||||
string taskName = UtilAll::getProcessName();
|
||||
prctl(PR_SET_NAME, "oderlyConsumeTP", 0, 0, 0);
|
||||
#endif
|
||||
for (int i = 0; i != threadCount; ++i) {
|
||||
m_threadpool.create_thread(boost::bind(&boost::asio::io_service::run, &m_ioService));
|
||||
}
|
||||
#if !defined(WIN32) && !defined(__APPLE__)
|
||||
prctl(PR_SET_NAME, taskName.c_str(), 0, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ConsumeMessageOrderlyService::boost_asio_work() {
|
||||
LOG_INFO("ConsumeMessageOrderlyService::boost asio async service runing");
|
||||
boost::asio::io_service::work work(m_async_ioService); // avoid async io
|
||||
// service stops after
|
||||
// first timer timeout
|
||||
// callback
|
||||
boost::system::error_code ec;
|
||||
boost::asio::deadline_timer t(m_async_ioService, boost::posix_time::milliseconds(PullRequest::RebalanceLockInterval));
|
||||
t.async_wait(boost::bind(&ConsumeMessageOrderlyService::lockMQPeriodically, this, ec, &t));
|
||||
|
||||
m_async_ioService.run();
|
||||
}
|
||||
|
||||
ConsumeMessageOrderlyService::~ConsumeMessageOrderlyService(void) {
|
||||
m_pConsumer = NULL;
|
||||
m_pMessageListener = NULL;
|
||||
}
|
||||
|
||||
void ConsumeMessageOrderlyService::start() {
|
||||
m_async_service_thread.reset(new boost::thread(boost::bind(&ConsumeMessageOrderlyService::boost_asio_work, this)));
|
||||
}
|
||||
|
||||
void ConsumeMessageOrderlyService::shutdown() {
|
||||
stopThreadPool();
|
||||
unlockAllMQ();
|
||||
}
|
||||
|
||||
void ConsumeMessageOrderlyService::lockMQPeriodically(boost::system::error_code& ec, boost::asio::deadline_timer* t) {
|
||||
m_pConsumer->getRebalance()->lockAll();
|
||||
|
||||
boost::system::error_code e;
|
||||
t->expires_at(t->expires_at() + boost::posix_time::milliseconds(PullRequest::RebalanceLockInterval), e);
|
||||
t->async_wait(boost::bind(&ConsumeMessageOrderlyService::lockMQPeriodically, this, ec, t));
|
||||
}
|
||||
|
||||
void ConsumeMessageOrderlyService::unlockAllMQ() {
|
||||
m_pConsumer->getRebalance()->unlockAll(false);
|
||||
}
|
||||
|
||||
bool ConsumeMessageOrderlyService::lockOneMQ(const MQMessageQueue& mq) {
|
||||
return m_pConsumer->getRebalance()->lock(mq);
|
||||
}
|
||||
|
||||
void ConsumeMessageOrderlyService::stopThreadPool() {
|
||||
m_shutdownInprogress = true;
|
||||
m_ioService.stop();
|
||||
m_async_ioService.stop();
|
||||
m_async_service_thread->interrupt();
|
||||
m_async_service_thread->join();
|
||||
m_threadpool.join_all();
|
||||
}
|
||||
|
||||
MessageListenerType ConsumeMessageOrderlyService::getConsumeMsgSerivceListenerType() {
|
||||
return m_pMessageListener->getMessageListenerType();
|
||||
}
|
||||
|
||||
void ConsumeMessageOrderlyService::submitConsumeRequest(boost::weak_ptr<PullRequest> pullRequest,
|
||||
vector<MQMessageExt>& msgs) {
|
||||
boost::shared_ptr<PullRequest> request = pullRequest.lock();
|
||||
if (!request) {
|
||||
LOG_WARN("Pull request has been released");
|
||||
return;
|
||||
}
|
||||
m_ioService.post(boost::bind(&ConsumeMessageOrderlyService::ConsumeRequest, this, request));
|
||||
}
|
||||
|
||||
void ConsumeMessageOrderlyService::static_submitConsumeRequestLater(void* context,
|
||||
boost::weak_ptr<PullRequest> pullRequest,
|
||||
bool tryLockMQ,
|
||||
boost::asio::deadline_timer* t) {
|
||||
boost::shared_ptr<PullRequest> request = pullRequest.lock();
|
||||
if (!request) {
|
||||
LOG_WARN("Pull request has been released");
|
||||
return;
|
||||
}
|
||||
LOG_INFO("submit consumeRequest later for mq:%s", request->m_messageQueue.toString().c_str());
|
||||
vector<MQMessageExt> msgs;
|
||||
ConsumeMessageOrderlyService* orderlyService = (ConsumeMessageOrderlyService*)context;
|
||||
orderlyService->submitConsumeRequest(request, msgs);
|
||||
if (tryLockMQ) {
|
||||
orderlyService->lockOneMQ(request->m_messageQueue);
|
||||
}
|
||||
if (t)
|
||||
deleteAndZero(t);
|
||||
}
|
||||
|
||||
void ConsumeMessageOrderlyService::ConsumeRequest(boost::weak_ptr<PullRequest> pullRequest) {
|
||||
boost::shared_ptr<PullRequest> request = pullRequest.lock();
|
||||
if (!request) {
|
||||
LOG_WARN("Pull request has been released");
|
||||
return;
|
||||
}
|
||||
bool bGetMutex = false;
|
||||
boost::unique_lock<boost::timed_mutex> lock(request->getPullRequestCriticalSection(), boost::try_to_lock);
|
||||
if (!lock.owns_lock()) {
|
||||
if (!lock.timed_lock(boost::get_system_time() + boost::posix_time::seconds(1))) {
|
||||
LOG_ERROR("ConsumeRequest of:%s get timed_mutex timeout", request->m_messageQueue.toString().c_str());
|
||||
return;
|
||||
} else {
|
||||
bGetMutex = true;
|
||||
}
|
||||
} else {
|
||||
bGetMutex = true;
|
||||
}
|
||||
if (!bGetMutex) {
|
||||
// LOG_INFO("pullrequest of mq:%s consume inprogress",
|
||||
// request->m_messageQueue.toString().c_str());
|
||||
return;
|
||||
}
|
||||
if (!request || request->isDropped()) {
|
||||
LOG_WARN("the pull result is NULL or Had been dropped");
|
||||
request->clearAllMsgs(); // add clear operation to avoid bad state when
|
||||
// dropped pullRequest returns normal
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pMessageListener) {
|
||||
if ((request->isLocked() && !request->isLockExpired()) || m_pConsumer->getMessageModel() == BROADCASTING) {
|
||||
// DefaultMQPushConsumer* pConsumer = (DefaultMQPushConsumer*)m_pConsumer;
|
||||
uint64_t beginTime = UtilAll::currentTimeMillis();
|
||||
bool continueConsume = true;
|
||||
while (continueConsume) {
|
||||
if ((UtilAll::currentTimeMillis() - beginTime) > m_MaxTimeConsumeContinuously) {
|
||||
LOG_INFO("Continuely consume %s more than 60s, consume it 1s later",
|
||||
request->m_messageQueue.toString().c_str());
|
||||
tryLockLaterAndReconsumeDelay(request, false, 1000);
|
||||
break;
|
||||
}
|
||||
vector<MQMessageExt> msgs;
|
||||
// request->takeMessages(msgs, pConsumer->getConsumeMessageBatchMaxSize());
|
||||
request->takeMessages(msgs, 1);
|
||||
if (!msgs.empty()) {
|
||||
request->setLastConsumeTimestamp(UtilAll::currentTimeMillis());
|
||||
if (m_pConsumer->isUseNameSpaceMode()) {
|
||||
MessageAccessor::withoutNameSpace(msgs, m_pConsumer->getNameSpace());
|
||||
}
|
||||
ConsumeMessageContext consumeMessageContext;
|
||||
DefaultMQPushConsumerImpl* pConsumer = dynamic_cast<DefaultMQPushConsumerImpl*>(m_pConsumer);
|
||||
if (pConsumer) {
|
||||
if (pConsumer->getMessageTrace() && pConsumer->hasConsumeMessageHook()) {
|
||||
consumeMessageContext.setDefaultMQPushConsumer(pConsumer);
|
||||
consumeMessageContext.setConsumerGroup(pConsumer->getGroupName());
|
||||
consumeMessageContext.setMessageQueue(request->m_messageQueue);
|
||||
consumeMessageContext.setMsgList(msgs);
|
||||
consumeMessageContext.setSuccess(false);
|
||||
consumeMessageContext.setNameSpace(pConsumer->getNameSpace());
|
||||
pConsumer->executeConsumeMessageHookBefore(&consumeMessageContext);
|
||||
}
|
||||
}
|
||||
ConsumeStatus consumeStatus = m_pMessageListener->consumeMessage(msgs);
|
||||
if (consumeStatus == RECONSUME_LATER) {
|
||||
if (pConsumer) {
|
||||
consumeMessageContext.setMsgIndex(0);
|
||||
consumeMessageContext.setStatus("RECONSUME_LATER");
|
||||
consumeMessageContext.setSuccess(false);
|
||||
pConsumer->executeConsumeMessageHookAfter(&consumeMessageContext);
|
||||
}
|
||||
if (msgs[0].getReconsumeTimes() <= 15) {
|
||||
msgs[0].setReconsumeTimes(msgs[0].getReconsumeTimes() + 1);
|
||||
request->makeMessageToCosumeAgain(msgs);
|
||||
continueConsume = false;
|
||||
tryLockLaterAndReconsumeDelay(request, false, 1000);
|
||||
} else {
|
||||
// need change to reconsumer delay level and print log.
|
||||
LOG_INFO("Local Consume failed [%d] times, change [%s] delay to 5s.", msgs[0].getReconsumeTimes(),
|
||||
msgs[0].getMsgId().c_str());
|
||||
msgs[0].setReconsumeTimes(msgs[0].getReconsumeTimes() + 1);
|
||||
continueConsume = false;
|
||||
request->makeMessageToCosumeAgain(msgs);
|
||||
tryLockLaterAndReconsumeDelay(request, false, 5000);
|
||||
}
|
||||
} else {
|
||||
if (pConsumer) {
|
||||
consumeMessageContext.setMsgIndex(0);
|
||||
consumeMessageContext.setStatus("CONSUME_SUCCESS");
|
||||
consumeMessageContext.setSuccess(true);
|
||||
pConsumer->executeConsumeMessageHookAfter(&consumeMessageContext);
|
||||
}
|
||||
m_pConsumer->updateConsumeOffset(request->m_messageQueue, request->commit());
|
||||
}
|
||||
} else {
|
||||
continueConsume = false;
|
||||
}
|
||||
msgs.clear();
|
||||
if (m_shutdownInprogress) {
|
||||
LOG_INFO("shutdown inprogress, break the consuming");
|
||||
return;
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("consume once exit of mq:%s", request->m_messageQueue.toString().c_str());
|
||||
} else {
|
||||
LOG_ERROR("message queue:%s was not locked", request->m_messageQueue.toString().c_str());
|
||||
tryLockLaterAndReconsumeDelay(request, true, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
void ConsumeMessageOrderlyService::tryLockLaterAndReconsumeDelay(boost::weak_ptr<PullRequest> pullRequest,
|
||||
bool tryLockMQ,
|
||||
int millisDelay) {
|
||||
boost::shared_ptr<PullRequest> request = pullRequest.lock();
|
||||
if (!request) {
|
||||
LOG_WARN("Pull request has been released");
|
||||
return;
|
||||
}
|
||||
int retryTimer = millisDelay;
|
||||
if (millisDelay >= 30000 || millisDelay <= 1000) {
|
||||
retryTimer = 1000;
|
||||
}
|
||||
boost::asio::deadline_timer* t =
|
||||
new boost::asio::deadline_timer(m_async_ioService, boost::posix_time::milliseconds(retryTimer));
|
||||
t->async_wait(
|
||||
boost::bind(&ConsumeMessageOrderlyService::static_submitConsumeRequestLater, this, request, tryLockMQ, t));
|
||||
}
|
||||
|
||||
} // namespace rocketmq
|
||||
115
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/ConsumeMsgService.h
vendored
Normal file
115
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/ConsumeMsgService.h
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _CONSUMEMESSAGESERVICE_H_
|
||||
#define _CONSUMEMESSAGESERVICE_H_
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include "DefaultMQPushConsumerImpl.h"
|
||||
#include "Logging.h"
|
||||
#include "MQConsumer.h"
|
||||
#include "MQMessageListener.h"
|
||||
#include "PullRequest.h"
|
||||
namespace rocketmq {
|
||||
// class MQConsumer;
|
||||
//<!***************************************************************************
|
||||
class ConsumeMsgService {
|
||||
public:
|
||||
ConsumeMsgService() {}
|
||||
virtual ~ConsumeMsgService() {}
|
||||
virtual void start() {}
|
||||
virtual void shutdown() {}
|
||||
virtual void stopThreadPool() {}
|
||||
virtual void submitConsumeRequest(boost::weak_ptr<PullRequest> request, vector<MQMessageExt>& msgs) {}
|
||||
virtual MessageListenerType getConsumeMsgSerivceListenerType() { return messageListenerDefaultly; }
|
||||
};
|
||||
|
||||
class ConsumeMessageConcurrentlyService : public ConsumeMsgService {
|
||||
public:
|
||||
ConsumeMessageConcurrentlyService(MQConsumer*, int threadCount, MQMessageListener* msgListener);
|
||||
virtual ~ConsumeMessageConcurrentlyService();
|
||||
virtual void start();
|
||||
virtual void shutdown();
|
||||
virtual void submitConsumeRequest(boost::weak_ptr<PullRequest> request, vector<MQMessageExt>& msgs);
|
||||
virtual MessageListenerType getConsumeMsgSerivceListenerType();
|
||||
virtual void stopThreadPool();
|
||||
|
||||
void ConsumeRequest(boost::weak_ptr<PullRequest> request, vector<MQMessageExt>& msgs);
|
||||
void submitConsumeRequestLater(boost::weak_ptr<PullRequest> request, vector<MQMessageExt>& msgs, int millis);
|
||||
|
||||
void triggersubmitConsumeRequestLater(boost::asio::deadline_timer* t,
|
||||
boost::weak_ptr<PullRequest> pullRequest,
|
||||
vector<MQMessageExt>& msgs);
|
||||
static void static_submitConsumeRequest(void* context,
|
||||
boost::asio::deadline_timer* t,
|
||||
boost::weak_ptr<PullRequest> pullRequest,
|
||||
vector<MQMessageExt>& msgs);
|
||||
|
||||
private:
|
||||
void resetRetryTopic(vector<MQMessageExt>& msgs);
|
||||
|
||||
private:
|
||||
MQConsumer* m_pConsumer;
|
||||
MQMessageListener* m_pMessageListener;
|
||||
boost::asio::io_service m_ioService;
|
||||
boost::thread_group m_threadpool;
|
||||
boost::asio::io_service::work m_ioServiceWork;
|
||||
};
|
||||
|
||||
class ConsumeMessageOrderlyService : public ConsumeMsgService {
|
||||
public:
|
||||
ConsumeMessageOrderlyService(MQConsumer*, int threadCount, MQMessageListener* msgListener);
|
||||
virtual ~ConsumeMessageOrderlyService();
|
||||
virtual void start();
|
||||
virtual void shutdown();
|
||||
virtual void submitConsumeRequest(boost::weak_ptr<PullRequest> request, vector<MQMessageExt>& msgs);
|
||||
virtual void stopThreadPool();
|
||||
virtual MessageListenerType getConsumeMsgSerivceListenerType();
|
||||
|
||||
void boost_asio_work();
|
||||
// void tryLockLaterAndReconsume(boost::weak_ptr<PullRequest> request, bool tryLockMQ);
|
||||
void tryLockLaterAndReconsumeDelay(boost::weak_ptr<PullRequest> request, bool tryLockMQ, int millisDelay);
|
||||
static void static_submitConsumeRequestLater(void* context,
|
||||
boost::weak_ptr<PullRequest> request,
|
||||
bool tryLockMQ,
|
||||
boost::asio::deadline_timer* t);
|
||||
void ConsumeRequest(boost::weak_ptr<PullRequest> request);
|
||||
void lockMQPeriodically(boost::system::error_code& ec, boost::asio::deadline_timer* t);
|
||||
void unlockAllMQ();
|
||||
bool lockOneMQ(const MQMessageQueue& mq);
|
||||
|
||||
private:
|
||||
MQConsumer* m_pConsumer;
|
||||
bool m_shutdownInprogress;
|
||||
MQMessageListener* m_pMessageListener;
|
||||
uint64_t m_MaxTimeConsumeContinuously;
|
||||
boost::asio::io_service m_ioService;
|
||||
boost::thread_group m_threadpool;
|
||||
boost::asio::io_service::work m_ioServiceWork;
|
||||
boost::asio::io_service m_async_ioService;
|
||||
boost::scoped_ptr<boost::thread> m_async_service_thread;
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
|
||||
#endif //<! _CONSUMEMESSAGESERVICE_H_
|
||||
198
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/DefaultMQPullConsumer.cpp
vendored
Normal file
198
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/DefaultMQPullConsumer.cpp
vendored
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "DefaultMQPullConsumer.h"
|
||||
#include "DefaultMQPullConsumerImpl.h"
|
||||
#include "MQVersion.h"
|
||||
|
||||
namespace rocketmq {
|
||||
|
||||
DefaultMQPullConsumer::DefaultMQPullConsumer(const std::string& groupName) {
|
||||
impl = new DefaultMQPullConsumerImpl(groupName);
|
||||
}
|
||||
|
||||
DefaultMQPullConsumer::~DefaultMQPullConsumer() {
|
||||
delete impl;
|
||||
}
|
||||
void DefaultMQPullConsumer::start() {
|
||||
impl->start();
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumer::shutdown() {
|
||||
impl->shutdown();
|
||||
}
|
||||
std::string DefaultMQPullConsumer::version() {
|
||||
std::string versions = impl->getClientVersionString();
|
||||
/*versions.append(", PROTOCOL VERSION: ")
|
||||
.append(MQVersion::GetVersionDesc(MQVersion::s_CurrentVersion))
|
||||
.append(", LANGUAGE: ")
|
||||
.append(MQVersion::s_CurrentLanguage);*/
|
||||
return versions;
|
||||
}
|
||||
// start mqclient set
|
||||
const std::string& DefaultMQPullConsumer::getNamesrvAddr() const {
|
||||
return impl->getNamesrvAddr();
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumer::setNamesrvAddr(const std::string& namesrvAddr) {
|
||||
impl->setNamesrvAddr(namesrvAddr);
|
||||
}
|
||||
|
||||
const std::string& DefaultMQPullConsumer::getNamesrvDomain() const {
|
||||
return impl->getNamesrvDomain();
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumer::setNamesrvDomain(const std::string& namesrvDomain) {
|
||||
impl->setNamesrvDomain(namesrvDomain);
|
||||
}
|
||||
void DefaultMQPullConsumer::setSessionCredentials(const std::string& accessKey,
|
||||
const std::string& secretKey,
|
||||
const std::string& accessChannel) {
|
||||
impl->setSessionCredentials(accessKey, secretKey, accessChannel);
|
||||
}
|
||||
|
||||
const SessionCredentials& DefaultMQPullConsumer::getSessionCredentials() const {
|
||||
return impl->getSessionCredentials();
|
||||
}
|
||||
const std::string& DefaultMQPullConsumer::getInstanceName() const {
|
||||
return impl->getInstanceName();
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumer::setInstanceName(const std::string& instanceName) {
|
||||
impl->setInstanceName(instanceName);
|
||||
}
|
||||
|
||||
const std::string& DefaultMQPullConsumer::getNameSpace() const {
|
||||
return impl->getNameSpace();
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumer::setNameSpace(const std::string& nameSpace) {
|
||||
impl->setNameSpace(nameSpace);
|
||||
}
|
||||
const std::string& DefaultMQPullConsumer::getGroupName() const {
|
||||
return impl->getGroupName();
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumer::setGroupName(const std::string& groupName) {
|
||||
impl->setGroupName(groupName);
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumer::setEnableSsl(bool enableSsl) {
|
||||
impl->setEnableSsl(enableSsl);
|
||||
}
|
||||
|
||||
bool DefaultMQPullConsumer::getEnableSsl() const {
|
||||
return impl->getEnableSsl();
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumer::setSslPropertyFile(const std::string& sslPropertyFile) {
|
||||
impl->setSslPropertyFile(sslPropertyFile);
|
||||
}
|
||||
|
||||
const std::string& DefaultMQPullConsumer::getSslPropertyFile() const {
|
||||
return impl->getSslPropertyFile();
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumer::setLogLevel(elogLevel inputLevel) {
|
||||
impl->setLogLevel(inputLevel);
|
||||
}
|
||||
|
||||
elogLevel DefaultMQPullConsumer::getLogLevel() {
|
||||
return impl->getLogLevel();
|
||||
}
|
||||
void DefaultMQPullConsumer::setLogFileSizeAndNum(int fileNum, long perFileSize) {
|
||||
impl->setLogFileSizeAndNum(fileNum, perFileSize);
|
||||
}
|
||||
|
||||
// void DefaultMQPullConsumer::setUnitName(std::string unitName) {
|
||||
// impl->setUnitName(unitName);
|
||||
// }
|
||||
// const std::string& DefaultMQPullConsumer::getUnitName() const {
|
||||
// return impl->getUnitName();
|
||||
// }
|
||||
|
||||
void DefaultMQPullConsumer::fetchSubscribeMessageQueues(const std::string& topic, std::vector<MQMessageQueue>& mqs) {
|
||||
impl->fetchSubscribeMessageQueues(topic, mqs);
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumer::persistConsumerOffset() {
|
||||
impl->persistConsumerOffset();
|
||||
}
|
||||
void DefaultMQPullConsumer::persistConsumerOffsetByResetOffset() {
|
||||
impl->persistConsumerOffsetByResetOffset();
|
||||
}
|
||||
void DefaultMQPullConsumer::updateTopicSubscribeInfo(const std::string& topic, std::vector<MQMessageQueue>& info) {
|
||||
impl->updateTopicSubscribeInfo(topic, info);
|
||||
}
|
||||
|
||||
ConsumeFromWhere DefaultMQPullConsumer::getConsumeFromWhere() {
|
||||
return impl->getConsumeFromWhere();
|
||||
}
|
||||
void DefaultMQPullConsumer::getSubscriptions(std::vector<SubscriptionData>& subData) {
|
||||
impl->getSubscriptions(subData);
|
||||
}
|
||||
void DefaultMQPullConsumer::updateConsumeOffset(const MQMessageQueue& mq, int64 offset) {
|
||||
impl->updateConsumeOffset(mq, offset);
|
||||
}
|
||||
void DefaultMQPullConsumer::removeConsumeOffset(const MQMessageQueue& mq) {
|
||||
impl->removeConsumeOffset(mq);
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumer::registerMessageQueueListener(const std::string& topic, MQueueListener* pListener) {
|
||||
impl->registerMessageQueueListener(topic, pListener);
|
||||
}
|
||||
PullResult DefaultMQPullConsumer::pull(const MQMessageQueue& mq,
|
||||
const std::string& subExpression,
|
||||
int64 offset,
|
||||
int maxNums) {
|
||||
return impl->pull(mq, subExpression, offset, maxNums);
|
||||
}
|
||||
void DefaultMQPullConsumer::pull(const MQMessageQueue& mq,
|
||||
const std::string& subExpression,
|
||||
int64 offset,
|
||||
int maxNums,
|
||||
PullCallback* pPullCallback) {
|
||||
impl->pull(mq, subExpression, offset, maxNums, pPullCallback);
|
||||
}
|
||||
|
||||
PullResult DefaultMQPullConsumer::pullBlockIfNotFound(const MQMessageQueue& mq,
|
||||
const std::string& subExpression,
|
||||
int64 offset,
|
||||
int maxNums) {
|
||||
return impl->pullBlockIfNotFound(mq, subExpression, offset, maxNums);
|
||||
}
|
||||
void DefaultMQPullConsumer::pullBlockIfNotFound(const MQMessageQueue& mq,
|
||||
const std::string& subExpression,
|
||||
int64 offset,
|
||||
int maxNums,
|
||||
PullCallback* pPullCallback) {
|
||||
impl->pullBlockIfNotFound(mq, subExpression, offset, maxNums, pPullCallback);
|
||||
}
|
||||
|
||||
int64 DefaultMQPullConsumer::fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore) {
|
||||
return impl->fetchConsumeOffset(mq, fromStore);
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumer::fetchMessageQueuesInBalance(const std::string& topic, std::vector<MQMessageQueue> mqs) {
|
||||
impl->fetchMessageQueuesInBalance(topic, mqs);
|
||||
}
|
||||
void DefaultMQPullConsumer::persistConsumerOffset4PullConsumer(const MQMessageQueue& mq) {
|
||||
// impl->persistConsumerOffsetByResetOffset(mq);
|
||||
}
|
||||
|
||||
//<!************************************************************************
|
||||
} // namespace rocketmq
|
||||
@@ -0,0 +1,421 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "DefaultMQPullConsumerImpl.h"
|
||||
#include "AsyncArg.h"
|
||||
#include "CommunicationMode.h"
|
||||
#include "FilterAPI.h"
|
||||
#include "Logging.h"
|
||||
#include "MQClientFactory.h"
|
||||
#include "MessageAccessor.h"
|
||||
#include "NameSpaceUtil.h"
|
||||
#include "OffsetStore.h"
|
||||
#include "PullAPIWrapper.h"
|
||||
#include "PullSysFlag.h"
|
||||
#include "Rebalance.h"
|
||||
#include "Validators.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
DefaultMQPullConsumerImpl::DefaultMQPullConsumerImpl(const string& groupname)
|
||||
: m_pMessageQueueListener(NULL),
|
||||
m_pOffsetStore(NULL),
|
||||
m_pRebalance(NULL),
|
||||
m_pPullAPIWrapper(NULL)
|
||||
|
||||
{
|
||||
//<!set default group name;
|
||||
string gname = groupname.empty() ? DEFAULT_CONSUMER_GROUP : groupname;
|
||||
setGroupName(gname);
|
||||
|
||||
setMessageModel(CLUSTERING);
|
||||
}
|
||||
|
||||
DefaultMQPullConsumerImpl::~DefaultMQPullConsumerImpl() {
|
||||
m_pMessageQueueListener = NULL;
|
||||
deleteAndZero(m_pRebalance);
|
||||
deleteAndZero(m_pOffsetStore);
|
||||
deleteAndZero(m_pPullAPIWrapper);
|
||||
}
|
||||
|
||||
// MQConsumer
|
||||
//<!************************************************************************
|
||||
void DefaultMQPullConsumerImpl::start() {
|
||||
#ifndef WIN32
|
||||
/* Ignore the SIGPIPE */
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(struct sigaction));
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sa.sa_flags = 0;
|
||||
sigaction(SIGPIPE, &sa, 0);
|
||||
#endif
|
||||
LOG_INFO("###Current Pull Consumer@%s", getClientVersionString().c_str());
|
||||
dealWithNameSpace();
|
||||
showClientConfigs();
|
||||
switch (m_serviceState) {
|
||||
case CREATE_JUST: {
|
||||
m_serviceState = START_FAILED;
|
||||
DefaultMQClient::start();
|
||||
LOG_INFO("DefaultMQPullConsumerImpl:%s start", m_GroupName.c_str());
|
||||
|
||||
//<!create rebalance;
|
||||
m_pRebalance = new RebalancePull(this, getFactory());
|
||||
|
||||
string groupname = getGroupName();
|
||||
m_pPullAPIWrapper = new PullAPIWrapper(getFactory(), groupname);
|
||||
|
||||
//<!data;
|
||||
checkConfig();
|
||||
copySubscription();
|
||||
|
||||
//<! registe;
|
||||
bool registerOK = getFactory()->registerConsumer(this);
|
||||
if (!registerOK) {
|
||||
m_serviceState = CREATE_JUST;
|
||||
THROW_MQEXCEPTION(
|
||||
MQClientException,
|
||||
"The cousumer group[" + getGroupName() + "] has been created before, specify another name please.", -1);
|
||||
}
|
||||
|
||||
//<!msg model;
|
||||
switch (getMessageModel()) {
|
||||
case BROADCASTING:
|
||||
m_pOffsetStore = new LocalFileOffsetStore(groupname, getFactory());
|
||||
break;
|
||||
case CLUSTERING:
|
||||
m_pOffsetStore = new RemoteBrokerOffsetStore(groupname, getFactory());
|
||||
break;
|
||||
}
|
||||
bool bStartFailed = false;
|
||||
string errorMsg;
|
||||
try {
|
||||
m_pOffsetStore->load();
|
||||
} catch (MQClientException& e) {
|
||||
bStartFailed = true;
|
||||
errorMsg = std::string(e.what());
|
||||
}
|
||||
|
||||
getFactory()->start();
|
||||
m_serviceState = RUNNING;
|
||||
if (bStartFailed) {
|
||||
shutdown();
|
||||
THROW_MQEXCEPTION(MQClientException, errorMsg, -1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RUNNING:
|
||||
case START_FAILED:
|
||||
case SHUTDOWN_ALREADY:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumerImpl::shutdown() {
|
||||
switch (m_serviceState) {
|
||||
case RUNNING: {
|
||||
LOG_INFO("DefaultMQPullConsumerImpl:%s shutdown", m_GroupName.c_str());
|
||||
persistConsumerOffset();
|
||||
getFactory()->unregisterConsumer(this);
|
||||
getFactory()->shutdown();
|
||||
m_serviceState = SHUTDOWN_ALREADY;
|
||||
break;
|
||||
}
|
||||
case SHUTDOWN_ALREADY:
|
||||
case CREATE_JUST:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool DefaultMQPullConsumerImpl::sendMessageBack(MQMessageExt& msg, int delayLevel, string& brokerName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumerImpl::fetchSubscribeMessageQueues(const string& topic, vector<MQMessageQueue>& mqs) {
|
||||
mqs.clear();
|
||||
try {
|
||||
const string localTopic = NameSpaceUtil::withNameSpace(topic, getNameSpace());
|
||||
getFactory()->fetchSubscribeMessageQueues(localTopic, mqs, getSessionCredentials());
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("%s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumerImpl::updateTopicSubscribeInfo(const string& topic, vector<MQMessageQueue>& info) {}
|
||||
|
||||
void DefaultMQPullConsumerImpl::registerMessageQueueListener(const string& topic, MQueueListener* pListener) {
|
||||
m_registerTopics.insert(topic);
|
||||
if (pListener) {
|
||||
m_pMessageQueueListener = pListener;
|
||||
}
|
||||
}
|
||||
|
||||
PullResult DefaultMQPullConsumerImpl::pull(const MQMessageQueue& mq,
|
||||
const string& subExpression,
|
||||
int64 offset,
|
||||
int maxNums) {
|
||||
return pullSyncImpl(mq, subExpression, offset, maxNums, false);
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumerImpl::pull(const MQMessageQueue& mq,
|
||||
const string& subExpression,
|
||||
int64 offset,
|
||||
int maxNums,
|
||||
PullCallback* pPullCallback) {
|
||||
pullAsyncImpl(mq, subExpression, offset, maxNums, false, pPullCallback);
|
||||
}
|
||||
|
||||
PullResult DefaultMQPullConsumerImpl::pullBlockIfNotFound(const MQMessageQueue& mq,
|
||||
const string& subExpression,
|
||||
int64 offset,
|
||||
int maxNums) {
|
||||
return pullSyncImpl(mq, subExpression, offset, maxNums, true);
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumerImpl::pullBlockIfNotFound(const MQMessageQueue& mq,
|
||||
const string& subExpression,
|
||||
int64 offset,
|
||||
int maxNums,
|
||||
PullCallback* pPullCallback) {
|
||||
pullAsyncImpl(mq, subExpression, offset, maxNums, true, pPullCallback);
|
||||
}
|
||||
|
||||
PullResult DefaultMQPullConsumerImpl::pullSyncImpl(const MQMessageQueue& mq,
|
||||
const string& subExpression,
|
||||
int64 offset,
|
||||
int maxNums,
|
||||
bool block) {
|
||||
if (offset < 0)
|
||||
THROW_MQEXCEPTION(MQClientException, "offset < 0", -1);
|
||||
|
||||
if (maxNums <= 0)
|
||||
THROW_MQEXCEPTION(MQClientException, "maxNums <= 0", -1);
|
||||
|
||||
//<!auto subscript,all sub;
|
||||
subscriptionAutomatically(mq.getTopic());
|
||||
|
||||
int sysFlag = PullSysFlag::buildSysFlag(false, block, true, false);
|
||||
|
||||
//<!this sub;
|
||||
unique_ptr<SubscriptionData> pSData(FilterAPI::buildSubscriptionData(mq.getTopic(), subExpression));
|
||||
|
||||
int timeoutMillis = block ? 1000 * 30 : 1000 * 10;
|
||||
|
||||
try {
|
||||
unique_ptr<PullResult> pullResult(m_pPullAPIWrapper->pullKernelImpl(mq, // 1
|
||||
pSData->getSubString(), // 2
|
||||
0L, // 3
|
||||
offset, // 4
|
||||
maxNums, // 5
|
||||
sysFlag, // 6
|
||||
0, // 7
|
||||
1000 * 20, // 8
|
||||
timeoutMillis, // 9
|
||||
ComMode_SYNC, // 10
|
||||
NULL, //<!callback;
|
||||
getSessionCredentials(), NULL));
|
||||
PullResult pr = m_pPullAPIWrapper->processPullResult(mq, pullResult.get(), pSData.get());
|
||||
if (m_useNameSpaceMode) {
|
||||
MessageAccessor::withoutNameSpace(pr.msgFoundList, m_nameSpace);
|
||||
}
|
||||
return pr;
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("%s", e.what());
|
||||
}
|
||||
return PullResult(BROKER_TIMEOUT);
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumerImpl::pullAsyncImpl(const MQMessageQueue& mq,
|
||||
const string& subExpression,
|
||||
int64 offset,
|
||||
int maxNums,
|
||||
bool block,
|
||||
PullCallback* pPullCallback) {
|
||||
if (offset < 0)
|
||||
THROW_MQEXCEPTION(MQClientException, "offset < 0", -1);
|
||||
|
||||
if (maxNums <= 0)
|
||||
THROW_MQEXCEPTION(MQClientException, "maxNums <= 0", -1);
|
||||
|
||||
if (!pPullCallback)
|
||||
THROW_MQEXCEPTION(MQClientException, "pPullCallback is null", -1);
|
||||
|
||||
//<!auto subscript,all sub;
|
||||
subscriptionAutomatically(mq.getTopic());
|
||||
|
||||
int sysFlag = PullSysFlag::buildSysFlag(false, block, true, false);
|
||||
|
||||
//<!this sub;
|
||||
unique_ptr<SubscriptionData> pSData(FilterAPI::buildSubscriptionData(mq.getTopic(), subExpression));
|
||||
|
||||
int timeoutMillis = block ? 1000 * 30 : 1000 * 10;
|
||||
|
||||
//<!<21>첽<EFBFBD><ECB2BD><EFBFBD><EFBFBD>;
|
||||
AsyncArg arg;
|
||||
arg.mq = mq;
|
||||
arg.subData = *pSData;
|
||||
arg.pPullWrapper = m_pPullAPIWrapper;
|
||||
|
||||
try {
|
||||
// not support name space
|
||||
unique_ptr<PullResult> pullResult(m_pPullAPIWrapper->pullKernelImpl(mq, // 1
|
||||
pSData->getSubString(), // 2
|
||||
0L, // 3
|
||||
offset, // 4
|
||||
maxNums, // 5
|
||||
sysFlag, // 6
|
||||
0, // 7
|
||||
1000 * 20, // 8
|
||||
timeoutMillis, // 9
|
||||
ComMode_ASYNC, // 10
|
||||
pPullCallback, getSessionCredentials(), &arg));
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("%s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumerImpl::subscriptionAutomatically(const string& topic) {
|
||||
SubscriptionData* pSdata = m_pRebalance->getSubscriptionData(topic);
|
||||
if (pSdata == NULL) {
|
||||
unique_ptr<SubscriptionData> subscriptionData(FilterAPI::buildSubscriptionData(topic, SUB_ALL));
|
||||
m_pRebalance->setSubscriptionData(topic, subscriptionData.release());
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumerImpl::updateConsumeOffset(const MQMessageQueue& mq, int64 offset) {
|
||||
m_pOffsetStore->updateOffset(mq, offset);
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumerImpl::removeConsumeOffset(const MQMessageQueue& mq) {
|
||||
m_pOffsetStore->removeOffset(mq);
|
||||
}
|
||||
|
||||
int64 DefaultMQPullConsumerImpl::fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore) {
|
||||
return m_pOffsetStore->readOffset(mq, fromStore ? READ_FROM_STORE : MEMORY_FIRST_THEN_STORE, getSessionCredentials());
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumerImpl::persistConsumerOffset() {
|
||||
/*As do not execute rebalance for pullConsumer now, requestTable is always
|
||||
empty
|
||||
map<MQMessageQueue, PullRequest*> requestTable =
|
||||
m_pRebalance->getPullRequestTable();
|
||||
map<MQMessageQueue, PullRequest*>::iterator it = requestTable.begin();
|
||||
vector<MQMessageQueue> mqs;
|
||||
for (; it != requestTable.end(); ++it)
|
||||
{
|
||||
if (it->second)
|
||||
{
|
||||
mqs.push_back(it->first);
|
||||
}
|
||||
}
|
||||
m_pOffsetStore->persistAll(mqs);*/
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumerImpl::persistConsumerOffsetByResetOffset() {}
|
||||
|
||||
void DefaultMQPullConsumerImpl::persistConsumerOffset4PullConsumer(const MQMessageQueue& mq) {
|
||||
if (isServiceStateOk()) {
|
||||
m_pOffsetStore->persist(mq, getSessionCredentials());
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumerImpl::fetchMessageQueuesInBalance(const string& topic, vector<MQMessageQueue> mqs) {}
|
||||
|
||||
void DefaultMQPullConsumerImpl::checkConfig() {
|
||||
string groupname = getGroupName();
|
||||
// check consumerGroup
|
||||
Validators::checkGroup(groupname);
|
||||
|
||||
// consumerGroup
|
||||
if (!groupname.compare(DEFAULT_CONSUMER_GROUP)) {
|
||||
THROW_MQEXCEPTION(MQClientException, "consumerGroup can not equal DEFAULT_CONSUMER", -1);
|
||||
}
|
||||
|
||||
if (getMessageModel() != BROADCASTING && getMessageModel() != CLUSTERING) {
|
||||
THROW_MQEXCEPTION(MQClientException, "messageModel is valid ", -1);
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumerImpl::doRebalance() {}
|
||||
|
||||
void DefaultMQPullConsumerImpl::copySubscription() {
|
||||
set<string>::iterator it = m_registerTopics.begin();
|
||||
for (; it != m_registerTopics.end(); ++it) {
|
||||
unique_ptr<SubscriptionData> subscriptionData(FilterAPI::buildSubscriptionData((*it), SUB_ALL));
|
||||
m_pRebalance->setSubscriptionData((*it), subscriptionData.release());
|
||||
}
|
||||
}
|
||||
|
||||
ConsumeType DefaultMQPullConsumerImpl::getConsumeType() {
|
||||
return CONSUME_ACTIVELY;
|
||||
}
|
||||
|
||||
ConsumeFromWhere DefaultMQPullConsumerImpl::getConsumeFromWhere() {
|
||||
return CONSUME_FROM_LAST_OFFSET;
|
||||
}
|
||||
|
||||
void DefaultMQPullConsumerImpl::getSubscriptions(vector<SubscriptionData>& result) {
|
||||
set<string>::iterator it = m_registerTopics.begin();
|
||||
for (; it != m_registerTopics.end(); ++it) {
|
||||
SubscriptionData ms(*it, SUB_ALL);
|
||||
result.push_back(ms);
|
||||
}
|
||||
}
|
||||
|
||||
bool DefaultMQPullConsumerImpl::producePullMsgTask(boost::weak_ptr<PullRequest> pullRequest) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Rebalance* DefaultMQPullConsumerImpl::getRebalance() const {
|
||||
return NULL;
|
||||
}
|
||||
// we should deal with name space before producer start.
|
||||
bool DefaultMQPullConsumerImpl::dealWithNameSpace() {
|
||||
string ns = getNameSpace();
|
||||
if (ns.empty()) {
|
||||
string nsAddr = getNamesrvAddr();
|
||||
if (!NameSpaceUtil::checkNameSpaceExistInNameServer(nsAddr)) {
|
||||
return true;
|
||||
}
|
||||
ns = NameSpaceUtil::getNameSpaceFromNsURL(nsAddr);
|
||||
// reset namespace
|
||||
setNameSpace(ns);
|
||||
}
|
||||
// reset group name
|
||||
if (!NameSpaceUtil::hasNameSpace(getGroupName(), ns)) {
|
||||
string fullGID = NameSpaceUtil::withNameSpace(getGroupName(), ns);
|
||||
setGroupName(fullGID);
|
||||
}
|
||||
set<string> tmpTopics;
|
||||
for (auto iter = m_registerTopics.begin(); iter != m_registerTopics.end(); iter++) {
|
||||
string topic = *iter;
|
||||
if (!NameSpaceUtil::hasNameSpace(topic, ns)) {
|
||||
LOG_INFO("Update Subscribe Topic[%s] with NameSpace:%s", topic.c_str(), ns.c_str());
|
||||
topic = NameSpaceUtil::withNameSpace(topic, ns);
|
||||
// let other mode to known, the name space model opened.
|
||||
m_useNameSpaceMode = true;
|
||||
}
|
||||
tmpTopics.insert(topic);
|
||||
}
|
||||
m_registerTopics.swap(tmpTopics);
|
||||
return true;
|
||||
}
|
||||
//<!************************************************************************
|
||||
} // namespace rocketmq
|
||||
148
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/DefaultMQPullConsumerImpl.h
vendored
Normal file
148
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/DefaultMQPullConsumerImpl.h
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __DEFAULTMQPULLCONSUMERIMPL_H__
|
||||
#define __DEFAULTMQPULLCONSUMERIMPL_H__
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "MQConsumer.h"
|
||||
#include "MQMessageQueue.h"
|
||||
#include "MQueueListener.h"
|
||||
#include "RocketMQClient.h"
|
||||
|
||||
namespace rocketmq {
|
||||
class Rebalance;
|
||||
class SubscriptionData;
|
||||
class OffsetStore;
|
||||
class PullAPIWrapper;
|
||||
class ConsumerRunningInfo;
|
||||
//<!***************************************************************************
|
||||
class DefaultMQPullConsumerImpl : public MQConsumer {
|
||||
public:
|
||||
DefaultMQPullConsumerImpl(const std::string& groupname);
|
||||
virtual ~DefaultMQPullConsumerImpl();
|
||||
|
||||
//<!begin mqadmin;
|
||||
virtual void start();
|
||||
virtual void shutdown();
|
||||
//<!end mqadmin;
|
||||
|
||||
//<!begin MQConsumer
|
||||
virtual bool sendMessageBack(MQMessageExt& msg, int delayLevel, std::string& brokerName);
|
||||
virtual void fetchSubscribeMessageQueues(const std::string& topic, std::vector<MQMessageQueue>& mqs);
|
||||
virtual void doRebalance();
|
||||
virtual void persistConsumerOffset();
|
||||
virtual void persistConsumerOffsetByResetOffset();
|
||||
virtual void updateTopicSubscribeInfo(const std::string& topic, std::vector<MQMessageQueue>& info);
|
||||
virtual ConsumeType getConsumeType();
|
||||
virtual ConsumeFromWhere getConsumeFromWhere();
|
||||
virtual void getSubscriptions(std::vector<SubscriptionData>&);
|
||||
virtual void updateConsumeOffset(const MQMessageQueue& mq, int64 offset);
|
||||
virtual void removeConsumeOffset(const MQMessageQueue& mq);
|
||||
virtual bool producePullMsgTask(boost::weak_ptr<PullRequest> pullRequest);
|
||||
virtual Rebalance* getRebalance() const;
|
||||
//<!end MQConsumer;
|
||||
|
||||
void registerMessageQueueListener(const std::string& topic, MQueueListener* pListener);
|
||||
/**
|
||||
* Pull message from specified queue, if no msg in queue, return directly
|
||||
*
|
||||
* @param mq
|
||||
* specify the pulled queue
|
||||
* @param subExpression
|
||||
* set filter expression for pulled msg, broker will filter msg actively
|
||||
* Now only OR operation is supported, eg: "tag1 || tag2 || tag3"
|
||||
* if subExpression is setted to "null" or "*", all msg will be subscribed
|
||||
* @param offset
|
||||
* specify the started pull offset
|
||||
* @param maxNums
|
||||
* specify max msg num by per pull
|
||||
* @return
|
||||
* PullResult
|
||||
*/
|
||||
virtual PullResult pull(const MQMessageQueue& mq, const std::string& subExpression, int64 offset, int maxNums);
|
||||
virtual void pull(const MQMessageQueue& mq,
|
||||
const std::string& subExpression,
|
||||
int64 offset,
|
||||
int maxNums,
|
||||
PullCallback* pPullCallback);
|
||||
|
||||
/**
|
||||
* pull msg from specified queue, if no msg, broker will suspend the pull request 20s
|
||||
*
|
||||
* @param mq
|
||||
* specify the pulled queue
|
||||
* @param subExpression
|
||||
* set filter expression for pulled msg, broker will filter msg actively
|
||||
* Now only OR operation is supported, eg: "tag1 || tag2 || tag3"
|
||||
* if subExpression is setted to "null" or "*", all msg will be subscribed
|
||||
* @param offset
|
||||
* specify the started pull offset
|
||||
* @param maxNums
|
||||
* specify max msg num by per pull
|
||||
* @return
|
||||
* accroding to PullResult
|
||||
*/
|
||||
PullResult pullBlockIfNotFound(const MQMessageQueue& mq, const std::string& subExpression, int64 offset, int maxNums);
|
||||
void pullBlockIfNotFound(const MQMessageQueue& mq,
|
||||
const std::string& subExpression,
|
||||
int64 offset,
|
||||
int maxNums,
|
||||
PullCallback* pPullCallback);
|
||||
|
||||
virtual ConsumerRunningInfo* getConsumerRunningInfo() { return NULL; }
|
||||
|
||||
int64 fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore);
|
||||
|
||||
void fetchMessageQueuesInBalance(const std::string& topic, std::vector<MQMessageQueue> mqs);
|
||||
|
||||
// temp persist consumer offset interface, only valid with
|
||||
// RemoteBrokerOffsetStore, updateConsumeOffset should be called before.
|
||||
void persistConsumerOffset4PullConsumer(const MQMessageQueue& mq);
|
||||
|
||||
private:
|
||||
void checkConfig();
|
||||
void copySubscription();
|
||||
bool dealWithNameSpace();
|
||||
|
||||
PullResult pullSyncImpl(const MQMessageQueue& mq,
|
||||
const std::string& subExpression,
|
||||
int64 offset,
|
||||
int maxNums,
|
||||
bool block);
|
||||
|
||||
void pullAsyncImpl(const MQMessageQueue& mq,
|
||||
const std::string& subExpression,
|
||||
int64 offset,
|
||||
int maxNums,
|
||||
bool block,
|
||||
PullCallback* pPullCallback);
|
||||
|
||||
void subscriptionAutomatically(const std::string& topic);
|
||||
|
||||
private:
|
||||
std::set<std::string> m_registerTopics;
|
||||
|
||||
MQueueListener* m_pMessageQueueListener;
|
||||
OffsetStore* m_pOffsetStore;
|
||||
Rebalance* m_pRebalance;
|
||||
PullAPIWrapper* m_pPullAPIWrapper;
|
||||
};
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
228
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/DefaultMQPushConsumer.cpp
vendored
Normal file
228
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/DefaultMQPushConsumer.cpp
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "DefaultMQPushConsumer.h"
|
||||
#include <MQVersion.h>
|
||||
#include "DefaultMQPushConsumerImpl.h"
|
||||
|
||||
namespace rocketmq {
|
||||
|
||||
DefaultMQPushConsumer::DefaultMQPushConsumer(const std::string& groupName) {
|
||||
impl = new DefaultMQPushConsumerImpl(groupName);
|
||||
}
|
||||
|
||||
DefaultMQPushConsumer::~DefaultMQPushConsumer() {
|
||||
delete impl;
|
||||
}
|
||||
void DefaultMQPushConsumer::start() {
|
||||
impl->start();
|
||||
}
|
||||
|
||||
void DefaultMQPushConsumer::shutdown() {
|
||||
impl->shutdown();
|
||||
}
|
||||
std::string DefaultMQPushConsumer::version() {
|
||||
std::string versions = impl->getClientVersionString();
|
||||
/*versions.append(", PROTOCOL VERSION: ")
|
||||
.append(MQVersion::GetVersionDesc(MQVersion::s_CurrentVersion))
|
||||
.append(", LANGUAGE: ")
|
||||
.append(MQVersion::s_CurrentLanguage);*/
|
||||
return versions;
|
||||
}
|
||||
// ConsumeType DefaultMQPushConsumer::getConsumeType() {
|
||||
// return impl->getConsumeType();
|
||||
//}
|
||||
|
||||
ConsumeFromWhere DefaultMQPushConsumer::getConsumeFromWhere() {
|
||||
return impl->getConsumeFromWhere();
|
||||
}
|
||||
void DefaultMQPushConsumer::setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) {
|
||||
impl->setConsumeFromWhere(consumeFromWhere);
|
||||
}
|
||||
|
||||
void DefaultMQPushConsumer::registerMessageListener(MQMessageListener* pMessageListener) {
|
||||
impl->registerMessageListener(pMessageListener);
|
||||
}
|
||||
MessageListenerType DefaultMQPushConsumer::getMessageListenerType() {
|
||||
return impl->getMessageListenerType();
|
||||
}
|
||||
void DefaultMQPushConsumer::subscribe(const std::string& topic, const std::string& subExpression) {
|
||||
impl->subscribe(topic, subExpression);
|
||||
}
|
||||
|
||||
void DefaultMQPushConsumer::setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) {
|
||||
impl->setConsumeMessageBatchMaxSize(consumeMessageBatchMaxSize);
|
||||
}
|
||||
int DefaultMQPushConsumer::getConsumeMessageBatchMaxSize() const {
|
||||
return impl->getConsumeMessageBatchMaxSize();
|
||||
}
|
||||
|
||||
/*
|
||||
set consuming thread count, default value is cpu cores
|
||||
*/
|
||||
void DefaultMQPushConsumer::setConsumeThreadCount(int threadCount) {
|
||||
impl->setConsumeThreadCount(threadCount);
|
||||
}
|
||||
int DefaultMQPushConsumer::getConsumeThreadCount() const {
|
||||
return impl->getConsumeThreadCount();
|
||||
}
|
||||
void DefaultMQPushConsumer::setMaxReconsumeTimes(int maxReconsumeTimes) {
|
||||
impl->setMaxReconsumeTimes(maxReconsumeTimes);
|
||||
}
|
||||
int DefaultMQPushConsumer::getMaxReconsumeTimes() const {
|
||||
return impl->getMaxReconsumeTimes();
|
||||
}
|
||||
|
||||
/*
|
||||
set pullMsg thread count, default value is cpu cores
|
||||
*/
|
||||
void DefaultMQPushConsumer::setPullMsgThreadPoolCount(int threadCount) {
|
||||
impl->setPullMsgThreadPoolCount(threadCount);
|
||||
}
|
||||
int DefaultMQPushConsumer::getPullMsgThreadPoolCount() const {
|
||||
return impl->getPullMsgThreadPoolCount();
|
||||
}
|
||||
|
||||
/*
|
||||
set max cache msg size perQueue in memory if consumer could not consume msgs
|
||||
immediately
|
||||
default maxCacheMsgSize perQueue is 1000, set range is:1~65535
|
||||
*/
|
||||
void DefaultMQPushConsumer::setMaxCacheMsgSizePerQueue(int maxCacheSize) {
|
||||
impl->setMaxCacheMsgSizePerQueue(maxCacheSize);
|
||||
}
|
||||
int DefaultMQPushConsumer::getMaxCacheMsgSizePerQueue() const {
|
||||
return impl->getMaxCacheMsgSizePerQueue();
|
||||
}
|
||||
|
||||
MessageModel DefaultMQPushConsumer::getMessageModel() const {
|
||||
return impl->getMessageModel();
|
||||
}
|
||||
void DefaultMQPushConsumer::setMessageModel(MessageModel messageModel) {
|
||||
impl->setMessageModel(messageModel);
|
||||
}
|
||||
|
||||
const std::string& DefaultMQPushConsumer::getNamesrvAddr() const {
|
||||
return impl->getNamesrvAddr();
|
||||
}
|
||||
|
||||
void DefaultMQPushConsumer::setNamesrvAddr(const std::string& namesrvAddr) {
|
||||
impl->setNamesrvAddr(namesrvAddr);
|
||||
}
|
||||
|
||||
const std::string& DefaultMQPushConsumer::getNamesrvDomain() const {
|
||||
return impl->getNamesrvDomain();
|
||||
}
|
||||
|
||||
void DefaultMQPushConsumer::setNamesrvDomain(const std::string& namesrvDomain) {
|
||||
impl->setNamesrvDomain(namesrvDomain);
|
||||
}
|
||||
void DefaultMQPushConsumer::setSessionCredentials(const std::string& accessKey,
|
||||
const std::string& secretKey,
|
||||
const std::string& accessChannel) {
|
||||
impl->setSessionCredentials(accessKey, secretKey, accessChannel);
|
||||
}
|
||||
|
||||
const SessionCredentials& DefaultMQPushConsumer::getSessionCredentials() const {
|
||||
return impl->getSessionCredentials();
|
||||
}
|
||||
const std::string& DefaultMQPushConsumer::getInstanceName() const {
|
||||
return impl->getInstanceName();
|
||||
}
|
||||
|
||||
void DefaultMQPushConsumer::setInstanceName(const std::string& instanceName) {
|
||||
impl->setInstanceName(instanceName);
|
||||
}
|
||||
|
||||
const std::string& DefaultMQPushConsumer::getNameSpace() const {
|
||||
return impl->getNameSpace();
|
||||
}
|
||||
|
||||
void DefaultMQPushConsumer::setNameSpace(const std::string& nameSpace) {
|
||||
impl->setNameSpace(nameSpace);
|
||||
}
|
||||
const std::string& DefaultMQPushConsumer::getGroupName() const {
|
||||
return impl->getGroupName();
|
||||
}
|
||||
|
||||
void DefaultMQPushConsumer::setGroupName(const std::string& groupName) {
|
||||
impl->setGroupName(groupName);
|
||||
}
|
||||
|
||||
void DefaultMQPushConsumer::setEnableSsl(bool enableSsl) {
|
||||
impl->setEnableSsl(enableSsl);
|
||||
}
|
||||
|
||||
bool DefaultMQPushConsumer::getEnableSsl() const {
|
||||
return impl->getEnableSsl();
|
||||
}
|
||||
|
||||
void DefaultMQPushConsumer::setSslPropertyFile(const std::string& sslPropertyFile) {
|
||||
impl->setSslPropertyFile(sslPropertyFile);
|
||||
}
|
||||
|
||||
const std::string& DefaultMQPushConsumer::getSslPropertyFile() const {
|
||||
return impl->getSslPropertyFile();
|
||||
}
|
||||
|
||||
void DefaultMQPushConsumer::setLogLevel(elogLevel inputLevel) {
|
||||
impl->setLogLevel(inputLevel);
|
||||
}
|
||||
|
||||
elogLevel DefaultMQPushConsumer::getLogLevel() {
|
||||
return impl->getLogLevel();
|
||||
}
|
||||
void DefaultMQPushConsumer::setLogFileSizeAndNum(int fileNum, long perFileSize) {
|
||||
impl->setLogFileSizeAndNum(fileNum, perFileSize);
|
||||
}
|
||||
|
||||
void DefaultMQPushConsumer::setUnitName(std::string unitName) {
|
||||
impl->setUnitName(unitName);
|
||||
}
|
||||
const std::string& DefaultMQPushConsumer::getUnitName() const {
|
||||
return impl->getUnitName();
|
||||
}
|
||||
|
||||
void DefaultMQPushConsumer::setTcpTransportPullThreadNum(int num) {
|
||||
impl->setTcpTransportPullThreadNum(num);
|
||||
}
|
||||
int DefaultMQPushConsumer::getTcpTransportPullThreadNum() const {
|
||||
return impl->getTcpTransportPullThreadNum();
|
||||
}
|
||||
|
||||
void DefaultMQPushConsumer::setTcpTransportConnectTimeout(uint64_t timeout) {
|
||||
impl->setTcpTransportConnectTimeout(timeout);
|
||||
}
|
||||
uint64_t DefaultMQPushConsumer::getTcpTransportConnectTimeout() const {
|
||||
return impl->getTcpTransportConnectTimeout();
|
||||
}
|
||||
void DefaultMQPushConsumer::setTcpTransportTryLockTimeout(uint64_t timeout) {
|
||||
impl->setTcpTransportTryLockTimeout(timeout);
|
||||
}
|
||||
uint64_t DefaultMQPushConsumer::getTcpTransportTryLockTimeout() const {
|
||||
return impl->getTcpTransportTryLockTimeout();
|
||||
}
|
||||
void DefaultMQPushConsumer::setAsyncPull(bool asyncFlag) {
|
||||
impl->setAsyncPull(asyncFlag);
|
||||
}
|
||||
void DefaultMQPushConsumer::setMessageTrace(bool messageTrace) {
|
||||
impl->setMessageTrace(messageTrace);
|
||||
}
|
||||
bool DefaultMQPushConsumer::getMessageTrace() const {
|
||||
return impl->getMessageTrace();
|
||||
}
|
||||
} // namespace rocketmq
|
||||
1172
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/DefaultMQPushConsumerImpl.cpp
vendored
Normal file
1172
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/DefaultMQPushConsumerImpl.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
185
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/DefaultMQPushConsumerImpl.h
vendored
Normal file
185
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/DefaultMQPushConsumerImpl.h
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __DEFAULTMQPUSHCONSUMERIMPL_H__
|
||||
#define __DEFAULTMQPUSHCONSUMERIMPL_H__
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <string>
|
||||
#include "AsyncCallback.h"
|
||||
#include "ConsumeMessageContext.h"
|
||||
#include "ConsumeMessageHook.h"
|
||||
#include "DefaultMQProducerImpl.h"
|
||||
#include "MQConsumer.h"
|
||||
#include "MQMessageListener.h"
|
||||
#include "MQMessageQueue.h"
|
||||
|
||||
namespace rocketmq {
|
||||
|
||||
class Rebalance;
|
||||
class SubscriptionData;
|
||||
class OffsetStore;
|
||||
class PullAPIWrapper;
|
||||
class PullRequest;
|
||||
class ConsumeMsgService;
|
||||
class TaskQueue;
|
||||
class TaskThread;
|
||||
class AsyncPullCallback;
|
||||
class ConsumerRunningInfo;
|
||||
//<!***************************************************************************
|
||||
class DefaultMQPushConsumerImpl : public MQConsumer {
|
||||
public:
|
||||
DefaultMQPushConsumerImpl();
|
||||
DefaultMQPushConsumerImpl(const std::string& groupname);
|
||||
void boost_asio_work();
|
||||
virtual ~DefaultMQPushConsumerImpl();
|
||||
|
||||
//<!begin mqadmin;
|
||||
virtual void start();
|
||||
virtual void shutdown();
|
||||
//<!end mqadmin;
|
||||
|
||||
//<!begin MQConsumer
|
||||
virtual bool sendMessageBack(MQMessageExt& msg, int delayLevel, std::string& brokerName);
|
||||
virtual void fetchSubscribeMessageQueues(const std::string& topic, std::vector<MQMessageQueue>& mqs);
|
||||
virtual void doRebalance();
|
||||
virtual void persistConsumerOffset();
|
||||
virtual void persistConsumerOffsetByResetOffset();
|
||||
virtual void updateTopicSubscribeInfo(const std::string& topic, std::vector<MQMessageQueue>& info);
|
||||
virtual ConsumeType getConsumeType();
|
||||
virtual ConsumeFromWhere getConsumeFromWhere();
|
||||
void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere);
|
||||
virtual void getSubscriptions(std::vector<SubscriptionData>&);
|
||||
virtual void updateConsumeOffset(const MQMessageQueue& mq, int64 offset);
|
||||
virtual void removeConsumeOffset(const MQMessageQueue& mq);
|
||||
virtual PullResult pull(const MQMessageQueue& mq, const std::string& subExpression, int64 offset, int maxNums) {
|
||||
return PullResult();
|
||||
}
|
||||
virtual void pull(const MQMessageQueue& mq,
|
||||
const std::string& subExpression,
|
||||
int64 offset,
|
||||
int maxNums,
|
||||
PullCallback* pPullCallback) {}
|
||||
virtual ConsumerRunningInfo* getConsumerRunningInfo();
|
||||
//<!end MQConsumer;
|
||||
|
||||
void registerMessageListener(MQMessageListener* pMessageListener);
|
||||
MessageListenerType getMessageListenerType();
|
||||
void subscribe(const std::string& topic, const std::string& subExpression);
|
||||
|
||||
OffsetStore* getOffsetStore() const;
|
||||
virtual Rebalance* getRebalance() const;
|
||||
ConsumeMsgService* getConsumerMsgService() const;
|
||||
|
||||
virtual bool producePullMsgTask(boost::weak_ptr<PullRequest>);
|
||||
virtual bool producePullMsgTaskLater(boost::weak_ptr<PullRequest>, int millis);
|
||||
static void static_triggerNextPullRequest(void* context,
|
||||
boost::asio::deadline_timer* t,
|
||||
boost::weak_ptr<PullRequest>);
|
||||
void triggerNextPullRequest(boost::asio::deadline_timer* t, boost::weak_ptr<PullRequest>);
|
||||
void runPullMsgQueue(TaskQueue* pTaskQueue);
|
||||
void pullMessage(boost::weak_ptr<PullRequest> pullrequest);
|
||||
void pullMessageAsync(boost::weak_ptr<PullRequest> pullrequest);
|
||||
void setAsyncPull(bool asyncFlag);
|
||||
AsyncPullCallback* getAsyncPullCallBack(boost::weak_ptr<PullRequest>, MQMessageQueue msgQueue);
|
||||
void shutdownAsyncPullCallBack();
|
||||
|
||||
/*
|
||||
for orderly consume, set the pull num of message size by each pullMsg,
|
||||
default value is 1;
|
||||
*/
|
||||
void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize);
|
||||
int getConsumeMessageBatchMaxSize() const;
|
||||
|
||||
/*
|
||||
set consuming thread count, default value is cpu cores
|
||||
*/
|
||||
void setConsumeThreadCount(int threadCount);
|
||||
int getConsumeThreadCount() const;
|
||||
void setMaxReconsumeTimes(int maxReconsumeTimes);
|
||||
int getMaxReconsumeTimes() const;
|
||||
|
||||
/*
|
||||
set pullMsg thread count, default value is cpu cores
|
||||
*/
|
||||
void setPullMsgThreadPoolCount(int threadCount);
|
||||
int getPullMsgThreadPoolCount() const;
|
||||
|
||||
/*
|
||||
set max cache msg size perQueue in memory if consumer could not consume msgs
|
||||
immediately
|
||||
default maxCacheMsgSize perQueue is 1000, set range is:1~65535
|
||||
*/
|
||||
void setMaxCacheMsgSizePerQueue(int maxCacheSize);
|
||||
int getMaxCacheMsgSizePerQueue() const;
|
||||
void submitSendTraceRequest(MQMessage& msg, SendCallback* pSendCallback);
|
||||
bool hasConsumeMessageHook();
|
||||
|
||||
void registerConsumeMessageHook(std::shared_ptr<ConsumeMessageHook>& hook);
|
||||
void setDefaultMqProducerImpl(DefaultMQProducerImpl* DefaultMqProducerImpl);
|
||||
void executeConsumeMessageHookBefore(ConsumeMessageContext* context);
|
||||
void executeConsumeMessageHookAfter(ConsumeMessageContext* context);
|
||||
|
||||
private:
|
||||
void checkConfig();
|
||||
void copySubscription();
|
||||
void updateTopicSubscribeInfoWhenSubscriptionChanged();
|
||||
bool dealWithNameSpace();
|
||||
void logConfigs();
|
||||
|
||||
bool dealWithMessageTrace();
|
||||
void createMessageTraceInnerProducer();
|
||||
void shutdownMessageTraceInnerProducer();
|
||||
|
||||
private:
|
||||
uint64_t m_startTime;
|
||||
ConsumeFromWhere m_consumeFromWhere;
|
||||
std::map<std::string, std::string> m_subTopics;
|
||||
int m_consumeThreadCount;
|
||||
OffsetStore* m_pOffsetStore;
|
||||
Rebalance* m_pRebalance;
|
||||
PullAPIWrapper* m_pPullAPIWrapper;
|
||||
ConsumeMsgService* m_consumerService;
|
||||
MQMessageListener* m_pMessageListener;
|
||||
int m_consumeMessageBatchMaxSize;
|
||||
int m_maxMsgCacheSize;
|
||||
int m_maxReconsumeTimes = -1;
|
||||
boost::asio::io_service m_async_ioService;
|
||||
boost::scoped_ptr<boost::thread> m_async_service_thread;
|
||||
|
||||
typedef std::map<MQMessageQueue, AsyncPullCallback*> PullMAP;
|
||||
PullMAP m_PullCallback;
|
||||
bool m_asyncPull;
|
||||
int m_asyncPullTimeout;
|
||||
int m_pullMsgThreadPoolNum;
|
||||
|
||||
private:
|
||||
TaskQueue* m_pullmsgQueue;
|
||||
std::unique_ptr<boost::thread> m_pullmsgThread;
|
||||
|
||||
// used for trace
|
||||
std::vector<std::shared_ptr<ConsumeMessageHook> > m_consumeMessageHookList;
|
||||
std::shared_ptr<DefaultMQProducerImpl> m_DefaultMQProducerImpl;
|
||||
};
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
32
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/FindBrokerResult.h
vendored
Normal file
32
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/FindBrokerResult.h
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __FINDBROKERRESULT_H__
|
||||
#define __FINDBROKERRESULT_H__
|
||||
|
||||
namespace rocketmq {
|
||||
//<!************************************************************************
|
||||
struct FindBrokerResult {
|
||||
FindBrokerResult(const std::string& sbrokerAddr, bool bslave) : brokerAddr(sbrokerAddr), slave(bslave) {}
|
||||
|
||||
public:
|
||||
std::string brokerAddr;
|
||||
bool slave;
|
||||
};
|
||||
} // namespace rocketmq
|
||||
|
||||
#endif
|
||||
343
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/OffsetStore.cpp
vendored
Normal file
343
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/OffsetStore.cpp
vendored
Normal file
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "OffsetStore.h"
|
||||
#include "Logging.h"
|
||||
#include "MQClientFactory.h"
|
||||
#include "MessageQueue.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/archive/binary_iarchive.hpp>
|
||||
#include <boost/archive/binary_oarchive.hpp>
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/serialization/map.hpp>
|
||||
namespace rocketmq {
|
||||
|
||||
//<!***************************************************************************
|
||||
OffsetStore::OffsetStore(const string& groupName, MQClientFactory* pfactory)
|
||||
: m_groupName(groupName), m_pClientFactory(pfactory) {}
|
||||
|
||||
OffsetStore::~OffsetStore() {
|
||||
m_pClientFactory = NULL;
|
||||
m_offsetTable.clear();
|
||||
}
|
||||
|
||||
//<!***************************************************************************
|
||||
LocalFileOffsetStore::LocalFileOffsetStore(const string& groupName, MQClientFactory* pfactory)
|
||||
: OffsetStore(groupName, pfactory) {
|
||||
MQConsumer* pConsumer = pfactory->selectConsumer(groupName);
|
||||
if (pConsumer) {
|
||||
LOG_INFO("new LocalFileOffsetStore");
|
||||
string directoryName = UtilAll::getLocalAddress() + "@" + pConsumer->getInstanceName();
|
||||
m_storePath = ".rocketmq_offsets/" + directoryName + "/" + groupName;
|
||||
string homeDir(UtilAll::getHomeDirectory());
|
||||
m_storeFile = homeDir + "/" + m_storePath + "/offsets.Json";
|
||||
|
||||
string storePath(homeDir);
|
||||
storePath.append("/").append(m_storePath);
|
||||
boost::filesystem::path dir(storePath);
|
||||
boost::system::error_code ec;
|
||||
if (!boost::filesystem::exists(dir, ec)) {
|
||||
if (!boost::filesystem::create_directories(dir, ec)) {
|
||||
LOG_ERROR("create offset store dir:%s error", storePath.c_str());
|
||||
string errorMsg("create offset store dir fail: ");
|
||||
errorMsg.append(storePath);
|
||||
THROW_MQEXCEPTION(MQClientException, errorMsg, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LocalFileOffsetStore::~LocalFileOffsetStore() {}
|
||||
|
||||
void LocalFileOffsetStore::load() {
|
||||
std::ifstream ifs(m_storeFile.c_str(), std::ios::in);
|
||||
if (ifs.good()) {
|
||||
if (ifs.is_open()) {
|
||||
if (ifs.peek() != std::ifstream::traits_type::eof()) {
|
||||
map<string, int64> m_offsetTable_tmp;
|
||||
boost::system::error_code e;
|
||||
try {
|
||||
boost::archive::text_iarchive ia(ifs);
|
||||
ia >> m_offsetTable_tmp;
|
||||
} catch (...) {
|
||||
LOG_ERROR(
|
||||
"load offset store file failed, please check whether file: %s is "
|
||||
"cleared by operator, if so, delete this offsets.Json file and "
|
||||
"then restart consumer",
|
||||
m_storeFile.c_str());
|
||||
ifs.close();
|
||||
string errorMsg("load offset store file: ");
|
||||
errorMsg.append(m_storeFile)
|
||||
.append(
|
||||
" failed, please check whether offsets.Json is cleared by "
|
||||
"operator, if so, delete this offsets.Json file and then "
|
||||
"restart consumer");
|
||||
THROW_MQEXCEPTION(MQClientException, errorMsg, -1);
|
||||
}
|
||||
ifs.close();
|
||||
|
||||
for (map<string, int64>::iterator it = m_offsetTable_tmp.begin(); it != m_offsetTable_tmp.end(); ++it) {
|
||||
// LOG_INFO("it->first:%s, it->second:%lld", it->first.c_str(),
|
||||
// it->second);
|
||||
Json::Reader reader;
|
||||
Json::Value object;
|
||||
reader.parse(it->first.c_str(), object);
|
||||
MQMessageQueue mq(object["topic"].asString(), object["brokerName"].asString(), object["queueId"].asInt());
|
||||
updateOffset(mq, it->second);
|
||||
}
|
||||
m_offsetTable_tmp.clear();
|
||||
} else {
|
||||
LOG_ERROR(
|
||||
"open offset store file failed, please check whether file: %s is "
|
||||
"cleared by operator, if so, delete this offsets.Json file and "
|
||||
"then restart consumer",
|
||||
m_storeFile.c_str());
|
||||
THROW_MQEXCEPTION(MQClientException,
|
||||
"open offset store file failed, please check whether "
|
||||
"offsets.Json is cleared by operator, if so, delete "
|
||||
"this offsets.Json file and then restart consumer",
|
||||
-1);
|
||||
}
|
||||
} else {
|
||||
LOG_ERROR(
|
||||
"open offset store file failed, please check whether file:%s is "
|
||||
"deleted by operator and then restart consumer",
|
||||
m_storeFile.c_str());
|
||||
THROW_MQEXCEPTION(MQClientException,
|
||||
"open offset store file failed, please check "
|
||||
"directory:%s is deleted by operator or offset.Json "
|
||||
"file is cleared by operator, and then restart "
|
||||
"consumer",
|
||||
-1);
|
||||
}
|
||||
} else {
|
||||
LOG_WARN(
|
||||
"offsets.Json file not exist, maybe this is the first time "
|
||||
"consumation");
|
||||
}
|
||||
}
|
||||
|
||||
void LocalFileOffsetStore::updateOffset(const MQMessageQueue& mq, int64 offset) {
|
||||
boost::lock_guard<boost::mutex> lock(m_lock);
|
||||
m_offsetTable[mq] = offset;
|
||||
}
|
||||
|
||||
int64 LocalFileOffsetStore::readOffset(const MQMessageQueue& mq,
|
||||
ReadOffsetType type,
|
||||
const SessionCredentials& session_credentials) {
|
||||
switch (type) {
|
||||
case MEMORY_FIRST_THEN_STORE:
|
||||
case READ_FROM_MEMORY: {
|
||||
boost::lock_guard<boost::mutex> lock(m_lock);
|
||||
MQ2OFFSET::iterator it = m_offsetTable.find(mq);
|
||||
if (it != m_offsetTable.end()) {
|
||||
return it->second;
|
||||
} else if (READ_FROM_MEMORY == type) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
case READ_FROM_STORE: {
|
||||
try {
|
||||
load();
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("catch exception when load local file");
|
||||
return -1;
|
||||
}
|
||||
boost::lock_guard<boost::mutex> lock(m_lock);
|
||||
MQ2OFFSET::iterator it = m_offsetTable.find(mq);
|
||||
if (it != m_offsetTable.end()) {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
LOG_ERROR("can not readOffset from offsetStore.json, maybe first time consumation");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void LocalFileOffsetStore::persist(const MQMessageQueue& mq, const SessionCredentials& session_credentials) {}
|
||||
|
||||
void LocalFileOffsetStore::persistAll(const std::vector<MQMessageQueue>& mqs) {
|
||||
boost::lock_guard<boost::mutex> lock(m_lock);
|
||||
|
||||
map<string, int64> m_offsetTable_tmp;
|
||||
vector<MQMessageQueue>::const_iterator it = mqs.begin();
|
||||
for (; it != mqs.end(); ++it) {
|
||||
MessageQueue mq_tmp((*it).getTopic(), (*it).getBrokerName(), (*it).getQueueId());
|
||||
string mqKey = mq_tmp.toJson().toStyledString();
|
||||
m_offsetTable_tmp[mqKey] = m_offsetTable[*it];
|
||||
}
|
||||
|
||||
std::ofstream s;
|
||||
string storefile_bak(m_storeFile);
|
||||
storefile_bak.append(".bak");
|
||||
s.open(storefile_bak.c_str(), std::ios::out);
|
||||
if (s.is_open()) {
|
||||
try {
|
||||
boost::archive::text_oarchive oa(s);
|
||||
// Boost is nervous that archiving non-const class instances which might
|
||||
// cause a problem with object tracking if different tracked objects use
|
||||
// the same address.
|
||||
oa << const_cast<const map<string, int64>&>(m_offsetTable_tmp);
|
||||
} catch (...) {
|
||||
LOG_ERROR("persist offset store file:%s failed", m_storeFile.c_str());
|
||||
s.close();
|
||||
THROW_MQEXCEPTION(MQClientException, "persistAll:open offset store file failed", -1);
|
||||
}
|
||||
s.close();
|
||||
if (!UtilAll::ReplaceFile(storefile_bak, m_storeFile))
|
||||
LOG_ERROR("could not rename bak file:%s", strerror(errno));
|
||||
m_offsetTable_tmp.clear();
|
||||
} else {
|
||||
LOG_ERROR("open offset store file:%s failed", m_storeFile.c_str());
|
||||
m_offsetTable_tmp.clear();
|
||||
THROW_MQEXCEPTION(MQClientException, "persistAll:open offset store file failed", -1);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalFileOffsetStore::removeOffset(const MQMessageQueue& mq) {}
|
||||
|
||||
//<!***************************************************************************
|
||||
RemoteBrokerOffsetStore::RemoteBrokerOffsetStore(const string& groupName, MQClientFactory* pfactory)
|
||||
: OffsetStore(groupName, pfactory) {}
|
||||
|
||||
RemoteBrokerOffsetStore::~RemoteBrokerOffsetStore() {}
|
||||
|
||||
void RemoteBrokerOffsetStore::load() {}
|
||||
|
||||
void RemoteBrokerOffsetStore::updateOffset(const MQMessageQueue& mq, int64 offset) {
|
||||
boost::lock_guard<boost::mutex> lock(m_lock);
|
||||
m_offsetTable[mq] = offset;
|
||||
}
|
||||
|
||||
int64 RemoteBrokerOffsetStore::readOffset(const MQMessageQueue& mq,
|
||||
ReadOffsetType type,
|
||||
const SessionCredentials& session_credentials) {
|
||||
switch (type) {
|
||||
case MEMORY_FIRST_THEN_STORE:
|
||||
case READ_FROM_MEMORY: {
|
||||
boost::lock_guard<boost::mutex> lock(m_lock);
|
||||
|
||||
MQ2OFFSET::iterator it = m_offsetTable.find(mq);
|
||||
if (it != m_offsetTable.end()) {
|
||||
return it->second;
|
||||
} else if (READ_FROM_MEMORY == type) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
case READ_FROM_STORE: {
|
||||
try {
|
||||
int64 brokerOffset = fetchConsumeOffsetFromBroker(mq, session_credentials);
|
||||
//<!update;
|
||||
updateOffset(mq, brokerOffset);
|
||||
return brokerOffset;
|
||||
} catch (MQBrokerException& e) {
|
||||
LOG_ERROR("%s", e.what());
|
||||
return -1;
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("%s", e.what());
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void RemoteBrokerOffsetStore::persist(const MQMessageQueue& mq, const SessionCredentials& session_credentials) {
|
||||
MQ2OFFSET offsetTable;
|
||||
{
|
||||
boost::lock_guard<boost::mutex> lock(m_lock);
|
||||
offsetTable = m_offsetTable;
|
||||
}
|
||||
|
||||
MQ2OFFSET::iterator it = offsetTable.find(mq);
|
||||
if (it != offsetTable.end()) {
|
||||
try {
|
||||
updateConsumeOffsetToBroker(mq, it->second, session_credentials);
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("updateConsumeOffsetToBroker %s ,offset:[%lld] error", mq.toString().c_str(), it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteBrokerOffsetStore::persistAll(const std::vector<MQMessageQueue>& mq) {}
|
||||
|
||||
void RemoteBrokerOffsetStore::removeOffset(const MQMessageQueue& mq) {
|
||||
boost::lock_guard<boost::mutex> lock(m_lock);
|
||||
if (m_offsetTable.find(mq) != m_offsetTable.end())
|
||||
m_offsetTable.erase(mq);
|
||||
}
|
||||
|
||||
void RemoteBrokerOffsetStore::updateConsumeOffsetToBroker(const MQMessageQueue& mq,
|
||||
int64 offset,
|
||||
const SessionCredentials& session_credentials) {
|
||||
unique_ptr<FindBrokerResult> pFindBrokerResult(m_pClientFactory->findBrokerAddressInAdmin(mq.getBrokerName()));
|
||||
|
||||
if (pFindBrokerResult == NULL) {
|
||||
m_pClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic(), session_credentials);
|
||||
pFindBrokerResult.reset(m_pClientFactory->findBrokerAddressInAdmin(mq.getBrokerName()));
|
||||
}
|
||||
|
||||
if (pFindBrokerResult != NULL) {
|
||||
UpdateConsumerOffsetRequestHeader* pRequestHeader = new UpdateConsumerOffsetRequestHeader();
|
||||
pRequestHeader->topic = mq.getTopic();
|
||||
pRequestHeader->consumerGroup = m_groupName;
|
||||
pRequestHeader->queueId = mq.getQueueId();
|
||||
pRequestHeader->commitOffset = offset;
|
||||
|
||||
try {
|
||||
LOG_INFO("oneway updateConsumeOffsetToBroker of mq:%s, its offset is:%lld", mq.toString().c_str(), offset);
|
||||
return m_pClientFactory->getMQClientAPIImpl()->updateConsumerOffsetOneway(
|
||||
pFindBrokerResult->brokerAddr, pRequestHeader, 1000 * 5, session_credentials);
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("%s", e.what());
|
||||
}
|
||||
}
|
||||
LOG_WARN("The broker not exist");
|
||||
}
|
||||
|
||||
int64 RemoteBrokerOffsetStore::fetchConsumeOffsetFromBroker(const MQMessageQueue& mq,
|
||||
const SessionCredentials& session_credentials) {
|
||||
unique_ptr<FindBrokerResult> pFindBrokerResult(m_pClientFactory->findBrokerAddressInAdmin(mq.getBrokerName()));
|
||||
|
||||
if (pFindBrokerResult == NULL) {
|
||||
m_pClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic(), session_credentials);
|
||||
pFindBrokerResult.reset(m_pClientFactory->findBrokerAddressInAdmin(mq.getBrokerName()));
|
||||
}
|
||||
|
||||
if (pFindBrokerResult != NULL) {
|
||||
QueryConsumerOffsetRequestHeader* pRequestHeader = new QueryConsumerOffsetRequestHeader();
|
||||
pRequestHeader->topic = mq.getTopic();
|
||||
pRequestHeader->consumerGroup = m_groupName;
|
||||
pRequestHeader->queueId = mq.getQueueId();
|
||||
|
||||
return m_pClientFactory->getMQClientAPIImpl()->queryConsumerOffset(pFindBrokerResult->brokerAddr, pRequestHeader,
|
||||
1000 * 5, session_credentials);
|
||||
} else {
|
||||
LOG_ERROR("The broker not exist when fetchConsumeOffsetFromBroker");
|
||||
THROW_MQEXCEPTION(MQClientException, "The broker not exist", -1);
|
||||
}
|
||||
}
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
106
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/OffsetStore.h
vendored
Normal file
106
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/OffsetStore.h
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __OFFSETSTORE_H__
|
||||
#define __OFFSETSTORE_H__
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <map>
|
||||
#include "MQMessageQueue.h"
|
||||
#include "SessionCredentials.h"
|
||||
|
||||
namespace rocketmq {
|
||||
class MQClientFactory;
|
||||
//<!***************************************************************************
|
||||
enum ReadOffsetType {
|
||||
// read offset from memory
|
||||
READ_FROM_MEMORY,
|
||||
// read offset from remoting
|
||||
READ_FROM_STORE,
|
||||
// read offset from memory firstly, then from remoting
|
||||
MEMORY_FIRST_THEN_STORE,
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
class OffsetStore {
|
||||
public:
|
||||
OffsetStore(const std::string& groupName, MQClientFactory*);
|
||||
virtual ~OffsetStore();
|
||||
|
||||
virtual void load() = 0;
|
||||
virtual void updateOffset(const MQMessageQueue& mq, int64 offset) = 0;
|
||||
virtual int64 readOffset(const MQMessageQueue& mq,
|
||||
ReadOffsetType type,
|
||||
const SessionCredentials& session_credentials) = 0;
|
||||
virtual void persist(const MQMessageQueue& mq, const SessionCredentials& session_credentials) = 0;
|
||||
virtual void persistAll(const std::vector<MQMessageQueue>& mq) = 0;
|
||||
virtual void removeOffset(const MQMessageQueue& mq) = 0;
|
||||
|
||||
protected:
|
||||
std::string m_groupName;
|
||||
typedef std::map<MQMessageQueue, int64> MQ2OFFSET;
|
||||
MQ2OFFSET m_offsetTable;
|
||||
MQClientFactory* m_pClientFactory;
|
||||
boost::mutex m_lock;
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
class LocalFileOffsetStore : public OffsetStore {
|
||||
public:
|
||||
LocalFileOffsetStore(const std::string& groupName, MQClientFactory*);
|
||||
virtual ~LocalFileOffsetStore();
|
||||
|
||||
virtual void load();
|
||||
virtual void updateOffset(const MQMessageQueue& mq, int64 offset);
|
||||
virtual int64 readOffset(const MQMessageQueue& mq,
|
||||
ReadOffsetType type,
|
||||
const SessionCredentials& session_credentials);
|
||||
virtual void persist(const MQMessageQueue& mq, const SessionCredentials& session_credentials);
|
||||
virtual void persistAll(const std::vector<MQMessageQueue>& mq);
|
||||
virtual void removeOffset(const MQMessageQueue& mq);
|
||||
|
||||
private:
|
||||
std::string m_storePath;
|
||||
std::string m_storeFile;
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
class RemoteBrokerOffsetStore : public OffsetStore {
|
||||
public:
|
||||
RemoteBrokerOffsetStore(const std::string& groupName, MQClientFactory*);
|
||||
virtual ~RemoteBrokerOffsetStore();
|
||||
|
||||
virtual void load();
|
||||
virtual void updateOffset(const MQMessageQueue& mq, int64 offset);
|
||||
virtual int64 readOffset(const MQMessageQueue& mq,
|
||||
ReadOffsetType type,
|
||||
const SessionCredentials& session_credentials);
|
||||
virtual void persist(const MQMessageQueue& mq, const SessionCredentials& session_credentials);
|
||||
virtual void persistAll(const std::vector<MQMessageQueue>& mq);
|
||||
virtual void removeOffset(const MQMessageQueue& mq);
|
||||
|
||||
private:
|
||||
void updateConsumeOffsetToBroker(const MQMessageQueue& mq,
|
||||
int64 offset,
|
||||
const SessionCredentials& session_credentials);
|
||||
int64 fetchConsumeOffsetFromBroker(const MQMessageQueue& mq, const SessionCredentials& session_credentials);
|
||||
};
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
|
||||
#endif
|
||||
133
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/PullAPIWrapper.cpp
vendored
Normal file
133
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/PullAPIWrapper.cpp
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "PullAPIWrapper.h"
|
||||
#include "CommunicationMode.h"
|
||||
#include "MQClientFactory.h"
|
||||
#include "PullResultExt.h"
|
||||
#include "PullSysFlag.h"
|
||||
namespace rocketmq {
|
||||
//<!************************************************************************
|
||||
PullAPIWrapper::PullAPIWrapper(MQClientFactory* mQClientFactory, const string& consumerGroup) {
|
||||
m_MQClientFactory = mQClientFactory;
|
||||
m_consumerGroup = consumerGroup;
|
||||
}
|
||||
|
||||
PullAPIWrapper::~PullAPIWrapper() {
|
||||
m_MQClientFactory = NULL;
|
||||
m_pullFromWhichNodeTable.clear();
|
||||
}
|
||||
|
||||
void PullAPIWrapper::updatePullFromWhichNode(const MQMessageQueue& mq, int brokerId) {
|
||||
boost::lock_guard<boost::mutex> lock(m_lock);
|
||||
m_pullFromWhichNodeTable[mq] = brokerId;
|
||||
}
|
||||
|
||||
int PullAPIWrapper::recalculatePullFromWhichNode(const MQMessageQueue& mq) {
|
||||
boost::lock_guard<boost::mutex> lock(m_lock);
|
||||
if (m_pullFromWhichNodeTable.find(mq) != m_pullFromWhichNodeTable.end()) {
|
||||
return m_pullFromWhichNodeTable[mq];
|
||||
}
|
||||
return MASTER_ID;
|
||||
}
|
||||
|
||||
PullResult PullAPIWrapper::processPullResult(const MQMessageQueue& mq,
|
||||
PullResult* pullResult,
|
||||
SubscriptionData* subscriptionData) {
|
||||
PullResultExt* pResultExt = static_cast<PullResultExt*>(pullResult);
|
||||
if (pResultExt == NULL) {
|
||||
string errMsg("The pullResult NULL of");
|
||||
errMsg.append(mq.toString());
|
||||
THROW_MQEXCEPTION(MQClientException, errMsg, -1);
|
||||
}
|
||||
|
||||
//<!update;
|
||||
updatePullFromWhichNode(mq, pResultExt->suggestWhichBrokerId);
|
||||
|
||||
vector<MQMessageExt> msgFilterList;
|
||||
if (pResultExt->pullStatus == FOUND) {
|
||||
//<!decode all msg list;
|
||||
vector<MQMessageExt> msgAllList;
|
||||
MQDecoder::decodes(&pResultExt->msgMemBlock, msgAllList);
|
||||
|
||||
//<!filter msg list again;
|
||||
if (subscriptionData != NULL && !subscriptionData->getTagsSet().empty()) {
|
||||
msgFilterList.reserve(msgAllList.size());
|
||||
vector<MQMessageExt>::iterator it = msgAllList.begin();
|
||||
for (; it != msgAllList.end(); ++it) {
|
||||
string msgTag = (*it).getTags();
|
||||
if (subscriptionData->containTag(msgTag)) {
|
||||
msgFilterList.push_back(*it);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
msgFilterList.swap(msgAllList);
|
||||
}
|
||||
}
|
||||
|
||||
return PullResult(pResultExt->pullStatus, pResultExt->nextBeginOffset, pResultExt->minOffset, pResultExt->maxOffset,
|
||||
msgFilterList);
|
||||
}
|
||||
|
||||
PullResult* PullAPIWrapper::pullKernelImpl(const MQMessageQueue& mq, // 1
|
||||
string subExpression, // 2
|
||||
int64 subVersion, // 3
|
||||
int64 offset, // 4
|
||||
int maxNums, // 5
|
||||
int sysFlag, // 6
|
||||
int64 commitOffset, // 7
|
||||
int brokerSuspendMaxTimeMillis, // 8
|
||||
int timeoutMillis, // 9
|
||||
int communicationMode, // 10
|
||||
PullCallback* pullCallback,
|
||||
const SessionCredentials& session_credentials,
|
||||
void* pArg /*= NULL*/) {
|
||||
unique_ptr<FindBrokerResult> pFindBrokerResult(
|
||||
m_MQClientFactory->findBrokerAddressInSubscribe(mq.getBrokerName(), recalculatePullFromWhichNode(mq), false));
|
||||
//<!goto nameserver;
|
||||
if (pFindBrokerResult == NULL) {
|
||||
m_MQClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic(), session_credentials);
|
||||
pFindBrokerResult.reset(
|
||||
m_MQClientFactory->findBrokerAddressInSubscribe(mq.getBrokerName(), recalculatePullFromWhichNode(mq), false));
|
||||
}
|
||||
|
||||
if (pFindBrokerResult != NULL) {
|
||||
int sysFlagInner = sysFlag;
|
||||
|
||||
if (pFindBrokerResult->slave) {
|
||||
sysFlagInner = PullSysFlag::clearCommitOffsetFlag(sysFlagInner);
|
||||
}
|
||||
|
||||
PullMessageRequestHeader* pRequestHeader = new PullMessageRequestHeader();
|
||||
pRequestHeader->consumerGroup = m_consumerGroup;
|
||||
pRequestHeader->topic = mq.getTopic();
|
||||
pRequestHeader->queueId = mq.getQueueId();
|
||||
pRequestHeader->queueOffset = offset;
|
||||
pRequestHeader->maxMsgNums = maxNums;
|
||||
pRequestHeader->sysFlag = sysFlagInner;
|
||||
pRequestHeader->commitOffset = commitOffset;
|
||||
pRequestHeader->suspendTimeoutMillis = brokerSuspendMaxTimeMillis;
|
||||
pRequestHeader->subscription = subExpression;
|
||||
pRequestHeader->subVersion = subVersion;
|
||||
|
||||
return m_MQClientFactory->getMQClientAPIImpl()->pullMessage(pFindBrokerResult->brokerAddr, pRequestHeader,
|
||||
timeoutMillis, communicationMode, pullCallback, pArg,
|
||||
session_credentials);
|
||||
}
|
||||
THROW_MQEXCEPTION(MQClientException, "The broker not exist", -1);
|
||||
}
|
||||
|
||||
} // namespace rocketmq
|
||||
66
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/PullAPIWrapper.h
vendored
Normal file
66
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/PullAPIWrapper.h
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef _PULLAPIWRAPPER_H_
|
||||
#define _PULLAPIWRAPPER_H_
|
||||
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include "AsyncCallback.h"
|
||||
#include "MQMessageQueue.h"
|
||||
#include "SessionCredentials.h"
|
||||
#include "SubscriptionData.h"
|
||||
|
||||
namespace rocketmq {
|
||||
class MQClientFactory;
|
||||
//<!***************************************************************************
|
||||
class PullAPIWrapper {
|
||||
public:
|
||||
PullAPIWrapper(MQClientFactory* mQClientFactory, const string& consumerGroup);
|
||||
~PullAPIWrapper();
|
||||
|
||||
PullResult processPullResult(const MQMessageQueue& mq, PullResult* pullResult, SubscriptionData* subscriptionData);
|
||||
|
||||
PullResult* pullKernelImpl(const MQMessageQueue& mq, // 1
|
||||
string subExpression, // 2
|
||||
int64 subVersion, // 3
|
||||
int64 offset, // 4
|
||||
int maxNums, // 5
|
||||
int sysFlag, // 6
|
||||
int64 commitOffset, // 7
|
||||
int brokerSuspendMaxTimeMillis, // 8
|
||||
int timeoutMillis, // 9
|
||||
int communicationMode, // 10
|
||||
PullCallback* pullCallback,
|
||||
const SessionCredentials& session_credentials,
|
||||
void* pArg = NULL);
|
||||
|
||||
private:
|
||||
void updatePullFromWhichNode(const MQMessageQueue& mq, int brokerId);
|
||||
|
||||
int recalculatePullFromWhichNode(const MQMessageQueue& mq);
|
||||
|
||||
private:
|
||||
MQClientFactory* m_MQClientFactory;
|
||||
string m_consumerGroup;
|
||||
boost::mutex m_lock;
|
||||
map<MQMessageQueue, int /* brokerId */> m_pullFromWhichNodeTable;
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
|
||||
#endif //<! _PULLAPIWRAPPER_H_
|
||||
278
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/PullRequest.cpp
vendored
Normal file
278
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/PullRequest.cpp
vendored
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "PullRequest.h"
|
||||
#include "Logging.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
const uint64 PullRequest::RebalanceLockInterval = 20 * 1000;
|
||||
const uint64 PullRequest::RebalanceLockMaxLiveTime = 30 * 1000;
|
||||
/**
|
||||
* If the process queue has not been pulled for more than MAX_PULL_IDLE_TIME, we need to mark it as dropped
|
||||
* default 120s
|
||||
*/
|
||||
const uint64 PullRequest::MAX_PULL_IDLE_TIME = 120 * 1000;
|
||||
|
||||
PullRequest::PullRequest(const string& groupname)
|
||||
: m_groupname(groupname), m_nextOffset(0), m_queueOffsetMax(0), m_bDropped(false), m_bLocked(false) {
|
||||
m_lastLockTimestamp = UtilAll::currentTimeMillis();
|
||||
m_lastPullTimestamp = UtilAll::currentTimeMillis();
|
||||
m_lastConsumeTimestamp = UtilAll::currentTimeMillis();
|
||||
}
|
||||
|
||||
PullRequest::~PullRequest() {
|
||||
m_msgTreeMapTemp.clear();
|
||||
m_msgTreeMap.clear();
|
||||
}
|
||||
|
||||
PullRequest& PullRequest::operator=(const PullRequest& other) {
|
||||
boost::lock_guard<boost::mutex> lock(m_pullRequestLock);
|
||||
if (this != &other) {
|
||||
m_groupname = other.m_groupname;
|
||||
m_nextOffset = other.m_nextOffset;
|
||||
m_bDropped.store(other.m_bDropped.load());
|
||||
m_queueOffsetMax = other.m_queueOffsetMax;
|
||||
m_messageQueue = other.m_messageQueue;
|
||||
m_msgTreeMap = other.m_msgTreeMap;
|
||||
m_msgTreeMapTemp = other.m_msgTreeMapTemp;
|
||||
m_lastPullTimestamp = other.m_lastPullTimestamp;
|
||||
m_lastConsumeTimestamp = other.m_lastConsumeTimestamp;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void PullRequest::putMessage(vector<MQMessageExt>& msgs) {
|
||||
boost::lock_guard<boost::mutex> lock(m_pullRequestLock);
|
||||
|
||||
vector<MQMessageExt>::iterator it = msgs.begin();
|
||||
for (; it != msgs.end(); it++) {
|
||||
m_msgTreeMap[it->getQueueOffset()] = *it;
|
||||
m_queueOffsetMax = (std::max)(m_queueOffsetMax, it->getQueueOffset());
|
||||
}
|
||||
LOG_DEBUG("PullRequest: putMessage m_queueOffsetMax:%lld ", m_queueOffsetMax);
|
||||
}
|
||||
|
||||
void PullRequest::getMessage(vector<MQMessageExt>& msgs) {
|
||||
boost::lock_guard<boost::mutex> lock(m_pullRequestLock);
|
||||
|
||||
map<int64, MQMessageExt>::iterator it = m_msgTreeMap.begin();
|
||||
for (; it != m_msgTreeMap.end(); it++) {
|
||||
msgs.push_back(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
int64 PullRequest::getCacheMinOffset() {
|
||||
boost::lock_guard<boost::mutex> lock(m_pullRequestLock);
|
||||
if (m_msgTreeMap.empty()) {
|
||||
return 0;
|
||||
} else {
|
||||
map<int64, MQMessageExt>::iterator it = m_msgTreeMap.begin();
|
||||
MQMessageExt msg = it->second;
|
||||
return msg.getQueueOffset();
|
||||
}
|
||||
}
|
||||
|
||||
int64 PullRequest::getCacheMaxOffset() {
|
||||
return m_queueOffsetMax;
|
||||
}
|
||||
|
||||
int PullRequest::getCacheMsgCount() {
|
||||
boost::lock_guard<boost::mutex> lock(m_pullRequestLock);
|
||||
return m_msgTreeMap.size();
|
||||
}
|
||||
|
||||
void PullRequest::getMessageByQueueOffset(vector<MQMessageExt>& msgs, int64 minQueueOffset, int64 maxQueueOffset) {
|
||||
boost::lock_guard<boost::mutex> lock(m_pullRequestLock);
|
||||
|
||||
int64 it = minQueueOffset;
|
||||
for (; it <= maxQueueOffset; it++) {
|
||||
msgs.push_back(m_msgTreeMap[it]);
|
||||
}
|
||||
}
|
||||
|
||||
int64 PullRequest::removeMessage(vector<MQMessageExt>& msgs) {
|
||||
boost::lock_guard<boost::mutex> lock(m_pullRequestLock);
|
||||
|
||||
int64 result = -1;
|
||||
LOG_DEBUG("m_queueOffsetMax is:%lld", m_queueOffsetMax);
|
||||
if (!m_msgTreeMap.empty()) {
|
||||
result = m_queueOffsetMax + 1;
|
||||
LOG_DEBUG(" offset result is:%lld, m_queueOffsetMax is:%lld, msgs size:" SIZET_FMT "", result, m_queueOffsetMax,
|
||||
msgs.size());
|
||||
vector<MQMessageExt>::iterator it = msgs.begin();
|
||||
for (; it != msgs.end(); it++) {
|
||||
LOG_DEBUG("remove these msg from m_msgTreeMap, its offset:%lld", it->getQueueOffset());
|
||||
m_msgTreeMap.erase(it->getQueueOffset());
|
||||
}
|
||||
|
||||
if (!m_msgTreeMap.empty()) {
|
||||
map<int64, MQMessageExt>::iterator it = m_msgTreeMap.begin();
|
||||
result = it->first;
|
||||
LOG_INFO("cache msg size:" SIZET_FMT " of pullRequest:%s, return offset result is:%lld", m_msgTreeMap.size(),
|
||||
m_messageQueue.toString().c_str(), result);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PullRequest::clearAllMsgs() {
|
||||
boost::lock_guard<boost::mutex> lock(m_pullRequestLock);
|
||||
|
||||
if (isDropped()) {
|
||||
LOG_DEBUG("clear m_msgTreeMap as PullRequest had been dropped.");
|
||||
m_msgTreeMap.clear();
|
||||
m_msgTreeMapTemp.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void PullRequest::updateQueueMaxOffset(int64 queueOffset) {
|
||||
// following 2 cases which may set queueOffset smaller than m_queueOffsetMax:
|
||||
// 1. resetOffset cmd
|
||||
// 2. during rebalance, if configured with CONSUMER_FROM_FIRST_OFFSET, when
|
||||
// readOffset called by computePullFromWhere was failed, m_nextOffset will be
|
||||
// setted to 0
|
||||
m_queueOffsetMax = queueOffset;
|
||||
}
|
||||
|
||||
void PullRequest::setDropped(bool dropped) {
|
||||
int temp = (dropped == true ? 1 : 0);
|
||||
m_bDropped.store(temp);
|
||||
/*
|
||||
m_queueOffsetMax = 0;
|
||||
m_nextOffset = 0;
|
||||
//the reason why not clear m_queueOffsetMax and m_nextOffset is due to
|
||||
ConsumeMsgService and drop mq are concurrent running.
|
||||
consider following situation:
|
||||
1>. ConsumeMsgService running
|
||||
2>. dorebalance, drop mq, reset m_nextOffset and m_queueOffsetMax
|
||||
3>. ConsumeMsgService calls removeMessages, if no other msgs in
|
||||
m_msgTreeMap, m_queueOffsetMax(0)+1 will return;
|
||||
4>. updateOffset with 1, which is more smaller than correct offset.
|
||||
*/
|
||||
}
|
||||
|
||||
bool PullRequest::isDropped() const {
|
||||
return m_bDropped.load() == 1;
|
||||
}
|
||||
|
||||
int64 PullRequest::getNextOffset() {
|
||||
boost::lock_guard<boost::mutex> lock(m_pullRequestLock);
|
||||
return m_nextOffset;
|
||||
}
|
||||
|
||||
void PullRequest::setLocked(bool Locked) {
|
||||
int temp = (Locked == true ? 1 : 0);
|
||||
m_bLocked.store(temp);
|
||||
}
|
||||
|
||||
bool PullRequest::isLocked() const {
|
||||
return m_bLocked.load() == 1;
|
||||
}
|
||||
|
||||
bool PullRequest::isLockExpired() const {
|
||||
return (UtilAll::currentTimeMillis() - m_lastLockTimestamp) > RebalanceLockMaxLiveTime;
|
||||
}
|
||||
|
||||
void PullRequest::setLastLockTimestamp(int64 time) {
|
||||
m_lastLockTimestamp = time;
|
||||
}
|
||||
|
||||
int64 PullRequest::getLastLockTimestamp() const {
|
||||
return m_lastLockTimestamp;
|
||||
}
|
||||
|
||||
void PullRequest::setLastPullTimestamp(uint64 time) {
|
||||
m_lastPullTimestamp = time;
|
||||
}
|
||||
|
||||
uint64 PullRequest::getLastPullTimestamp() const {
|
||||
return m_lastPullTimestamp;
|
||||
}
|
||||
|
||||
bool PullRequest::isPullRequestExpired() const {
|
||||
uint64 interval = m_lastPullTimestamp + MAX_PULL_IDLE_TIME;
|
||||
if (interval <= UtilAll::currentTimeMillis()) {
|
||||
LOG_WARN("PullRequest for [%s] has been expired %lld ms,m_lastPullTimestamp = %lld ms",
|
||||
m_messageQueue.toString().c_str(), UtilAll::currentTimeMillis() - interval, m_lastPullTimestamp);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PullRequest::setLastConsumeTimestamp(uint64 time) {
|
||||
m_lastConsumeTimestamp = time;
|
||||
}
|
||||
|
||||
uint64 PullRequest::getLastConsumeTimestamp() const {
|
||||
return m_lastConsumeTimestamp;
|
||||
}
|
||||
|
||||
void PullRequest::setTryUnlockTimes(int time) {
|
||||
m_lastLockTimestamp = time;
|
||||
}
|
||||
|
||||
int PullRequest::getTryUnlockTimes() const {
|
||||
return m_lastLockTimestamp;
|
||||
}
|
||||
|
||||
void PullRequest::setNextOffset(int64 nextoffset) {
|
||||
boost::lock_guard<boost::mutex> lock(m_pullRequestLock);
|
||||
m_nextOffset = nextoffset;
|
||||
}
|
||||
|
||||
string PullRequest::getGroupName() const {
|
||||
return m_groupname;
|
||||
}
|
||||
|
||||
boost::timed_mutex& PullRequest::getPullRequestCriticalSection() {
|
||||
return m_consumeLock;
|
||||
}
|
||||
|
||||
void PullRequest::takeMessages(vector<MQMessageExt>& msgs, int batchSize) {
|
||||
boost::lock_guard<boost::mutex> lock(m_pullRequestLock);
|
||||
for (int i = 0; i != batchSize; i++) {
|
||||
map<int64, MQMessageExt>::iterator it = m_msgTreeMap.begin();
|
||||
if (it != m_msgTreeMap.end()) {
|
||||
msgs.push_back(it->second);
|
||||
m_msgTreeMapTemp[it->first] = it->second;
|
||||
m_msgTreeMap.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PullRequest::makeMessageToCosumeAgain(vector<MQMessageExt>& msgs) {
|
||||
boost::lock_guard<boost::mutex> lock(m_pullRequestLock);
|
||||
for (unsigned int it = 0; it != msgs.size(); ++it) {
|
||||
m_msgTreeMap[msgs[it].getQueueOffset()] = msgs[it];
|
||||
m_msgTreeMapTemp.erase(msgs[it].getQueueOffset());
|
||||
}
|
||||
}
|
||||
|
||||
int64 PullRequest::commit() {
|
||||
boost::lock_guard<boost::mutex> lock(m_pullRequestLock);
|
||||
if (!m_msgTreeMapTemp.empty()) {
|
||||
int64 offset = (--m_msgTreeMapTemp.end())->first;
|
||||
m_msgTreeMapTemp.clear();
|
||||
return offset + 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
101
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/PullRequest.h
vendored
Normal file
101
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/PullRequest.h
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __PULLREQUEST_H__
|
||||
#define __PULLREQUEST_H__
|
||||
|
||||
#include <boost/atomic.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include "MQMessageExt.h"
|
||||
#include "MQMessageQueue.h"
|
||||
#include "UtilAll.h"
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
class PullRequest {
|
||||
public:
|
||||
PullRequest(const string& groupname);
|
||||
virtual ~PullRequest();
|
||||
|
||||
void putMessage(vector<MQMessageExt>& msgs);
|
||||
void getMessage(vector<MQMessageExt>& msgs);
|
||||
int64 getCacheMinOffset();
|
||||
int64 getCacheMaxOffset();
|
||||
int getCacheMsgCount();
|
||||
void getMessageByQueueOffset(vector<MQMessageExt>& msgs, int64 minQueueOffset, int64 maxQueueOffset);
|
||||
int64 removeMessage(vector<MQMessageExt>& msgs);
|
||||
void clearAllMsgs();
|
||||
|
||||
PullRequest& operator=(const PullRequest& other);
|
||||
|
||||
void setDropped(bool dropped);
|
||||
bool isDropped() const;
|
||||
|
||||
int64 getNextOffset();
|
||||
void setNextOffset(int64 nextoffset);
|
||||
|
||||
string getGroupName() const;
|
||||
|
||||
void updateQueueMaxOffset(int64 queueOffset);
|
||||
|
||||
void setLocked(bool Locked);
|
||||
bool isLocked() const;
|
||||
bool isLockExpired() const;
|
||||
void setLastLockTimestamp(int64 time);
|
||||
int64 getLastLockTimestamp() const;
|
||||
void setLastPullTimestamp(uint64 time);
|
||||
uint64 getLastPullTimestamp() const;
|
||||
bool isPullRequestExpired() const;
|
||||
void setLastConsumeTimestamp(uint64 time);
|
||||
uint64 getLastConsumeTimestamp() const;
|
||||
void setTryUnlockTimes(int time);
|
||||
int getTryUnlockTimes() const;
|
||||
void takeMessages(vector<MQMessageExt>& msgs, int batchSize);
|
||||
int64 commit();
|
||||
void makeMessageToCosumeAgain(vector<MQMessageExt>& msgs);
|
||||
boost::timed_mutex& getPullRequestCriticalSection();
|
||||
bool removePullMsgEvent(bool force = false);
|
||||
bool addPullMsgEvent();
|
||||
/**
|
||||
* Check if there is an in-flight pull request.
|
||||
*/
|
||||
bool hasInFlightPullRequest() const;
|
||||
|
||||
public:
|
||||
MQMessageQueue m_messageQueue;
|
||||
static const uint64 RebalanceLockInterval; // ms
|
||||
static const uint64 RebalanceLockMaxLiveTime; // ms
|
||||
static const uint64 MAX_PULL_IDLE_TIME; // ms
|
||||
|
||||
private:
|
||||
string m_groupname;
|
||||
int64 m_nextOffset;
|
||||
int64 m_queueOffsetMax;
|
||||
boost::atomic<bool> m_bDropped;
|
||||
boost::atomic<bool> m_bLocked;
|
||||
map<int64, MQMessageExt> m_msgTreeMap;
|
||||
map<int64, MQMessageExt> m_msgTreeMapTemp;
|
||||
boost::mutex m_pullRequestLock;
|
||||
uint64 m_lastLockTimestamp; // ms
|
||||
// uint64 m_tryUnlockTimes;
|
||||
uint64 m_lastPullTimestamp;
|
||||
uint64 m_lastConsumeTimestamp;
|
||||
boost::timed_mutex m_consumeLock;
|
||||
};
|
||||
//<!************************************************************************
|
||||
} // namespace rocketmq
|
||||
|
||||
#endif
|
||||
46
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/PullResult.cpp
vendored
Normal file
46
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/PullResult.cpp
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "PullResult.h"
|
||||
#include "UtilAll.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!************************************************************************
|
||||
PullResult::PullResult() : pullStatus(NO_MATCHED_MSG), nextBeginOffset(0), minOffset(0), maxOffset(0) {}
|
||||
|
||||
PullResult::PullResult(PullStatus status) : pullStatus(status), nextBeginOffset(0), minOffset(0), maxOffset(0) {}
|
||||
|
||||
PullResult::PullResult(PullStatus pullStatus, int64 nextBeginOffset, int64 minOffset, int64 maxOffset)
|
||||
: pullStatus(pullStatus), nextBeginOffset(nextBeginOffset), minOffset(minOffset), maxOffset(maxOffset) {}
|
||||
|
||||
PullResult::PullResult(PullStatus pullStatus,
|
||||
int64 nextBeginOffset,
|
||||
int64 minOffset,
|
||||
int64 maxOffset,
|
||||
const vector<MQMessageExt>& src)
|
||||
: pullStatus(pullStatus), nextBeginOffset(nextBeginOffset), minOffset(minOffset), maxOffset(maxOffset) {
|
||||
msgFoundList.reserve(src.size());
|
||||
for (size_t i = 0; i < src.size(); i++) {
|
||||
msgFoundList.push_back(src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
PullResult::~PullResult() {
|
||||
msgFoundList.clear();
|
||||
}
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
62
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/PullResultExt.h
vendored
Normal file
62
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/PullResultExt.h
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "PullResult.h"
|
||||
#include "UtilAll.h"
|
||||
#include "dataBlock.h"
|
||||
|
||||
namespace rocketmq {
|
||||
/**
|
||||
* use internal only
|
||||
*/
|
||||
//<!***************************************************************************
|
||||
class PullResultExt : public PullResult {
|
||||
public:
|
||||
PullResultExt(PullStatus pullStatus,
|
||||
int64 nextBeginOffset,
|
||||
int64 minOffset,
|
||||
int64 maxOffset,
|
||||
int suggestWhichBrokerId,
|
||||
const MemoryBlock& messageBinary)
|
||||
: PullResult(pullStatus, nextBeginOffset, minOffset, maxOffset),
|
||||
suggestWhichBrokerId(suggestWhichBrokerId),
|
||||
msgMemBlock(messageBinary) {}
|
||||
|
||||
PullResultExt(PullStatus pullStatus,
|
||||
int64 nextBeginOffset,
|
||||
int64 minOffset,
|
||||
int64 maxOffset,
|
||||
int suggestWhichBrokerId,
|
||||
MemoryBlock&& messageBinary)
|
||||
: PullResult(pullStatus, nextBeginOffset, minOffset, maxOffset),
|
||||
suggestWhichBrokerId(suggestWhichBrokerId),
|
||||
msgMemBlock(std::forward<MemoryBlock>(messageBinary)) {}
|
||||
|
||||
PullResultExt(PullStatus pullStatus,
|
||||
int64 nextBeginOffset,
|
||||
int64 minOffset,
|
||||
int64 maxOffset,
|
||||
int suggestWhichBrokerId)
|
||||
: PullResult(pullStatus, nextBeginOffset, minOffset, maxOffset), suggestWhichBrokerId(suggestWhichBrokerId) {}
|
||||
|
||||
virtual ~PullResultExt() {}
|
||||
|
||||
public:
|
||||
int suggestWhichBrokerId;
|
||||
MemoryBlock msgMemBlock;
|
||||
};
|
||||
|
||||
} // namespace rocketmq
|
||||
658
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/Rebalance.cpp
vendored
Normal file
658
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/Rebalance.cpp
vendored
Normal file
@@ -0,0 +1,658 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "Rebalance.h"
|
||||
#include "DefaultMQPushConsumerImpl.h"
|
||||
#include "LockBatchBody.h"
|
||||
#include "Logging.h"
|
||||
#include "MQClientAPIImpl.h"
|
||||
#include "MQClientFactory.h"
|
||||
#include "OffsetStore.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!************************************************************************
|
||||
Rebalance::Rebalance(MQConsumer* consumer, MQClientFactory* pfactory)
|
||||
: m_pConsumer(consumer), m_pClientFactory(pfactory) {
|
||||
m_pAllocateMQStrategy = new AllocateMQAveragely();
|
||||
}
|
||||
|
||||
Rebalance::~Rebalance() {
|
||||
{
|
||||
map<string, SubscriptionData*>::iterator it = m_subscriptionData.begin();
|
||||
for (; it != m_subscriptionData.end(); ++it) {
|
||||
deleteAndZero(it->second);
|
||||
}
|
||||
m_subscriptionData.clear();
|
||||
}
|
||||
{
|
||||
/*
|
||||
MQ2PULLREQ::iterator it = m_requestQueueTable.begin();
|
||||
for (; it != m_requestQueueTable.end(); ++it) {
|
||||
delete it->second;
|
||||
it->second = NULL;
|
||||
}
|
||||
m_requestQueueTable.clear();*/
|
||||
}
|
||||
m_topicSubscribeInfoTable.clear();
|
||||
m_pConsumer = NULL;
|
||||
m_pClientFactory = NULL;
|
||||
deleteAndZero(m_pAllocateMQStrategy);
|
||||
}
|
||||
|
||||
void Rebalance::doRebalance() {
|
||||
LOG_DEBUG("start doRebalance");
|
||||
try {
|
||||
map<string, SubscriptionData*>::iterator it = m_subscriptionData.begin();
|
||||
for (; it != m_subscriptionData.end(); ++it) {
|
||||
string topic = (it->first);
|
||||
LOG_DEBUG("current topic is:%s", topic.c_str());
|
||||
//<!topic -> mqs
|
||||
vector<MQMessageQueue> mqAll;
|
||||
if (!getTopicSubscribeInfo(topic, mqAll)) {
|
||||
continue;
|
||||
}
|
||||
if (mqAll.empty()) {
|
||||
if (!UtilAll::startsWith_retry(topic)) {
|
||||
std::string msg("#doRebalance. mqAll for topic:");
|
||||
msg.append(topic);
|
||||
msg.append(" is empty");
|
||||
LOG_ERROR("Queues to allocate are empty. Msg: %s", msg.c_str());
|
||||
// to check, return error or throw exception
|
||||
THROW_MQEXCEPTION(MQClientException, msg, -1);
|
||||
}
|
||||
}
|
||||
|
||||
//<!msg model;
|
||||
switch (m_pConsumer->getMessageModel()) {
|
||||
case BROADCASTING: {
|
||||
bool changed = updateRequestTableInRebalance(topic, mqAll);
|
||||
if (changed) {
|
||||
messageQueueChanged(topic, mqAll, mqAll);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CLUSTERING: {
|
||||
vector<string> cidAll;
|
||||
m_pClientFactory->findConsumerIds(topic, m_pConsumer->getGroupName(), cidAll,
|
||||
m_pConsumer->getSessionCredentials());
|
||||
|
||||
if (cidAll.empty()) {
|
||||
LOG_ERROR("[ERROR] Get empty consumer IDs. Consumer Group: %s, Topic: %s",
|
||||
m_pConsumer->getGroupName().c_str(), topic.c_str());
|
||||
// Should skip this round of re-balance immediately if consumer ID set is empty.
|
||||
THROW_MQEXCEPTION(MQClientException, "doRebalance the cidAll is empty", -1);
|
||||
}
|
||||
// log
|
||||
for (int i = 0; i < (int)cidAll.size(); ++i) {
|
||||
LOG_DEBUG("client id:%s of topic:%s", cidAll[i].c_str(), topic.c_str());
|
||||
}
|
||||
//<! sort;
|
||||
sort(mqAll.begin(), mqAll.end());
|
||||
sort(cidAll.begin(), cidAll.end());
|
||||
|
||||
//<! allocate;
|
||||
vector<MQMessageQueue> allocateResult;
|
||||
try {
|
||||
m_pAllocateMQStrategy->allocate(m_pConsumer->getMQClientId(), mqAll, cidAll, allocateResult);
|
||||
} catch (MQException& e) {
|
||||
std::string errMsg("Allocate message queue for ConsumerGroup[");
|
||||
errMsg.append(m_pConsumer->getGroupName());
|
||||
errMsg.append("],Topic[");
|
||||
errMsg.append(topic);
|
||||
errMsg.append("] failed. ");
|
||||
LOG_ERROR("%s", errMsg.c_str());
|
||||
THROW_MQEXCEPTION(MQClientException, errMsg, -1);
|
||||
}
|
||||
|
||||
// log
|
||||
for (int i = 0; i < (int)allocateResult.size(); ++i) {
|
||||
LOG_DEBUG("allocate mq:%s", allocateResult[i].toString().c_str());
|
||||
}
|
||||
|
||||
//<!update local;
|
||||
bool changed = updateRequestTableInRebalance(topic, allocateResult);
|
||||
if (changed) {
|
||||
std::stringstream ss;
|
||||
ss << "Allocation result for [Consumer Group: " << m_pConsumer->getGroupName() << ", Topic: " << topic
|
||||
<< ", Current Consumer ID: " << m_pConsumer->getMQClientId() << "] is changed.\n"
|
||||
<< "Total Queue :#" << mqAll.size() << ", Total Consumer :#" << cidAll.size()
|
||||
<< ", Allocated Queues are: \n";
|
||||
|
||||
for (vector<MQMessageQueue>::size_type i = 0; i < allocateResult.size(); ++i) {
|
||||
ss << allocateResult[i].toString() << "\n";
|
||||
}
|
||||
// Log allocation result.
|
||||
LOG_INFO("%s", ss.str().c_str());
|
||||
|
||||
messageQueueChanged(topic, mqAll, allocateResult);
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("%s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void Rebalance::persistConsumerOffset() {
|
||||
DefaultMQPushConsumerImpl* pConsumer = static_cast<DefaultMQPushConsumerImpl*>(m_pConsumer);
|
||||
OffsetStore* pOffsetStore = pConsumer->getOffsetStore();
|
||||
vector<MQMessageQueue> mqs;
|
||||
{
|
||||
boost::lock_guard<boost::mutex> lock(m_requestTableMutex);
|
||||
MQ2PULLREQ::iterator it = m_requestQueueTable.begin();
|
||||
for (; it != m_requestQueueTable.end(); ++it) {
|
||||
if (it->second && (!it->second->isDropped())) {
|
||||
mqs.push_back(it->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pConsumer->getMessageModel() == BROADCASTING) {
|
||||
pOffsetStore->persistAll(mqs);
|
||||
} else {
|
||||
vector<MQMessageQueue>::iterator it2 = mqs.begin();
|
||||
for (; it2 != mqs.end(); ++it2) {
|
||||
pOffsetStore->persist(*it2, m_pConsumer->getSessionCredentials());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Rebalance::persistConsumerOffsetByResetOffset() {
|
||||
DefaultMQPushConsumerImpl* pConsumer = static_cast<DefaultMQPushConsumerImpl*>(m_pConsumer);
|
||||
OffsetStore* pOffsetStore = pConsumer->getOffsetStore();
|
||||
vector<MQMessageQueue> mqs;
|
||||
{
|
||||
boost::lock_guard<boost::mutex> lock(m_requestTableMutex);
|
||||
MQ2PULLREQ::iterator it = m_requestQueueTable.begin();
|
||||
for (; it != m_requestQueueTable.end(); ++it) {
|
||||
if (it->second) { // even if it was dropped, also need update offset when
|
||||
// rcv resetOffset cmd
|
||||
mqs.push_back(it->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
vector<MQMessageQueue>::iterator it2 = mqs.begin();
|
||||
for (; it2 != mqs.end(); ++it2) {
|
||||
pOffsetStore->persist(*it2, m_pConsumer->getSessionCredentials());
|
||||
}
|
||||
}
|
||||
|
||||
SubscriptionData* Rebalance::getSubscriptionData(const string& topic) {
|
||||
if (m_subscriptionData.find(topic) != m_subscriptionData.end()) {
|
||||
return m_subscriptionData[topic];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
map<string, SubscriptionData*>& Rebalance::getSubscriptionInner() {
|
||||
return m_subscriptionData;
|
||||
}
|
||||
|
||||
void Rebalance::setSubscriptionData(const string& topic, SubscriptionData* pdata) {
|
||||
if (pdata != NULL && m_subscriptionData.find(topic) == m_subscriptionData.end())
|
||||
m_subscriptionData[topic] = pdata;
|
||||
}
|
||||
|
||||
void Rebalance::setTopicSubscribeInfo(const string& topic, vector<MQMessageQueue>& mqs) {
|
||||
if (m_subscriptionData.find(topic) != m_subscriptionData.end()) {
|
||||
{
|
||||
boost::lock_guard<boost::mutex> lock(m_topicSubscribeInfoTableMutex);
|
||||
if (m_topicSubscribeInfoTable.find(topic) != m_topicSubscribeInfoTable.end())
|
||||
m_topicSubscribeInfoTable.erase(topic);
|
||||
m_topicSubscribeInfoTable[topic] = mqs;
|
||||
}
|
||||
// log
|
||||
vector<MQMessageQueue>::iterator it = mqs.begin();
|
||||
for (; it != mqs.end(); ++it) {
|
||||
LOG_DEBUG("topic [%s] has :%s", topic.c_str(), (*it).toString().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Rebalance::getTopicSubscribeInfo(const string& topic, vector<MQMessageQueue>& mqs) {
|
||||
boost::lock_guard<boost::mutex> lock(m_topicSubscribeInfoTableMutex);
|
||||
if (m_topicSubscribeInfoTable.find(topic) != m_topicSubscribeInfoTable.end()) {
|
||||
mqs = m_topicSubscribeInfoTable[topic];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Rebalance::addPullRequest(MQMessageQueue mq, boost::shared_ptr<PullRequest> pPullRequest) {
|
||||
boost::lock_guard<boost::mutex> lock(m_requestTableMutex);
|
||||
m_requestQueueTable[mq] = pPullRequest;
|
||||
}
|
||||
|
||||
void Rebalance::removePullRequest(MQMessageQueue mq) {
|
||||
boost::lock_guard<boost::mutex> lock(m_requestTableMutex);
|
||||
if (m_requestQueueTable.find(mq) != m_requestQueueTable.end()) {
|
||||
m_requestQueueTable.erase(mq);
|
||||
}
|
||||
}
|
||||
bool Rebalance::isPullRequestExist(MQMessageQueue mq) {
|
||||
boost::lock_guard<boost::mutex> lock(m_requestTableMutex);
|
||||
if (m_requestQueueTable.find(mq) != m_requestQueueTable.end()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
boost::weak_ptr<PullRequest> Rebalance::getPullRequest(MQMessageQueue mq) {
|
||||
boost::lock_guard<boost::mutex> lock(m_requestTableMutex);
|
||||
if (m_requestQueueTable.find(mq) != m_requestQueueTable.end()) {
|
||||
return m_requestQueueTable[mq];
|
||||
}
|
||||
return boost::weak_ptr<PullRequest>();
|
||||
}
|
||||
|
||||
map<MQMessageQueue, boost::shared_ptr<PullRequest>> Rebalance::getPullRequestTable() {
|
||||
boost::lock_guard<boost::mutex> lock(m_requestTableMutex);
|
||||
return m_requestQueueTable;
|
||||
}
|
||||
|
||||
void Rebalance::unlockAll(bool oneWay) {
|
||||
map<string, vector<MQMessageQueue>*> brokerMqs;
|
||||
MQ2PULLREQ requestQueueTable = getPullRequestTable();
|
||||
for (MQ2PULLREQ::iterator it = requestQueueTable.begin(); it != requestQueueTable.end(); ++it) {
|
||||
if (!(it->second->isDropped())) {
|
||||
if (brokerMqs.find(it->first.getBrokerName()) == brokerMqs.end()) {
|
||||
vector<MQMessageQueue>* mqs = new vector<MQMessageQueue>;
|
||||
brokerMqs[it->first.getBrokerName()] = mqs;
|
||||
} else {
|
||||
brokerMqs[it->first.getBrokerName()]->push_back(it->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG_INFO("unLockAll " SIZET_FMT " broker mqs", brokerMqs.size());
|
||||
for (map<string, vector<MQMessageQueue>*>::iterator itb = brokerMqs.begin(); itb != brokerMqs.end(); ++itb) {
|
||||
unique_ptr<FindBrokerResult> pFindBrokerResult(
|
||||
m_pClientFactory->findBrokerAddressInSubscribe(itb->first, MASTER_ID, true));
|
||||
if (!pFindBrokerResult) {
|
||||
LOG_ERROR("unlockAll findBrokerAddressInSubscribe ret null for broker:%s", itb->first.data());
|
||||
continue;
|
||||
}
|
||||
unique_ptr<UnlockBatchRequestBody> unlockBatchRequest(new UnlockBatchRequestBody());
|
||||
vector<MQMessageQueue> mqs(*(itb->second));
|
||||
unlockBatchRequest->setClientId(m_pConsumer->getMQClientId());
|
||||
unlockBatchRequest->setConsumerGroup(m_pConsumer->getGroupName());
|
||||
unlockBatchRequest->setMqSet(mqs);
|
||||
|
||||
try {
|
||||
m_pClientFactory->getMQClientAPIImpl()->unlockBatchMQ(pFindBrokerResult->brokerAddr, unlockBatchRequest.get(),
|
||||
1000, m_pConsumer->getSessionCredentials());
|
||||
for (unsigned int i = 0; i != mqs.size(); ++i) {
|
||||
boost::weak_ptr<PullRequest> pullreq = getPullRequest(mqs[i]);
|
||||
if (!pullreq.expired()) {
|
||||
LOG_INFO("unlockBatchMQ success of mq:%s", mqs[i].toString().c_str());
|
||||
pullreq.lock()->setLocked(false);
|
||||
} else {
|
||||
LOG_ERROR("unlockBatchMQ fails of mq:%s", mqs[i].toString().c_str());
|
||||
}
|
||||
}
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("unlockBatchMQ fails");
|
||||
}
|
||||
deleteAndZero(itb->second);
|
||||
}
|
||||
brokerMqs.clear();
|
||||
}
|
||||
|
||||
void Rebalance::unlock(MQMessageQueue mq) {
|
||||
unique_ptr<FindBrokerResult> pFindBrokerResult(
|
||||
m_pClientFactory->findBrokerAddressInSubscribe(mq.getBrokerName(), MASTER_ID, true));
|
||||
if (!pFindBrokerResult) {
|
||||
LOG_ERROR("unlock findBrokerAddressInSubscribe ret null for broker:%s", mq.getBrokerName().data());
|
||||
return;
|
||||
}
|
||||
unique_ptr<UnlockBatchRequestBody> unlockBatchRequest(new UnlockBatchRequestBody());
|
||||
vector<MQMessageQueue> mqs;
|
||||
mqs.push_back(mq);
|
||||
unlockBatchRequest->setClientId(m_pConsumer->getMQClientId());
|
||||
unlockBatchRequest->setConsumerGroup(m_pConsumer->getGroupName());
|
||||
unlockBatchRequest->setMqSet(mqs);
|
||||
|
||||
try {
|
||||
m_pClientFactory->getMQClientAPIImpl()->unlockBatchMQ(pFindBrokerResult->brokerAddr, unlockBatchRequest.get(), 1000,
|
||||
m_pConsumer->getSessionCredentials());
|
||||
for (unsigned int i = 0; i != mqs.size(); ++i) {
|
||||
boost::weak_ptr<PullRequest> pullreq = getPullRequest(mqs[i]);
|
||||
if (!pullreq.expired()) {
|
||||
LOG_INFO("unlock success of mq:%s", mqs[i].toString().c_str());
|
||||
pullreq.lock()->setLocked(false);
|
||||
} else {
|
||||
LOG_ERROR("unlock fails of mq:%s", mqs[i].toString().c_str());
|
||||
}
|
||||
}
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("unlock fails of mq:%s", mq.toString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void Rebalance::lockAll() {
|
||||
map<string, vector<MQMessageQueue>*> brokerMqs;
|
||||
MQ2PULLREQ requestQueueTable = getPullRequestTable();
|
||||
for (MQ2PULLREQ::iterator it = requestQueueTable.begin(); it != requestQueueTable.end(); ++it) {
|
||||
if (!(it->second->isDropped())) {
|
||||
string brokerKey = it->first.getBrokerName() + it->first.getTopic();
|
||||
if (brokerMqs.find(brokerKey) == brokerMqs.end()) {
|
||||
vector<MQMessageQueue>* mqs = new vector<MQMessageQueue>;
|
||||
brokerMqs[brokerKey] = mqs;
|
||||
brokerMqs[brokerKey]->push_back(it->first);
|
||||
} else {
|
||||
brokerMqs[brokerKey]->push_back(it->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG_INFO("LockAll " SIZET_FMT " broker mqs", brokerMqs.size());
|
||||
for (map<string, vector<MQMessageQueue>*>::iterator itb = brokerMqs.begin(); itb != brokerMqs.end(); ++itb) {
|
||||
string brokerName = (*(itb->second))[0].getBrokerName();
|
||||
unique_ptr<FindBrokerResult> pFindBrokerResult(
|
||||
m_pClientFactory->findBrokerAddressInSubscribe(brokerName, MASTER_ID, true));
|
||||
if (!pFindBrokerResult) {
|
||||
LOG_ERROR("lockAll findBrokerAddressInSubscribe ret null for broker:%s", brokerName.data());
|
||||
continue;
|
||||
}
|
||||
unique_ptr<LockBatchRequestBody> lockBatchRequest(new LockBatchRequestBody());
|
||||
lockBatchRequest->setClientId(m_pConsumer->getMQClientId());
|
||||
lockBatchRequest->setConsumerGroup(m_pConsumer->getGroupName());
|
||||
lockBatchRequest->setMqSet(*(itb->second));
|
||||
LOG_INFO("try to lock:" SIZET_FMT " mqs of broker:%s", itb->second->size(), itb->first.c_str());
|
||||
try {
|
||||
vector<MQMessageQueue> messageQueues;
|
||||
m_pClientFactory->getMQClientAPIImpl()->lockBatchMQ(pFindBrokerResult->brokerAddr, lockBatchRequest.get(),
|
||||
messageQueues, 1000, m_pConsumer->getSessionCredentials());
|
||||
for (unsigned int i = 0; i != messageQueues.size(); ++i) {
|
||||
boost::weak_ptr<PullRequest> pullreq = getPullRequest(messageQueues[i]);
|
||||
if (!pullreq.expired()) {
|
||||
LOG_INFO("lockBatchMQ success of mq:%s", messageQueues[i].toString().c_str());
|
||||
pullreq.lock()->setLocked(true);
|
||||
pullreq.lock()->setLastLockTimestamp(UtilAll::currentTimeMillis());
|
||||
} else {
|
||||
LOG_ERROR("lockBatchMQ fails of mq:%s", messageQueues[i].toString().c_str());
|
||||
}
|
||||
}
|
||||
messageQueues.clear();
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("lockBatchMQ fails");
|
||||
}
|
||||
deleteAndZero(itb->second);
|
||||
}
|
||||
brokerMqs.clear();
|
||||
}
|
||||
|
||||
bool Rebalance::lock(MQMessageQueue mq) {
|
||||
unique_ptr<FindBrokerResult> pFindBrokerResult(
|
||||
m_pClientFactory->findBrokerAddressInSubscribe(mq.getBrokerName(), MASTER_ID, true));
|
||||
if (!pFindBrokerResult) {
|
||||
LOG_ERROR("lock findBrokerAddressInSubscribe ret null for broker:%s", mq.getBrokerName().data());
|
||||
return false;
|
||||
}
|
||||
unique_ptr<LockBatchRequestBody> lockBatchRequest(new LockBatchRequestBody());
|
||||
lockBatchRequest->setClientId(m_pConsumer->getMQClientId());
|
||||
lockBatchRequest->setConsumerGroup(m_pConsumer->getGroupName());
|
||||
vector<MQMessageQueue> in_mqSet;
|
||||
in_mqSet.push_back(mq);
|
||||
lockBatchRequest->setMqSet(in_mqSet);
|
||||
bool lockResult = false;
|
||||
|
||||
try {
|
||||
vector<MQMessageQueue> messageQueues;
|
||||
LOG_DEBUG("try to lock mq:%s", mq.toString().c_str());
|
||||
m_pClientFactory->getMQClientAPIImpl()->lockBatchMQ(pFindBrokerResult->brokerAddr, lockBatchRequest.get(),
|
||||
messageQueues, 1000, m_pConsumer->getSessionCredentials());
|
||||
if (messageQueues.size() == 0) {
|
||||
LOG_ERROR("lock mq on broker:%s failed", pFindBrokerResult->brokerAddr.c_str());
|
||||
return false;
|
||||
}
|
||||
for (unsigned int i = 0; i != messageQueues.size(); ++i) {
|
||||
boost::weak_ptr<PullRequest> pullreq = getPullRequest(messageQueues[i]);
|
||||
if (!pullreq.expired()) {
|
||||
LOG_INFO("lock success of mq:%s", messageQueues[i].toString().c_str());
|
||||
pullreq.lock()->setLocked(true);
|
||||
pullreq.lock()->setLastLockTimestamp(UtilAll::currentTimeMillis());
|
||||
lockResult = true;
|
||||
} else {
|
||||
LOG_ERROR("lock fails of mq:%s", messageQueues[i].toString().c_str());
|
||||
}
|
||||
}
|
||||
messageQueues.clear();
|
||||
return lockResult;
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("lock fails of mq:%s", mq.toString().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//<!************************************************************************
|
||||
RebalancePull::RebalancePull(MQConsumer* consumer, MQClientFactory* pfactory) : Rebalance(consumer, pfactory) {}
|
||||
|
||||
bool RebalancePull::updateRequestTableInRebalance(const string& topic, vector<MQMessageQueue>& mqsSelf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int64 RebalancePull::computePullFromWhere(const MQMessageQueue& mq) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RebalancePull::messageQueueChanged(const string& topic,
|
||||
vector<MQMessageQueue>& mqAll,
|
||||
vector<MQMessageQueue>& mqDivided) {}
|
||||
|
||||
void RebalancePull::removeUnnecessaryMessageQueue(const MQMessageQueue& mq) {}
|
||||
|
||||
//<!***************************************************************************
|
||||
RebalancePush::RebalancePush(MQConsumer* consumer, MQClientFactory* pfactory) : Rebalance(consumer, pfactory) {}
|
||||
|
||||
bool RebalancePush::updateRequestTableInRebalance(const string& topic, vector<MQMessageQueue>& mqsSelf) {
|
||||
LOG_DEBUG("updateRequestTableInRebalance for Topic[%s] Enter", topic.c_str());
|
||||
|
||||
// 1. Clear no in charge of
|
||||
// 1. set dropped
|
||||
// 2. clear local message
|
||||
// 3. clear offset
|
||||
// 4. remove request table
|
||||
// 5. set flag for route changed
|
||||
// 2. Check and clear dropped/invalid pullrequest(timeout and so on)
|
||||
// 3. Add new mq in charge of
|
||||
// 1. new pullrequest
|
||||
// 2. init next pull offset
|
||||
// 3. int offset
|
||||
// 4. add request table
|
||||
// 5. set flag for route changed
|
||||
// 4. Start long pull for request
|
||||
if (mqsSelf.empty()) {
|
||||
LOG_WARN("allocated queue is empty for topic:%s", topic.c_str());
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
|
||||
//<!remove none responsive mq
|
||||
MQ2PULLREQ requestQueueTable(getPullRequestTable());
|
||||
MQ2PULLREQ::iterator itDel = requestQueueTable.begin();
|
||||
for (; itDel != requestQueueTable.end(); ++itDel) {
|
||||
MQMessageQueue mqtemp = itDel->first;
|
||||
if (mqtemp.getTopic().compare(topic) == 0) {
|
||||
if (mqsSelf.empty() || (std::find(mqsSelf.begin(), mqsSelf.end(), mqtemp) == mqsSelf.end())) {
|
||||
// if not response , set to dropped
|
||||
LOG_INFO("Drop mq:%s,because not responsive", mqtemp.toString().c_str());
|
||||
itDel->second->setDropped(true);
|
||||
// remove offset table to avoid offset backup
|
||||
removeUnnecessaryMessageQueue(mqtemp);
|
||||
itDel->second->clearAllMsgs();
|
||||
removePullRequest(mqtemp);
|
||||
changed = true;
|
||||
} else if (itDel->second->isPullRequestExpired()) {
|
||||
// if pull expired , set to dropped, eg: if add pull task error, the pull request will be expired.
|
||||
LOG_INFO("Drop mq:%s according Pull timeout.", mqtemp.toString().c_str());
|
||||
itDel->second->setDropped(true);
|
||||
removeUnnecessaryMessageQueue(mqtemp);
|
||||
itDel->second->clearAllMsgs();
|
||||
removePullRequest(mqtemp);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//<!add check new mq added.
|
||||
vector<boost::shared_ptr<PullRequest>> pullRequestsToAdd;
|
||||
vector<MQMessageQueue>::iterator itAdd = mqsSelf.begin();
|
||||
for (; itAdd != mqsSelf.end(); ++itAdd) {
|
||||
if (isPullRequestExist(*itAdd)) {
|
||||
// have check the expired pull request, re-add it.
|
||||
continue;
|
||||
}
|
||||
boost::shared_ptr<PullRequest> pullRequest = boost::make_shared<PullRequest>(m_pConsumer->getGroupName());
|
||||
pullRequest->m_messageQueue = *itAdd;
|
||||
int64 nextOffset = computePullFromWhere(*itAdd);
|
||||
if (nextOffset >= 0) {
|
||||
pullRequest->setNextOffset(nextOffset);
|
||||
changed = true;
|
||||
addPullRequest(*itAdd, pullRequest);
|
||||
pullRequestsToAdd.push_back(pullRequest);
|
||||
LOG_INFO("Add mq:%s, request initial offset:%ld", (*itAdd).toString().c_str(), nextOffset);
|
||||
} else {
|
||||
LOG_WARN(
|
||||
"Failed to add pull request for %s due to failure of querying consume offset, request initial offset:%ld",
|
||||
(*itAdd).toString().c_str(), nextOffset);
|
||||
}
|
||||
}
|
||||
|
||||
for (vector<boost::shared_ptr<PullRequest>>::iterator itAdded = pullRequestsToAdd.begin();
|
||||
itAdded != pullRequestsToAdd.end(); ++itAdded) {
|
||||
LOG_INFO("Start to pull %s, offset:%ld, GroupName %s", (*itAdded)->m_messageQueue.toString().c_str(),
|
||||
(*itAdded)->getNextOffset(), (*itAdded)->getGroupName().c_str());
|
||||
if (!m_pConsumer->producePullMsgTask(*itAdded)) {
|
||||
LOG_WARN(
|
||||
"Failed to producer pull message task for %s, Remove it from Request table and wait for next #Rebalance.",
|
||||
(*itAdded)->m_messageQueue.toString().c_str());
|
||||
// remove from request table, and wait for next rebalance.
|
||||
(*itAdded)->setDropped(true);
|
||||
removePullRequest((*itAdded)->m_messageQueue);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("updateRequestTableInRebalance Topic[%s] exit", topic.c_str());
|
||||
return changed;
|
||||
}
|
||||
|
||||
int64 RebalancePush::computePullFromWhere(const MQMessageQueue& mq) {
|
||||
int64 result = -1;
|
||||
DefaultMQPushConsumerImpl* pConsumer = dynamic_cast<DefaultMQPushConsumerImpl*>(m_pConsumer);
|
||||
if (!pConsumer) {
|
||||
LOG_ERROR("Cast consumer pointer to DefaultMQPushConsumer pointer failed when computePullFromWhere %s",
|
||||
mq.toString().c_str());
|
||||
return result;
|
||||
}
|
||||
ConsumeFromWhere consumeFromWhere = pConsumer->getConsumeFromWhere();
|
||||
OffsetStore* pOffsetStore = pConsumer->getOffsetStore();
|
||||
switch (consumeFromWhere) {
|
||||
case CONSUME_FROM_LAST_OFFSET: {
|
||||
int64 lastOffset = pOffsetStore->readOffset(mq, READ_FROM_STORE, m_pConsumer->getSessionCredentials());
|
||||
if (lastOffset >= 0) {
|
||||
LOG_INFO("CONSUME_FROM_LAST_OFFSET, lastOffset of mq:%s is:%lld", mq.toString().c_str(), lastOffset);
|
||||
result = lastOffset;
|
||||
} else if (-1 == lastOffset) {
|
||||
LOG_WARN("CONSUME_FROM_LAST_OFFSET, lastOffset of mq:%s is -1", mq.toString().c_str());
|
||||
if (UtilAll::startsWith_retry(mq.getTopic())) {
|
||||
LOG_INFO("CONSUME_FROM_LAST_OFFSET, lastOffset of mq:%s is 0", mq.toString().c_str());
|
||||
result = 0;
|
||||
} else {
|
||||
try {
|
||||
result = pConsumer->maxOffset(mq);
|
||||
LOG_INFO("CONSUME_FROM_LAST_OFFSET, maxOffset of mq:%s is:%lld", mq.toString().c_str(), result);
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("CONSUME_FROM_LAST_OFFSET error, lastOffset of mq:%s is -1", mq.toString().c_str());
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG_ERROR("CONSUME_FROM_LAST_OFFSET error, lastOffset of mq:%s is -1", mq.toString().c_str());
|
||||
result = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CONSUME_FROM_FIRST_OFFSET: {
|
||||
int64 lastOffset = pOffsetStore->readOffset(mq, READ_FROM_STORE, m_pConsumer->getSessionCredentials());
|
||||
if (lastOffset >= 0) {
|
||||
LOG_INFO("CONSUME_FROM_FIRST_OFFSET, lastOffset of mq:%s is:%lld", mq.toString().c_str(), lastOffset);
|
||||
result = lastOffset;
|
||||
} else if (-1 == lastOffset) {
|
||||
LOG_INFO("CONSUME_FROM_FIRST_OFFSET, lastOffset of mq:%s, return 0", mq.toString().c_str());
|
||||
result = 0;
|
||||
} else {
|
||||
LOG_ERROR("CONSUME_FROM_FIRST_OFFSET, lastOffset of mq:%s, return -1", mq.toString().c_str());
|
||||
result = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CONSUME_FROM_TIMESTAMP: {
|
||||
int64 lastOffset = pOffsetStore->readOffset(mq, READ_FROM_STORE, m_pConsumer->getSessionCredentials());
|
||||
if (lastOffset >= 0) {
|
||||
LOG_INFO("CONSUME_FROM_TIMESTAMP, lastOffset of mq:%s is:%lld", mq.toString().c_str(), lastOffset);
|
||||
result = lastOffset;
|
||||
} else if (-1 == lastOffset) {
|
||||
if (UtilAll::startsWith_retry(mq.getTopic())) {
|
||||
try {
|
||||
result = pConsumer->maxOffset(mq);
|
||||
LOG_INFO("CONSUME_FROM_TIMESTAMP, maxOffset of mq:%s is:%lld", mq.toString().c_str(), result);
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("CONSUME_FROM_TIMESTAMP error, lastOffset of mq:%s is -1", mq.toString().c_str());
|
||||
result = -1;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
} catch (MQException& e) {
|
||||
LOG_ERROR("CONSUME_FROM_TIMESTAMP error, lastOffset of mq:%s, return 0", mq.toString().c_str());
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG_ERROR("CONSUME_FROM_TIMESTAMP error, lastOffset of mq:%s, return -1", mq.toString().c_str());
|
||||
result = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void RebalancePush::messageQueueChanged(const string& topic,
|
||||
vector<MQMessageQueue>& mqAll,
|
||||
vector<MQMessageQueue>& mqDivided) {}
|
||||
|
||||
void RebalancePush::removeUnnecessaryMessageQueue(const MQMessageQueue& mq) {
|
||||
// DefaultMQPushConsumer *pConsumer = static_cast<DefaultMQPushConsumer *>(m_pConsumer);
|
||||
DefaultMQPushConsumerImpl* pConsumer = dynamic_cast<DefaultMQPushConsumerImpl*>(m_pConsumer);
|
||||
if (!pConsumer) {
|
||||
LOG_ERROR("Cast MQConsumer* to DefaultMQPushConsumer* failed when remove %s", mq.toString().c_str());
|
||||
return;
|
||||
}
|
||||
OffsetStore* pOffsetStore = pConsumer->getOffsetStore();
|
||||
|
||||
pOffsetStore->persist(mq, m_pConsumer->getSessionCredentials());
|
||||
pOffsetStore->removeOffset(mq);
|
||||
if (pConsumer->getMessageListenerType() == messageListenerOrderly) {
|
||||
unlock(mq);
|
||||
}
|
||||
}
|
||||
|
||||
//<!************************************************************************
|
||||
} // namespace rocketmq
|
||||
137
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/Rebalance.h
vendored
Normal file
137
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/Rebalance.h
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __REBALANCEIMPL_H__
|
||||
#define __REBALANCEIMPL_H__
|
||||
|
||||
#include "AllocateMQStrategy.h"
|
||||
#include "ConsumeType.h"
|
||||
#include "MQConsumer.h"
|
||||
#include "MQMessageQueue.h"
|
||||
#include "PullRequest.h"
|
||||
#include "SubscriptionData.h"
|
||||
|
||||
#include <boost/smart_ptr.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
namespace rocketmq {
|
||||
class MQClientFactory;
|
||||
|
||||
//<!************************************************************************
|
||||
class Rebalance {
|
||||
public:
|
||||
Rebalance(MQConsumer*, MQClientFactory*);
|
||||
|
||||
virtual ~Rebalance();
|
||||
|
||||
virtual void messageQueueChanged(const string& topic,
|
||||
vector<MQMessageQueue>& mqAll,
|
||||
vector<MQMessageQueue>& mqDivided) = 0;
|
||||
|
||||
virtual void removeUnnecessaryMessageQueue(const MQMessageQueue& mq) = 0;
|
||||
|
||||
virtual int64 computePullFromWhere(const MQMessageQueue& mq) = 0;
|
||||
|
||||
virtual bool updateRequestTableInRebalance(const string& topic, vector<MQMessageQueue>& mqsSelf) = 0;
|
||||
|
||||
public:
|
||||
void doRebalance();
|
||||
|
||||
void persistConsumerOffset();
|
||||
|
||||
void persistConsumerOffsetByResetOffset();
|
||||
|
||||
//<!m_subscriptionInner;
|
||||
SubscriptionData* getSubscriptionData(const string& topic);
|
||||
|
||||
void setSubscriptionData(const string& topic, SubscriptionData* pdata);
|
||||
|
||||
map<string, SubscriptionData*>& getSubscriptionInner();
|
||||
|
||||
//<!m_topicSubscribeInfoTable;
|
||||
void setTopicSubscribeInfo(const string& topic, vector<MQMessageQueue>& mqs);
|
||||
|
||||
bool getTopicSubscribeInfo(const string& topic, vector<MQMessageQueue>& mqs);
|
||||
|
||||
void addPullRequest(MQMessageQueue mq, boost::shared_ptr<PullRequest> pPullRequest);
|
||||
void removePullRequest(MQMessageQueue mq);
|
||||
bool isPullRequestExist(MQMessageQueue mq);
|
||||
boost::weak_ptr<PullRequest> getPullRequest(MQMessageQueue mq);
|
||||
|
||||
map<MQMessageQueue, boost::shared_ptr<PullRequest>> getPullRequestTable();
|
||||
|
||||
void lockAll();
|
||||
|
||||
bool lock(MQMessageQueue mq);
|
||||
|
||||
void unlockAll(bool oneWay = false);
|
||||
|
||||
void unlock(MQMessageQueue mq);
|
||||
|
||||
protected:
|
||||
map<string, SubscriptionData*> m_subscriptionData;
|
||||
|
||||
boost::mutex m_topicSubscribeInfoTableMutex;
|
||||
map<string, vector<MQMessageQueue>> m_topicSubscribeInfoTable;
|
||||
typedef map<MQMessageQueue, boost::shared_ptr<PullRequest>> MQ2PULLREQ;
|
||||
MQ2PULLREQ m_requestQueueTable;
|
||||
boost::mutex m_requestTableMutex;
|
||||
|
||||
AllocateMQStrategy* m_pAllocateMQStrategy;
|
||||
MQConsumer* m_pConsumer;
|
||||
MQClientFactory* m_pClientFactory;
|
||||
};
|
||||
|
||||
//<!************************************************************************
|
||||
class RebalancePull : public Rebalance {
|
||||
public:
|
||||
RebalancePull(MQConsumer*, MQClientFactory*);
|
||||
|
||||
virtual ~RebalancePull(){};
|
||||
|
||||
virtual void messageQueueChanged(const string& topic,
|
||||
vector<MQMessageQueue>& mqAll,
|
||||
vector<MQMessageQueue>& mqDivided);
|
||||
|
||||
virtual void removeUnnecessaryMessageQueue(const MQMessageQueue& mq);
|
||||
|
||||
virtual int64 computePullFromWhere(const MQMessageQueue& mq);
|
||||
|
||||
virtual bool updateRequestTableInRebalance(const string& topic, vector<MQMessageQueue>& mqsSelf);
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
class RebalancePush : public Rebalance {
|
||||
public:
|
||||
RebalancePush(MQConsumer*, MQClientFactory*);
|
||||
|
||||
virtual ~RebalancePush(){};
|
||||
|
||||
virtual void messageQueueChanged(const string& topic,
|
||||
vector<MQMessageQueue>& mqAll,
|
||||
vector<MQMessageQueue>& mqDivided);
|
||||
|
||||
virtual void removeUnnecessaryMessageQueue(const MQMessageQueue& mq);
|
||||
|
||||
virtual int64 computePullFromWhere(const MQMessageQueue& mq);
|
||||
|
||||
virtual bool updateRequestTableInRebalance(const string& topic, vector<MQMessageQueue>& mqsSelf);
|
||||
};
|
||||
|
||||
//<!************************************************************************
|
||||
} // namespace rocketmq
|
||||
|
||||
#endif
|
||||
130
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/SubscriptionData.cpp
vendored
Normal file
130
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/SubscriptionData.cpp
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "SubscriptionData.h"
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include "Logging.h"
|
||||
#include "UtilAll.h"
|
||||
namespace rocketmq {
|
||||
//<!************************************************************************
|
||||
SubscriptionData::SubscriptionData() {
|
||||
m_subVersion = UtilAll::currentTimeMillis();
|
||||
}
|
||||
|
||||
SubscriptionData::SubscriptionData(const string& topic, const string& subString)
|
||||
: m_topic(topic), m_subString(subString) {
|
||||
m_subVersion = UtilAll::currentTimeMillis();
|
||||
}
|
||||
|
||||
SubscriptionData::SubscriptionData(const SubscriptionData& other) {
|
||||
m_subString = other.m_subString;
|
||||
m_subVersion = other.m_subVersion;
|
||||
m_tagSet = other.m_tagSet;
|
||||
m_topic = other.m_topic;
|
||||
m_codeSet = other.m_codeSet;
|
||||
}
|
||||
|
||||
const string& SubscriptionData::getTopic() const {
|
||||
return m_topic;
|
||||
}
|
||||
|
||||
const string& SubscriptionData::getSubString() const {
|
||||
return m_subString;
|
||||
}
|
||||
|
||||
void SubscriptionData::setSubString(const string& sub) {
|
||||
m_subString = sub;
|
||||
}
|
||||
|
||||
int64 SubscriptionData::getSubVersion() const {
|
||||
return m_subVersion;
|
||||
}
|
||||
|
||||
void SubscriptionData::putTagsSet(const string& tag) {
|
||||
m_tagSet.push_back(tag);
|
||||
}
|
||||
|
||||
bool SubscriptionData::containTag(const string& tag) {
|
||||
return std::find(m_tagSet.begin(), m_tagSet.end(), tag) != m_tagSet.end();
|
||||
}
|
||||
|
||||
vector<string>& SubscriptionData::getTagsSet() {
|
||||
return m_tagSet;
|
||||
}
|
||||
|
||||
bool SubscriptionData::operator==(const SubscriptionData& other) const {
|
||||
if (!m_subString.compare(other.m_subString)) {
|
||||
return false;
|
||||
}
|
||||
if (m_subVersion != other.m_subVersion) {
|
||||
return false;
|
||||
}
|
||||
if (m_tagSet.size() != other.m_tagSet.size()) {
|
||||
return false;
|
||||
}
|
||||
if (!m_topic.compare(other.m_topic)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SubscriptionData::operator<(const SubscriptionData& other) const {
|
||||
int ret = m_topic.compare(other.m_topic);
|
||||
if (ret < 0) {
|
||||
return true;
|
||||
} else if (ret == 0) {
|
||||
ret = m_subString.compare(other.m_subString);
|
||||
if (ret < 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void SubscriptionData::putCodeSet(const string& tag) {
|
||||
int value = atoi(tag.c_str());
|
||||
m_codeSet.push_back(value);
|
||||
}
|
||||
|
||||
Json::Value SubscriptionData::toJson() const {
|
||||
Json::Value outJson;
|
||||
outJson["subString"] = m_subString;
|
||||
outJson["subVersion"] = UtilAll::to_string(m_subVersion);
|
||||
outJson["topic"] = m_topic;
|
||||
|
||||
{
|
||||
vector<string>::const_iterator it = m_tagSet.begin();
|
||||
for (; it != m_tagSet.end(); it++) {
|
||||
outJson["tagsSet"].append(*it);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
vector<int>::const_iterator it = m_codeSet.begin();
|
||||
for (; it != m_codeSet.end(); it++) {
|
||||
outJson["codeSet"].append(*it);
|
||||
}
|
||||
}
|
||||
return outJson;
|
||||
}
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
62
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/SubscriptionData.h
vendored
Normal file
62
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/consumer/SubscriptionData.h
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __SUBSCRIPTIONDATA_H__
|
||||
#define __SUBSCRIPTIONDATA_H__
|
||||
|
||||
#include <string>
|
||||
#include "UtilAll.h"
|
||||
#include "json/json.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!************************************************************************
|
||||
class SubscriptionData {
|
||||
public:
|
||||
SubscriptionData();
|
||||
virtual ~SubscriptionData() {
|
||||
m_tagSet.clear();
|
||||
m_codeSet.clear();
|
||||
}
|
||||
SubscriptionData(const string& topic, const string& subString);
|
||||
SubscriptionData(const SubscriptionData& other);
|
||||
|
||||
const string& getTopic() const;
|
||||
const string& getSubString() const;
|
||||
void setSubString(const string& sub);
|
||||
int64 getSubVersion() const;
|
||||
|
||||
void putTagsSet(const string& tag);
|
||||
bool containTag(const string& tag);
|
||||
vector<string>& getTagsSet();
|
||||
|
||||
void putCodeSet(const string& tag);
|
||||
|
||||
bool operator==(const SubscriptionData& other) const;
|
||||
bool operator<(const SubscriptionData& other) const;
|
||||
|
||||
Json::Value toJson() const;
|
||||
|
||||
private:
|
||||
string m_topic;
|
||||
string m_subString;
|
||||
int64 m_subVersion;
|
||||
vector<string> m_tagSet;
|
||||
vector<int> m_codeSet;
|
||||
};
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
|
||||
#endif
|
||||
33
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/dllmain.cpp
vendored
Normal file
33
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/dllmain.cpp
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "windows.h"
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
|
||||
switch (ul_reason_for_call) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
59
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/extern/CBatchMessage.cpp
vendored
Normal file
59
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/extern/CBatchMessage.cpp
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "CBatchMessage.h"
|
||||
#include "CCommon.h"
|
||||
#include "CMessage.h"
|
||||
#include "MQMessage.h"
|
||||
|
||||
using std::vector;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
using namespace rocketmq;
|
||||
|
||||
CBatchMessage* CreateBatchMessage() {
|
||||
vector<MQMessage>* msgs = new vector<MQMessage>();
|
||||
return (CBatchMessage*)msgs;
|
||||
}
|
||||
|
||||
int AddMessage(CBatchMessage* batchMsg, CMessage* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
if (batchMsg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
MQMessage* message = (MQMessage*)msg;
|
||||
((vector<MQMessage>*)batchMsg)->push_back(*message);
|
||||
return OK;
|
||||
}
|
||||
int DestroyBatchMessage(CBatchMessage* batchMsg) {
|
||||
if (batchMsg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
delete (vector<MQMessage>*)batchMsg;
|
||||
return OK;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
33
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/extern/CErrorMessage.cpp
vendored
Normal file
33
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/extern/CErrorMessage.cpp
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "CErrorMessage.h"
|
||||
#include "CCommon.h"
|
||||
#include "MQClientErrorContainer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
using namespace rocketmq;
|
||||
|
||||
const char* GetLatestErrorMessage() {
|
||||
return MQClientErrorContainer::getErr().c_str();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
129
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/extern/CMessage.cpp
vendored
Normal file
129
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/extern/CMessage.cpp
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "CMessage.h"
|
||||
#include "CCommon.h"
|
||||
#include "MQMessage.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
using namespace rocketmq;
|
||||
|
||||
CMessage* CreateMessage(const char* topic) {
|
||||
MQMessage* mqMessage = new MQMessage();
|
||||
if (topic != NULL) {
|
||||
mqMessage->setTopic(topic);
|
||||
}
|
||||
return (CMessage*)mqMessage;
|
||||
}
|
||||
int DestroyMessage(CMessage* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
delete (MQMessage*)msg;
|
||||
return OK;
|
||||
}
|
||||
int SetMessageTopic(CMessage* msg, const char* topic) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((MQMessage*)msg)->setTopic(topic);
|
||||
return OK;
|
||||
}
|
||||
int SetMessageTags(CMessage* msg, const char* tags) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((MQMessage*)msg)->setTags(tags);
|
||||
return OK;
|
||||
}
|
||||
int SetMessageKeys(CMessage* msg, const char* keys) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((MQMessage*)msg)->setKeys(keys);
|
||||
return OK;
|
||||
}
|
||||
int SetMessageBody(CMessage* msg, const char* body) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((MQMessage*)msg)->setBody(body);
|
||||
return OK;
|
||||
}
|
||||
int SetByteMessageBody(CMessage* msg, const char* body, int len) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((MQMessage*)msg)->setBody(body, len);
|
||||
return OK;
|
||||
}
|
||||
int SetMessageProperty(CMessage* msg, const char* key, const char* value) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((MQMessage*)msg)->setProperty(key, value);
|
||||
return OK;
|
||||
}
|
||||
int SetDelayTimeLevel(CMessage* msg, int level) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((MQMessage*)msg)->setDelayTimeLevel(level);
|
||||
return OK;
|
||||
}
|
||||
const char* GetOriginMessageTopic(CMessage* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return ((MQMessage*)msg)->getTopic().c_str();
|
||||
}
|
||||
const char* GetOriginMessageTags(CMessage* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return ((MQMessage*)msg)->getTags().c_str();
|
||||
}
|
||||
const char* GetOriginMessageKeys(CMessage* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return ((MQMessage*)msg)->getKeys().c_str();
|
||||
}
|
||||
const char* GetOriginMessageBody(CMessage* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return ((MQMessage*)msg)->getBody().c_str();
|
||||
}
|
||||
const char* GetOriginMessageProperty(CMessage* msg, const char* key) {
|
||||
if (msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return ((MQMessage*)msg)->getProperty(key).c_str();
|
||||
}
|
||||
int GetOriginDelayTimeLevel(CMessage* msg) {
|
||||
if (msg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
return ((MQMessage*)msg)->getDelayTimeLevel();
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
127
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/extern/CMessageExt.cpp
vendored
Normal file
127
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/extern/CMessageExt.cpp
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "CMessageExt.h"
|
||||
#include "CCommon.h"
|
||||
#include "MQMessageExt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
using namespace rocketmq;
|
||||
const char* GetMessageTopic(CMessageExt* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return ((MQMessageExt*)msg)->getTopic().c_str();
|
||||
}
|
||||
const char* GetMessageTags(CMessageExt* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return ((MQMessageExt*)msg)->getTags().c_str();
|
||||
}
|
||||
const char* GetMessageKeys(CMessageExt* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return ((MQMessageExt*)msg)->getKeys().c_str();
|
||||
}
|
||||
const char* GetMessageBody(CMessageExt* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return ((MQMessageExt*)msg)->getBody().c_str();
|
||||
}
|
||||
const char* GetMessageProperty(CMessageExt* msg, const char* key) {
|
||||
if (msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return ((MQMessageExt*)msg)->getProperty(key).c_str();
|
||||
}
|
||||
const char* GetMessageId(CMessageExt* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return ((MQMessageExt*)msg)->getMsgId().c_str();
|
||||
}
|
||||
|
||||
int GetMessageDelayTimeLevel(CMessageExt* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
return ((MQMessageExt*)msg)->getDelayTimeLevel();
|
||||
}
|
||||
|
||||
int GetMessageQueueId(CMessageExt* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
return ((MQMessageExt*)msg)->getQueueId();
|
||||
}
|
||||
|
||||
int GetMessageReconsumeTimes(CMessageExt* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
return ((MQMessageExt*)msg)->getReconsumeTimes();
|
||||
}
|
||||
|
||||
int GetMessageStoreSize(CMessageExt* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
return ((MQMessageExt*)msg)->getStoreSize();
|
||||
}
|
||||
|
||||
long long GetMessageBornTimestamp(CMessageExt* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
return ((MQMessageExt*)msg)->getBornTimestamp();
|
||||
}
|
||||
|
||||
long long GetMessageStoreTimestamp(CMessageExt* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
return ((MQMessageExt*)msg)->getStoreTimestamp();
|
||||
}
|
||||
|
||||
long long GetMessageQueueOffset(CMessageExt* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
return ((MQMessageExt*)msg)->getQueueOffset();
|
||||
}
|
||||
|
||||
long long GetMessageCommitLogOffset(CMessageExt* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
return ((MQMessageExt*)msg)->getCommitLogOffset();
|
||||
}
|
||||
|
||||
long long GetMessagePreparedTransactionOffset(CMessageExt* msg) {
|
||||
if (msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
return ((MQMessageExt*)msg)->getPreparedTransactionOffset();
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
820
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/extern/CProducer.cpp
vendored
Normal file
820
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/extern/CProducer.cpp
vendored
Normal file
@@ -0,0 +1,820 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "CProducer.h"
|
||||
#include <string.h>
|
||||
#include <functional>
|
||||
#include <typeindex>
|
||||
#include <typeinfo>
|
||||
#include "AsyncCallback.h"
|
||||
#include "CBatchMessage.h"
|
||||
#include "CCommon.h"
|
||||
#include "CMQException.h"
|
||||
#include "CMessage.h"
|
||||
#include "CSendResult.h"
|
||||
#include "DefaultMQProducer.h"
|
||||
#include "MQClient.h"
|
||||
#include "MQClientErrorContainer.h"
|
||||
#include "TransactionListener.h"
|
||||
#include "TransactionMQProducer.h"
|
||||
#include "TransactionSendResult.h"
|
||||
#include "UtilAll.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
using namespace rocketmq;
|
||||
using namespace std;
|
||||
class MyLocalTransactionExecuterInner {
|
||||
public:
|
||||
MyLocalTransactionExecuterInner(CLocalTransactionExecutorCallback executor, CMessage* msg, void* userData)
|
||||
: m_ExcutorCallback(executor), message(msg), data(userData) {}
|
||||
~MyLocalTransactionExecuterInner() {}
|
||||
CLocalTransactionExecutorCallback m_ExcutorCallback;
|
||||
CMessage* message;
|
||||
void* data;
|
||||
};
|
||||
class LocalTransactionListenerInner : public TransactionListener {
|
||||
public:
|
||||
LocalTransactionListenerInner() {}
|
||||
|
||||
LocalTransactionListenerInner(CProducer* producer, CLocalTransactionCheckerCallback pCallback, void* data) {
|
||||
m_CheckerCallback = pCallback;
|
||||
m_producer = producer;
|
||||
m_data = data;
|
||||
}
|
||||
|
||||
~LocalTransactionListenerInner() {}
|
||||
|
||||
LocalTransactionState executeLocalTransaction(const MQMessage& message, void* arg) {
|
||||
if (m_CheckerCallback == NULL) {
|
||||
return LocalTransactionState::UNKNOWN;
|
||||
}
|
||||
(void)(message);
|
||||
MyLocalTransactionExecuterInner* executerInner = (MyLocalTransactionExecuterInner*)arg;
|
||||
CTransactionStatus status =
|
||||
executerInner->m_ExcutorCallback(m_producer, executerInner->message, executerInner->data);
|
||||
switch (status) {
|
||||
case E_COMMIT_TRANSACTION:
|
||||
return LocalTransactionState::COMMIT_MESSAGE;
|
||||
|
||||
case E_ROLLBACK_TRANSACTION:
|
||||
return LocalTransactionState::ROLLBACK_MESSAGE;
|
||||
|
||||
default:
|
||||
return LocalTransactionState::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
LocalTransactionState checkLocalTransaction(const MQMessageExt& msg) {
|
||||
if (m_CheckerCallback == NULL) {
|
||||
return LocalTransactionState::UNKNOWN;
|
||||
}
|
||||
CMessageExt* msgExt = (CMessageExt*)(&msg);
|
||||
// CMessage *msg = (CMessage *) (&message);
|
||||
CTransactionStatus status = m_CheckerCallback(m_producer, msgExt, m_data);
|
||||
switch (status) {
|
||||
case E_COMMIT_TRANSACTION:
|
||||
return LocalTransactionState::COMMIT_MESSAGE;
|
||||
|
||||
case E_ROLLBACK_TRANSACTION:
|
||||
return LocalTransactionState::ROLLBACK_MESSAGE;
|
||||
|
||||
default:
|
||||
return LocalTransactionState::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
CLocalTransactionCheckerCallback m_CheckerCallback;
|
||||
CProducer* m_producer;
|
||||
void* m_data;
|
||||
};
|
||||
|
||||
class SelectMessageQueueInner : public MessageQueueSelector {
|
||||
public:
|
||||
MQMessageQueue select(const std::vector<MQMessageQueue>& mqs, const MQMessage& msg, void* arg) {
|
||||
int index = 0;
|
||||
std::string shardingKey = rocketmq::UtilAll::to_string((char*)arg);
|
||||
|
||||
index = std::hash<std::string>{}(shardingKey) % mqs.size();
|
||||
return mqs[index % mqs.size()];
|
||||
}
|
||||
};
|
||||
|
||||
class SelectMessageQueue : public MessageQueueSelector {
|
||||
public:
|
||||
SelectMessageQueue(QueueSelectorCallback callback) { m_pCallback = callback; }
|
||||
|
||||
MQMessageQueue select(const std::vector<MQMessageQueue>& mqs, const MQMessage& msg, void* arg) {
|
||||
CMessage* message = (CMessage*)&msg;
|
||||
// Get the index of sending MQMessageQueue through callback function.
|
||||
int index = m_pCallback(mqs.size(), message, arg);
|
||||
return mqs[index];
|
||||
}
|
||||
|
||||
private:
|
||||
QueueSelectorCallback m_pCallback;
|
||||
};
|
||||
class COnSendCallback : public AutoDeleteSendCallBack {
|
||||
public:
|
||||
COnSendCallback(COnSendSuccessCallback cSendSuccessCallback,
|
||||
COnSendExceptionCallback cSendExceptionCallback,
|
||||
void* message,
|
||||
void* userData) {
|
||||
m_cSendSuccessCallback = cSendSuccessCallback;
|
||||
m_cSendExceptionCallback = cSendExceptionCallback;
|
||||
m_message = message;
|
||||
m_userData = userData;
|
||||
}
|
||||
|
||||
virtual ~COnSendCallback() {}
|
||||
|
||||
virtual void onSuccess(SendResult& sendResult) {
|
||||
CSendResult result;
|
||||
result.sendStatus = CSendStatus((int)sendResult.getSendStatus());
|
||||
result.offset = sendResult.getQueueOffset();
|
||||
strncpy(result.msgId, sendResult.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1);
|
||||
result.msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0;
|
||||
m_cSendSuccessCallback(result, (CMessage*)m_message, m_userData);
|
||||
}
|
||||
|
||||
virtual void onException(MQException& e) {
|
||||
CMQException exception;
|
||||
exception.error = e.GetError();
|
||||
exception.line = e.GetLine();
|
||||
strncpy(exception.msg, e.what(), MAX_EXEPTION_MSG_LENGTH - 1);
|
||||
strncpy(exception.file, e.GetFile(), MAX_EXEPTION_FILE_LENGTH - 1);
|
||||
m_cSendExceptionCallback(exception, (CMessage*)m_message, m_userData);
|
||||
}
|
||||
|
||||
private:
|
||||
COnSendSuccessCallback m_cSendSuccessCallback;
|
||||
COnSendExceptionCallback m_cSendExceptionCallback;
|
||||
void* m_message;
|
||||
void* m_userData;
|
||||
};
|
||||
|
||||
class CSendCallback : public AutoDeleteSendCallBack {
|
||||
public:
|
||||
CSendCallback(CSendSuccessCallback cSendSuccessCallback, CSendExceptionCallback cSendExceptionCallback) {
|
||||
m_cSendSuccessCallback = cSendSuccessCallback;
|
||||
m_cSendExceptionCallback = cSendExceptionCallback;
|
||||
}
|
||||
|
||||
virtual ~CSendCallback() {}
|
||||
|
||||
virtual void onSuccess(SendResult& sendResult) {
|
||||
CSendResult result;
|
||||
result.sendStatus = CSendStatus((int)sendResult.getSendStatus());
|
||||
result.offset = sendResult.getQueueOffset();
|
||||
strncpy(result.msgId, sendResult.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1);
|
||||
result.msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0;
|
||||
m_cSendSuccessCallback(result);
|
||||
}
|
||||
|
||||
virtual void onException(MQException& e) {
|
||||
CMQException exception;
|
||||
exception.error = e.GetError();
|
||||
exception.line = e.GetLine();
|
||||
strncpy(exception.msg, e.what(), MAX_EXEPTION_MSG_LENGTH - 1);
|
||||
strncpy(exception.file, e.GetFile(), MAX_EXEPTION_FILE_LENGTH - 1);
|
||||
m_cSendExceptionCallback(exception);
|
||||
}
|
||||
|
||||
private:
|
||||
CSendSuccessCallback m_cSendSuccessCallback;
|
||||
CSendExceptionCallback m_cSendExceptionCallback;
|
||||
};
|
||||
#ifndef CAPI_C_PRODUCER_TYPE_COMMON
|
||||
#define CAPI_C_PRODUCER_TYPE_COMMON 0
|
||||
#endif
|
||||
|
||||
#ifndef CAPI_C_PRODUCER_TYPE_ORDERLY
|
||||
#define CAPI_C_PRODUCER_TYPE_ORDERLY 1
|
||||
#endif
|
||||
|
||||
#ifndef CAPI_C_PRODUCER_TYPE_TRANSACTION
|
||||
#define CAPI_C_PRODUCER_TYPE_TRANSACTION 2
|
||||
#endif
|
||||
typedef struct __DefaultProducer__ {
|
||||
DefaultMQProducer* innerProducer;
|
||||
TransactionMQProducer* innerTransactionProducer;
|
||||
LocalTransactionListenerInner* listenerInner;
|
||||
int producerType;
|
||||
char* version;
|
||||
} DefaultProducer;
|
||||
CProducer* CreateProducer(const char* groupId) {
|
||||
if (groupId == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = new DefaultProducer();
|
||||
defaultMQProducer->producerType = CAPI_C_PRODUCER_TYPE_COMMON;
|
||||
defaultMQProducer->innerProducer = new DefaultMQProducer(groupId);
|
||||
defaultMQProducer->version = new char[MAX_SDK_VERSION_LENGTH];
|
||||
strncpy(defaultMQProducer->version, defaultMQProducer->innerProducer->version().c_str(), MAX_SDK_VERSION_LENGTH - 1);
|
||||
defaultMQProducer->version[MAX_SDK_VERSION_LENGTH - 1] = 0;
|
||||
defaultMQProducer->innerTransactionProducer = NULL;
|
||||
defaultMQProducer->listenerInner = NULL;
|
||||
return (CProducer*)defaultMQProducer;
|
||||
}
|
||||
|
||||
CProducer* CreateOrderlyProducer(const char* groupId) {
|
||||
if (groupId == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = new DefaultProducer();
|
||||
defaultMQProducer->producerType = CAPI_C_PRODUCER_TYPE_ORDERLY;
|
||||
defaultMQProducer->innerProducer = new DefaultMQProducer(groupId);
|
||||
|
||||
defaultMQProducer->version = new char[MAX_SDK_VERSION_LENGTH];
|
||||
strncpy(defaultMQProducer->version, defaultMQProducer->innerProducer->version().c_str(), MAX_SDK_VERSION_LENGTH - 1);
|
||||
defaultMQProducer->version[MAX_SDK_VERSION_LENGTH - 1] = 0;
|
||||
defaultMQProducer->innerTransactionProducer = NULL;
|
||||
defaultMQProducer->listenerInner = NULL;
|
||||
return (CProducer*)defaultMQProducer;
|
||||
}
|
||||
|
||||
CProducer* CreateTransactionProducer(const char* groupId, CLocalTransactionCheckerCallback callback, void* userData) {
|
||||
if (groupId == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = new DefaultProducer();
|
||||
defaultMQProducer->producerType = CAPI_C_PRODUCER_TYPE_TRANSACTION;
|
||||
defaultMQProducer->innerProducer = NULL;
|
||||
defaultMQProducer->innerTransactionProducer = new TransactionMQProducer(groupId);
|
||||
defaultMQProducer->listenerInner =
|
||||
new LocalTransactionListenerInner((CProducer*)defaultMQProducer, callback, userData);
|
||||
defaultMQProducer->innerTransactionProducer->setTransactionListener(defaultMQProducer->listenerInner);
|
||||
|
||||
defaultMQProducer->version = new char[MAX_SDK_VERSION_LENGTH];
|
||||
strncpy(defaultMQProducer->version, defaultMQProducer->innerTransactionProducer->version().c_str(),
|
||||
MAX_SDK_VERSION_LENGTH - 1);
|
||||
defaultMQProducer->version[MAX_SDK_VERSION_LENGTH - 1] = 0;
|
||||
return (CProducer*)defaultMQProducer;
|
||||
}
|
||||
int DestroyProducer(CProducer* pProducer) {
|
||||
if (pProducer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)pProducer;
|
||||
if (defaultMQProducer->version != NULL) {
|
||||
delete defaultMQProducer->version;
|
||||
defaultMQProducer->version = NULL;
|
||||
}
|
||||
if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
|
||||
if (defaultMQProducer->innerTransactionProducer != NULL) {
|
||||
delete defaultMQProducer->innerTransactionProducer;
|
||||
defaultMQProducer->innerTransactionProducer = NULL;
|
||||
}
|
||||
} else {
|
||||
if (defaultMQProducer->innerProducer != NULL) {
|
||||
delete defaultMQProducer->innerProducer;
|
||||
defaultMQProducer->innerProducer = NULL;
|
||||
}
|
||||
}
|
||||
delete reinterpret_cast<DefaultProducer*>(pProducer);
|
||||
return OK;
|
||||
}
|
||||
int StartProducer(CProducer* producer) {
|
||||
if (producer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
try {
|
||||
if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
|
||||
defaultMQProducer->innerTransactionProducer->start();
|
||||
} else {
|
||||
defaultMQProducer->innerProducer->start();
|
||||
}
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_START_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
int ShutdownProducer(CProducer* producer) {
|
||||
if (producer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
try {
|
||||
if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
|
||||
defaultMQProducer->innerTransactionProducer->shutdown();
|
||||
} else {
|
||||
defaultMQProducer->innerProducer->shutdown();
|
||||
}
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_START_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
const char* ShowProducerVersion(CProducer* producer) {
|
||||
if (producer == NULL) {
|
||||
return DEFAULT_SDK_VERSION;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
|
||||
return defaultMQProducer->version;
|
||||
}
|
||||
int SetProducerNameServerAddress(CProducer* producer, const char* namesrv) {
|
||||
if (producer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
try {
|
||||
if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
|
||||
defaultMQProducer->innerTransactionProducer->setNamesrvAddr(namesrv);
|
||||
} else {
|
||||
defaultMQProducer->innerProducer->setNamesrvAddr(namesrv);
|
||||
}
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_START_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
int SetProducerNameServerDomain(CProducer* producer, const char* domain) {
|
||||
if (producer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
try {
|
||||
if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
|
||||
defaultMQProducer->innerTransactionProducer->setNamesrvDomain(domain);
|
||||
} else {
|
||||
defaultMQProducer->innerProducer->setNamesrvDomain(domain);
|
||||
}
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_START_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
int SendMessageSync(CProducer* producer, CMessage* msg, CSendResult* result) {
|
||||
// CSendResult sendResult;
|
||||
if (producer == NULL || msg == NULL || result == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
try {
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
MQMessage* message = (MQMessage*)msg;
|
||||
SendResult sendResult = defaultMQProducer->innerProducer->send(*message);
|
||||
switch (sendResult.getSendStatus()) {
|
||||
case SEND_OK:
|
||||
result->sendStatus = E_SEND_OK;
|
||||
break;
|
||||
case SEND_FLUSH_DISK_TIMEOUT:
|
||||
result->sendStatus = E_SEND_FLUSH_DISK_TIMEOUT;
|
||||
break;
|
||||
case SEND_FLUSH_SLAVE_TIMEOUT:
|
||||
result->sendStatus = E_SEND_FLUSH_SLAVE_TIMEOUT;
|
||||
break;
|
||||
case SEND_SLAVE_NOT_AVAILABLE:
|
||||
result->sendStatus = E_SEND_SLAVE_NOT_AVAILABLE;
|
||||
break;
|
||||
default:
|
||||
result->sendStatus = E_SEND_OK;
|
||||
break;
|
||||
}
|
||||
result->offset = sendResult.getQueueOffset();
|
||||
strncpy(result->msgId, sendResult.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1);
|
||||
result->msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0;
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_SEND_SYNC_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SendBatchMessage(CProducer* producer, CBatchMessage* batcMsg, CSendResult* result) {
|
||||
// CSendResult sendResult;
|
||||
if (producer == NULL || batcMsg == NULL || result == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
try {
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
vector<MQMessage>* message = (vector<MQMessage>*)batcMsg;
|
||||
SendResult sendResult = defaultMQProducer->innerProducer->send(*message);
|
||||
switch (sendResult.getSendStatus()) {
|
||||
case SEND_OK:
|
||||
result->sendStatus = E_SEND_OK;
|
||||
break;
|
||||
case SEND_FLUSH_DISK_TIMEOUT:
|
||||
result->sendStatus = E_SEND_FLUSH_DISK_TIMEOUT;
|
||||
break;
|
||||
case SEND_FLUSH_SLAVE_TIMEOUT:
|
||||
result->sendStatus = E_SEND_FLUSH_SLAVE_TIMEOUT;
|
||||
break;
|
||||
case SEND_SLAVE_NOT_AVAILABLE:
|
||||
result->sendStatus = E_SEND_SLAVE_NOT_AVAILABLE;
|
||||
break;
|
||||
default:
|
||||
result->sendStatus = E_SEND_OK;
|
||||
break;
|
||||
}
|
||||
result->offset = sendResult.getQueueOffset();
|
||||
strncpy(result->msgId, sendResult.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1);
|
||||
result->msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0;
|
||||
} catch (exception& e) {
|
||||
return PRODUCER_SEND_SYNC_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SendMessageAsync(CProducer* producer,
|
||||
CMessage* msg,
|
||||
CSendSuccessCallback cSendSuccessCallback,
|
||||
CSendExceptionCallback cSendExceptionCallback) {
|
||||
if (producer == NULL || msg == NULL || cSendSuccessCallback == NULL || cSendExceptionCallback == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
MQMessage* message = (MQMessage*)msg;
|
||||
CSendCallback* cSendCallback = new CSendCallback(cSendSuccessCallback, cSendExceptionCallback);
|
||||
|
||||
try {
|
||||
defaultMQProducer->innerProducer->send(*message, cSendCallback);
|
||||
} catch (exception& e) {
|
||||
if (cSendCallback != NULL) {
|
||||
if (std::type_index(typeid(e)) == std::type_index(typeid(MQException))) {
|
||||
MQException& mqe = (MQException&)e;
|
||||
cSendCallback->onException(mqe);
|
||||
}
|
||||
delete cSendCallback;
|
||||
cSendCallback = NULL;
|
||||
}
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_SEND_ASYNC_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SendAsync(CProducer* producer,
|
||||
CMessage* msg,
|
||||
COnSendSuccessCallback onSuccess,
|
||||
COnSendExceptionCallback onException,
|
||||
void* usrData) {
|
||||
if (producer == NULL || msg == NULL || onSuccess == NULL || onException == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
MQMessage* message = (MQMessage*)msg;
|
||||
COnSendCallback* cSendCallback = new COnSendCallback(onSuccess, onException, (void*)msg, usrData);
|
||||
|
||||
try {
|
||||
defaultMQProducer->innerProducer->send(*message, cSendCallback);
|
||||
} catch (exception& e) {
|
||||
if (cSendCallback != NULL) {
|
||||
if (std::type_index(typeid(e)) == std::type_index(typeid(MQException))) {
|
||||
MQException& mqe = (MQException&)e;
|
||||
cSendCallback->onException(mqe);
|
||||
}
|
||||
delete cSendCallback;
|
||||
cSendCallback = NULL;
|
||||
}
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_SEND_ASYNC_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SendMessageOneway(CProducer* producer, CMessage* msg) {
|
||||
if (producer == NULL || msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
MQMessage* message = (MQMessage*)msg;
|
||||
try {
|
||||
defaultMQProducer->innerProducer->sendOneway(*message);
|
||||
} catch (exception& e) {
|
||||
return PRODUCER_SEND_ONEWAY_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SendMessageOnewayOrderly(CProducer* producer, CMessage* msg, QueueSelectorCallback selector, void* arg) {
|
||||
if (producer == NULL || msg == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
MQMessage* message = (MQMessage*)msg;
|
||||
try {
|
||||
SelectMessageQueue selectMessageQueue(selector);
|
||||
defaultMQProducer->innerProducer->sendOneway(*message, &selectMessageQueue, arg);
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_SEND_ONEWAY_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SendMessageOrderlyAsync(CProducer* producer,
|
||||
CMessage* msg,
|
||||
QueueSelectorCallback callback,
|
||||
void* arg,
|
||||
CSendSuccessCallback cSendSuccessCallback,
|
||||
CSendExceptionCallback cSendExceptionCallback) {
|
||||
if (producer == NULL || msg == NULL || callback == NULL || cSendSuccessCallback == NULL ||
|
||||
cSendExceptionCallback == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
MQMessage* message = (MQMessage*)msg;
|
||||
CSendCallback* cSendCallback = new CSendCallback(cSendSuccessCallback, cSendExceptionCallback);
|
||||
|
||||
try {
|
||||
// Constructing SelectMessageQueue objects through function pointer callback
|
||||
SelectMessageQueue selectMessageQueue(callback);
|
||||
defaultMQProducer->innerProducer->send(*message, &selectMessageQueue, arg, cSendCallback);
|
||||
} catch (exception& e) {
|
||||
printf("%s\n", e.what());
|
||||
// std::count<<e.what( )<<std::endl;
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_SEND_ORDERLYASYNC_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SendMessageOrderly(CProducer* producer,
|
||||
CMessage* msg,
|
||||
QueueSelectorCallback callback,
|
||||
void* arg,
|
||||
int autoRetryTimes,
|
||||
CSendResult* result) {
|
||||
if (producer == NULL || msg == NULL || callback == NULL || arg == NULL || result == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
MQMessage* message = (MQMessage*)msg;
|
||||
try {
|
||||
// Constructing SelectMessageQueue objects through function pointer callback
|
||||
SelectMessageQueue selectMessageQueue(callback);
|
||||
SendResult sendResult = defaultMQProducer->innerProducer->send(*message, &selectMessageQueue, arg, autoRetryTimes);
|
||||
// Convert SendStatus to CSendStatus
|
||||
result->sendStatus = CSendStatus((int)sendResult.getSendStatus());
|
||||
result->offset = sendResult.getQueueOffset();
|
||||
strncpy(result->msgId, sendResult.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1);
|
||||
result->msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0;
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_SEND_ORDERLY_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
int SendMessageOrderlyByShardingKey(CProducer* producer, CMessage* msg, const char* shardingKey, CSendResult* result) {
|
||||
if (producer == NULL || msg == NULL || shardingKey == NULL || result == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
MQMessage* message = (MQMessage*)msg;
|
||||
|
||||
string sKey(shardingKey);
|
||||
message->setProperty("__SHARDINGKEY", sKey);
|
||||
try {
|
||||
// Constructing SelectMessageQueue objects through function pointer callback
|
||||
int retryTimes = 3;
|
||||
SelectMessageQueueInner selectMessageQueue;
|
||||
SendResult sendResult =
|
||||
defaultMQProducer->innerProducer->send(*message, &selectMessageQueue, (void*)shardingKey, retryTimes);
|
||||
// Convert SendStatus to CSendStatus
|
||||
result->sendStatus = CSendStatus((int)sendResult.getSendStatus());
|
||||
result->offset = sendResult.getQueueOffset();
|
||||
strncpy(result->msgId, sendResult.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1);
|
||||
result->msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0;
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_SEND_ORDERLY_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SendMessageTransaction(CProducer* producer,
|
||||
CMessage* msg,
|
||||
CLocalTransactionExecutorCallback callback,
|
||||
void* userData,
|
||||
CSendResult* result) {
|
||||
if (producer == NULL || msg == NULL || callback == NULL || result == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
try {
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
MQMessage* message = (MQMessage*)msg;
|
||||
MyLocalTransactionExecuterInner executerInner(callback, msg, userData);
|
||||
// defaultMQProducer->listenerInner->setM_m_ExcutorCallback(callback);
|
||||
SendResult sendResult =
|
||||
defaultMQProducer->innerTransactionProducer->sendMessageInTransaction(*message, &executerInner);
|
||||
result->sendStatus = CSendStatus((int)sendResult.getSendStatus());
|
||||
result->offset = sendResult.getQueueOffset();
|
||||
strncpy(result->msgId, sendResult.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1);
|
||||
result->msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0;
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_SEND_TRANSACTION_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
int SetProducerGroupName(CProducer* producer, const char* groupName) {
|
||||
if (producer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
try {
|
||||
if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
|
||||
defaultMQProducer->innerTransactionProducer->setGroupName(groupName);
|
||||
} else {
|
||||
defaultMQProducer->innerProducer->setGroupName(groupName);
|
||||
}
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_START_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
int SetProducerInstanceName(CProducer* producer, const char* instanceName) {
|
||||
if (producer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
try {
|
||||
if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
|
||||
defaultMQProducer->innerTransactionProducer->setInstanceName(instanceName);
|
||||
} else {
|
||||
defaultMQProducer->innerProducer->setInstanceName(instanceName);
|
||||
}
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_START_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
int SetProducerSessionCredentials(CProducer* producer,
|
||||
const char* accessKey,
|
||||
const char* secretKey,
|
||||
const char* onsChannel) {
|
||||
if (producer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
try {
|
||||
if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
|
||||
defaultMQProducer->innerTransactionProducer->setSessionCredentials(accessKey, secretKey, onsChannel);
|
||||
} else {
|
||||
defaultMQProducer->innerProducer->setSessionCredentials(accessKey, secretKey, onsChannel);
|
||||
}
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_START_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
int SetProducerLogPath(CProducer* producer, const char* logPath) {
|
||||
if (producer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SetProducerLogFileNumAndSize(CProducer* producer, int fileNum, long fileSize) {
|
||||
if (producer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
try {
|
||||
if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
|
||||
defaultMQProducer->innerTransactionProducer->setLogFileSizeAndNum(fileNum, fileSize);
|
||||
} else {
|
||||
defaultMQProducer->innerProducer->setLogFileSizeAndNum(fileNum, fileSize);
|
||||
}
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_START_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SetProducerLogLevel(CProducer* producer, CLogLevel level) {
|
||||
if (producer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
try {
|
||||
if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
|
||||
defaultMQProducer->innerTransactionProducer->setLogLevel((elogLevel)level);
|
||||
} else {
|
||||
defaultMQProducer->innerProducer->setLogLevel((elogLevel)level);
|
||||
}
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_START_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SetProducerSendMsgTimeout(CProducer* producer, int timeout) {
|
||||
if (producer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
try {
|
||||
if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
|
||||
defaultMQProducer->innerTransactionProducer->setSendMsgTimeout(timeout);
|
||||
} else {
|
||||
defaultMQProducer->innerProducer->setSendMsgTimeout(timeout);
|
||||
}
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_START_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SetProducerCompressMsgBodyOverHowmuch(CProducer* producer, int howmuch) {
|
||||
if (producer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
try {
|
||||
if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
|
||||
defaultMQProducer->innerTransactionProducer->setCompressMsgBodyOverHowmuch(howmuch);
|
||||
} else {
|
||||
defaultMQProducer->innerProducer->setCompressMsgBodyOverHowmuch(howmuch);
|
||||
}
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_START_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SetProducerCompressLevel(CProducer* producer, int level) {
|
||||
if (producer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
try {
|
||||
if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
|
||||
defaultMQProducer->innerTransactionProducer->setCompressLevel(level);
|
||||
} else {
|
||||
defaultMQProducer->innerProducer->setCompressLevel(level);
|
||||
}
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_START_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SetProducerMaxMessageSize(CProducer* producer, int size) {
|
||||
if (producer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
try {
|
||||
if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
|
||||
defaultMQProducer->innerTransactionProducer->setMaxMessageSize(size);
|
||||
} else {
|
||||
defaultMQProducer->innerProducer->setMaxMessageSize(size);
|
||||
}
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_START_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
int SetProducerMessageTrace(CProducer* producer, CTraceModel openTrace) {
|
||||
if (producer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
|
||||
bool messageTrace = openTrace == OPEN ? true : false;
|
||||
try {
|
||||
if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
|
||||
defaultMQProducer->innerTransactionProducer->setMessageTrace(messageTrace);
|
||||
} else {
|
||||
defaultMQProducer->innerProducer->setMessageTrace(messageTrace);
|
||||
}
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PRODUCER_START_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
259
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/extern/CPullConsumer.cpp
vendored
Normal file
259
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/extern/CPullConsumer.cpp
vendored
Normal file
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "CPullConsumer.h"
|
||||
#include "CCommon.h"
|
||||
#include "CMessageExt.h"
|
||||
#include "DefaultMQPullConsumer.h"
|
||||
#include "MQClientErrorContainer.h"
|
||||
|
||||
using namespace rocketmq;
|
||||
using namespace std;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
char VERSION_FOR_PULL_CONSUMER[MAX_SDK_VERSION_LENGTH];
|
||||
CPullConsumer* CreatePullConsumer(const char* groupId) {
|
||||
if (groupId == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
DefaultMQPullConsumer* defaultMQPullConsumer = new DefaultMQPullConsumer(groupId);
|
||||
strncpy(VERSION_FOR_PULL_CONSUMER, defaultMQPullConsumer->version().c_str(), MAX_SDK_VERSION_LENGTH - 1);
|
||||
VERSION_FOR_PULL_CONSUMER[MAX_SDK_VERSION_LENGTH - 1] = 0;
|
||||
return (CPullConsumer*)defaultMQPullConsumer;
|
||||
}
|
||||
int DestroyPullConsumer(CPullConsumer* consumer) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
delete reinterpret_cast<DefaultMQPullConsumer*>(consumer);
|
||||
return OK;
|
||||
}
|
||||
int StartPullConsumer(CPullConsumer* consumer) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
try {
|
||||
((DefaultMQPullConsumer*)consumer)->start();
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PULLCONSUMER_START_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
int ShutdownPullConsumer(CPullConsumer* consumer) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPullConsumer*)consumer)->shutdown();
|
||||
return OK;
|
||||
}
|
||||
const char* ShowPullConsumerVersion(CPullConsumer* consumer) {
|
||||
if (consumer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return VERSION_FOR_PULL_CONSUMER;
|
||||
}
|
||||
|
||||
int SetPullConsumerGroupID(CPullConsumer* consumer, const char* groupId) {
|
||||
if (consumer == NULL || groupId == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPullConsumer*)consumer)->setGroupName(groupId);
|
||||
return OK;
|
||||
}
|
||||
const char* GetPullConsumerGroupID(CPullConsumer* consumer) {
|
||||
if (consumer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return ((DefaultMQPullConsumer*)consumer)->getGroupName().c_str();
|
||||
}
|
||||
int SetPullConsumerNameServerAddress(CPullConsumer* consumer, const char* namesrv) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPullConsumer*)consumer)->setNamesrvAddr(namesrv);
|
||||
return OK;
|
||||
}
|
||||
int SetPullConsumerNameServerDomain(CPullConsumer* consumer, const char* domain) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPullConsumer*)consumer)->setNamesrvDomain(domain);
|
||||
return OK;
|
||||
}
|
||||
int SetPullConsumerSessionCredentials(CPullConsumer* consumer,
|
||||
const char* accessKey,
|
||||
const char* secretKey,
|
||||
const char* channel) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPullConsumer*)consumer)->setSessionCredentials(accessKey, secretKey, channel);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SetPullConsumerLogPath(CPullConsumer* consumer, const char* logPath) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
// Todo, This api should be implemented by core api.
|
||||
//((DefaultMQPullConsumer *) consumer)->setInstanceName(instanceName);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SetPullConsumerLogFileNumAndSize(CPullConsumer* consumer, int fileNum, long fileSize) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPullConsumer*)consumer)->setLogFileSizeAndNum(fileNum, fileSize);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SetPullConsumerLogLevel(CPullConsumer* consumer, CLogLevel level) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPullConsumer*)consumer)->setLogLevel((elogLevel)level);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int FetchSubscriptionMessageQueues(CPullConsumer* consumer, const char* topic, CMessageQueue** mqs, int* size) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
unsigned int index = 0;
|
||||
CMessageQueue* temMQ = NULL;
|
||||
std::vector<MQMessageQueue> fullMQ;
|
||||
try {
|
||||
((DefaultMQPullConsumer*)consumer)->fetchSubscribeMessageQueues(topic, fullMQ);
|
||||
*size = fullMQ.size();
|
||||
// Alloc memory to save the pointer to CPP MessageQueue, and the MessageQueues may be changed.
|
||||
// Thus, this memory should be released by users using @ReleaseSubscribeMessageQueue every time.
|
||||
temMQ = (CMessageQueue*)malloc(*size * sizeof(CMessageQueue));
|
||||
if (temMQ == NULL) {
|
||||
*size = 0;
|
||||
*mqs = NULL;
|
||||
return MALLOC_FAILED;
|
||||
}
|
||||
auto iter = fullMQ.begin();
|
||||
for (index = 0; iter != fullMQ.end() && index <= fullMQ.size(); ++iter, index++) {
|
||||
strncpy(temMQ[index].topic, iter->getTopic().c_str(), MAX_TOPIC_LENGTH - 1);
|
||||
strncpy(temMQ[index].brokerName, iter->getBrokerName().c_str(), MAX_BROKER_NAME_ID_LENGTH - 1);
|
||||
temMQ[index].queueId = iter->getQueueId();
|
||||
}
|
||||
*mqs = temMQ;
|
||||
} catch (MQException& e) {
|
||||
*size = 0;
|
||||
*mqs = NULL;
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PULLCONSUMER_FETCH_MQ_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
int ReleaseSubscriptionMessageQueue(CMessageQueue* mqs) {
|
||||
if (mqs == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
free((void*)mqs);
|
||||
mqs = NULL;
|
||||
return OK;
|
||||
}
|
||||
CPullResult Pull(CPullConsumer* consumer,
|
||||
const CMessageQueue* mq,
|
||||
const char* subExpression,
|
||||
long long offset,
|
||||
int maxNums) {
|
||||
CPullResult pullResult;
|
||||
memset(&pullResult, 0, sizeof(CPullResult));
|
||||
if (consumer == NULL || subExpression == NULL) {
|
||||
pullResult.pullStatus = E_BROKER_TIMEOUT;
|
||||
return pullResult;
|
||||
}
|
||||
MQMessageQueue messageQueue(mq->topic, mq->brokerName, mq->queueId);
|
||||
PullResult cppPullResult;
|
||||
try {
|
||||
cppPullResult = ((DefaultMQPullConsumer*)consumer)->pull(messageQueue, subExpression, offset, maxNums);
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
cppPullResult.pullStatus = BROKER_TIMEOUT;
|
||||
}
|
||||
|
||||
if (cppPullResult.pullStatus != BROKER_TIMEOUT) {
|
||||
pullResult.maxOffset = cppPullResult.maxOffset;
|
||||
pullResult.minOffset = cppPullResult.minOffset;
|
||||
pullResult.nextBeginOffset = cppPullResult.nextBeginOffset;
|
||||
}
|
||||
|
||||
switch (cppPullResult.pullStatus) {
|
||||
case FOUND: {
|
||||
pullResult.pullStatus = E_FOUND;
|
||||
pullResult.size = cppPullResult.msgFoundList.size();
|
||||
PullResult* tmpPullResult = new PullResult(cppPullResult);
|
||||
pullResult.pData = tmpPullResult;
|
||||
// Alloc memory to save the pointer to CPP MQMessageExt, which will be release by the CPP SDK core.
|
||||
// Thus, this memory should be released by users using @ReleasePullResult
|
||||
pullResult.msgFoundList = (CMessageExt**)malloc(pullResult.size * sizeof(CMessageExt*));
|
||||
for (size_t i = 0; i < cppPullResult.msgFoundList.size(); i++) {
|
||||
MQMessageExt* msg = const_cast<MQMessageExt*>(&tmpPullResult->msgFoundList[i]);
|
||||
pullResult.msgFoundList[i] = (CMessageExt*)(msg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NO_NEW_MSG: {
|
||||
pullResult.pullStatus = E_NO_NEW_MSG;
|
||||
break;
|
||||
}
|
||||
case NO_MATCHED_MSG: {
|
||||
pullResult.pullStatus = E_NO_MATCHED_MSG;
|
||||
break;
|
||||
}
|
||||
case OFFSET_ILLEGAL: {
|
||||
pullResult.pullStatus = E_OFFSET_ILLEGAL;
|
||||
break;
|
||||
}
|
||||
case BROKER_TIMEOUT: {
|
||||
pullResult.pullStatus = E_BROKER_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
pullResult.pullStatus = E_NO_NEW_MSG;
|
||||
break;
|
||||
}
|
||||
return pullResult;
|
||||
}
|
||||
int ReleasePullResult(CPullResult pullResult) {
|
||||
if (pullResult.size == 0 || pullResult.msgFoundList == NULL || pullResult.pData == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
if (pullResult.pData != NULL) {
|
||||
try {
|
||||
delete ((PullResult*)pullResult.pData);
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return NULL_POINTER;
|
||||
}
|
||||
}
|
||||
free((void*)pullResult.msgFoundList);
|
||||
pullResult.msgFoundList = NULL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
309
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/extern/CPushConsumer.cpp
vendored
Normal file
309
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/extern/CPushConsumer.cpp
vendored
Normal file
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "CPushConsumer.h"
|
||||
#include <map>
|
||||
#include "CCommon.h"
|
||||
#include "CMessageExt.h"
|
||||
#include "DefaultMQPushConsumer.h"
|
||||
#include "MQClientErrorContainer.h"
|
||||
|
||||
using namespace rocketmq;
|
||||
using namespace std;
|
||||
|
||||
class MessageListenerInner : public MessageListenerConcurrently {
|
||||
public:
|
||||
MessageListenerInner() {}
|
||||
|
||||
MessageListenerInner(CPushConsumer* consumer, MessageCallBack pCallback) {
|
||||
m_pconsumer = consumer;
|
||||
m_pMsgReceiveCallback = pCallback;
|
||||
}
|
||||
|
||||
~MessageListenerInner() {}
|
||||
|
||||
ConsumeStatus consumeMessage(const std::vector<MQMessageExt>& msgs) {
|
||||
// to do user call back
|
||||
if (m_pMsgReceiveCallback == NULL) {
|
||||
return RECONSUME_LATER;
|
||||
}
|
||||
for (size_t i = 0; i < msgs.size(); ++i) {
|
||||
MQMessageExt* msg = const_cast<MQMessageExt*>(&msgs[i]);
|
||||
CMessageExt* message = (CMessageExt*)(msg);
|
||||
if (m_pMsgReceiveCallback(m_pconsumer, message) != E_CONSUME_SUCCESS)
|
||||
return RECONSUME_LATER;
|
||||
}
|
||||
return CONSUME_SUCCESS;
|
||||
}
|
||||
|
||||
private:
|
||||
MessageCallBack m_pMsgReceiveCallback;
|
||||
CPushConsumer* m_pconsumer;
|
||||
};
|
||||
|
||||
class MessageListenerOrderlyInner : public MessageListenerOrderly {
|
||||
public:
|
||||
MessageListenerOrderlyInner(CPushConsumer* consumer, MessageCallBack pCallback) {
|
||||
m_pconsumer = consumer;
|
||||
m_pMsgReceiveCallback = pCallback;
|
||||
}
|
||||
|
||||
ConsumeStatus consumeMessage(const std::vector<MQMessageExt>& msgs) {
|
||||
if (m_pMsgReceiveCallback == NULL) {
|
||||
return RECONSUME_LATER;
|
||||
}
|
||||
for (size_t i = 0; i < msgs.size(); ++i) {
|
||||
MQMessageExt* msg = const_cast<MQMessageExt*>(&msgs[i]);
|
||||
CMessageExt* message = (CMessageExt*)(msg);
|
||||
if (m_pMsgReceiveCallback(m_pconsumer, message) != E_CONSUME_SUCCESS)
|
||||
return RECONSUME_LATER;
|
||||
}
|
||||
return CONSUME_SUCCESS;
|
||||
}
|
||||
|
||||
private:
|
||||
MessageCallBack m_pMsgReceiveCallback;
|
||||
CPushConsumer* m_pconsumer;
|
||||
};
|
||||
|
||||
map<CPushConsumer*, MessageListenerInner*> g_ListenerMap;
|
||||
map<CPushConsumer*, MessageListenerOrderlyInner*> g_OrderListenerMap;
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
char VERSION_FOR_PUSH_CONSUMER[MAX_SDK_VERSION_LENGTH];
|
||||
CPushConsumer* CreatePushConsumer(const char* groupId) {
|
||||
if (groupId == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
DefaultMQPushConsumer* defaultMQPushConsumer = new DefaultMQPushConsumer(groupId);
|
||||
defaultMQPushConsumer->setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET);
|
||||
|
||||
strncpy(VERSION_FOR_PUSH_CONSUMER, defaultMQPushConsumer->version().c_str(), MAX_SDK_VERSION_LENGTH - 1);
|
||||
VERSION_FOR_PUSH_CONSUMER[MAX_SDK_VERSION_LENGTH - 1] = 0;
|
||||
return (CPushConsumer*)defaultMQPushConsumer;
|
||||
}
|
||||
int DestroyPushConsumer(CPushConsumer* consumer) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
delete reinterpret_cast<DefaultMQPushConsumer*>(consumer);
|
||||
return OK;
|
||||
}
|
||||
int StartPushConsumer(CPushConsumer* consumer) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
try {
|
||||
((DefaultMQPushConsumer*)consumer)->start();
|
||||
} catch (exception& e) {
|
||||
MQClientErrorContainer::setErr(string(e.what()));
|
||||
return PUSHCONSUMER_START_FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
int ShutdownPushConsumer(CPushConsumer* consumer) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPushConsumer*)consumer)->shutdown();
|
||||
return OK;
|
||||
}
|
||||
|
||||
const char* ShowPushConsumerVersion(CPushConsumer* consumer) {
|
||||
if (consumer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return VERSION_FOR_PUSH_CONSUMER;
|
||||
}
|
||||
int SetPushConsumerGroupID(CPushConsumer* consumer, const char* groupId) {
|
||||
if (consumer == NULL || groupId == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPushConsumer*)consumer)->setGroupName(groupId);
|
||||
return OK;
|
||||
}
|
||||
const char* GetPushConsumerGroupID(CPushConsumer* consumer) {
|
||||
if (consumer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return ((DefaultMQPushConsumer*)consumer)->getGroupName().c_str();
|
||||
}
|
||||
int SetPushConsumerNameServerAddress(CPushConsumer* consumer, const char* namesrv) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPushConsumer*)consumer)->setNamesrvAddr(namesrv);
|
||||
return OK;
|
||||
}
|
||||
int SetPushConsumerNameServerDomain(CPushConsumer* consumer, const char* domain) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPushConsumer*)consumer)->setNamesrvDomain(domain);
|
||||
return OK;
|
||||
}
|
||||
int Subscribe(CPushConsumer* consumer, const char* topic, const char* expression) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPushConsumer*)consumer)->subscribe(topic, expression);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int RegisterMessageCallback(CPushConsumer* consumer, MessageCallBack pCallback) {
|
||||
if (consumer == NULL || pCallback == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
MessageListenerInner* listenerInner = new MessageListenerInner(consumer, pCallback);
|
||||
((DefaultMQPushConsumer*)consumer)->registerMessageListener(listenerInner);
|
||||
g_ListenerMap[consumer] = listenerInner;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int RegisterMessageCallbackOrderly(CPushConsumer* consumer, MessageCallBack pCallback) {
|
||||
if (consumer == NULL || pCallback == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
MessageListenerOrderlyInner* messageListenerOrderlyInner = new MessageListenerOrderlyInner(consumer, pCallback);
|
||||
((DefaultMQPushConsumer*)consumer)->registerMessageListener(messageListenerOrderlyInner);
|
||||
g_OrderListenerMap[consumer] = messageListenerOrderlyInner;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int UnregisterMessageCallbackOrderly(CPushConsumer* consumer) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
map<CPushConsumer*, MessageListenerOrderlyInner*>::iterator iter;
|
||||
iter = g_OrderListenerMap.find(consumer);
|
||||
if (iter != g_OrderListenerMap.end()) {
|
||||
MessageListenerOrderlyInner* listenerInner = iter->second;
|
||||
if (listenerInner != NULL) {
|
||||
delete listenerInner;
|
||||
}
|
||||
g_OrderListenerMap.erase(iter);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int UnregisterMessageCallback(CPushConsumer* consumer) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
map<CPushConsumer*, MessageListenerInner*>::iterator iter;
|
||||
iter = g_ListenerMap.find(consumer);
|
||||
|
||||
if (iter != g_ListenerMap.end()) {
|
||||
MessageListenerInner* listenerInner = iter->second;
|
||||
if (listenerInner != NULL) {
|
||||
delete listenerInner;
|
||||
}
|
||||
g_ListenerMap.erase(iter);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SetPushConsumerMessageModel(CPushConsumer* consumer, CMessageModel messageModel) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPushConsumer*)consumer)->setMessageModel(MessageModel((int)messageModel));
|
||||
return OK;
|
||||
}
|
||||
int SetPushConsumerThreadCount(CPushConsumer* consumer, int threadCount) {
|
||||
if (consumer == NULL || threadCount == 0) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPushConsumer*)consumer)->setConsumeThreadCount(threadCount);
|
||||
return OK;
|
||||
}
|
||||
int SetPushConsumerMessageBatchMaxSize(CPushConsumer* consumer, int batchSize) {
|
||||
if (consumer == NULL || batchSize == 0) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPushConsumer*)consumer)->setConsumeMessageBatchMaxSize(batchSize);
|
||||
return OK;
|
||||
}
|
||||
int SetPushConsumerMaxCacheMessageSize(CPushConsumer* consumer, int maxCacheSize) {
|
||||
if (consumer == NULL || maxCacheSize <= 0) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPushConsumer*)consumer)->setMaxCacheMsgSizePerQueue(maxCacheSize);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SetPushConsumerMaxCacheMessageSizeInMb(CPushConsumer* consumer, int maxCacheSizeInMb) {
|
||||
if (consumer == NULL || maxCacheSizeInMb <= 0) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
return Not_Support;
|
||||
}
|
||||
int SetPushConsumerInstanceName(CPushConsumer* consumer, const char* instanceName) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPushConsumer*)consumer)->setInstanceName(instanceName);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SetPushConsumerSessionCredentials(CPushConsumer* consumer,
|
||||
const char* accessKey,
|
||||
const char* secretKey,
|
||||
const char* channel) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPushConsumer*)consumer)->setSessionCredentials(accessKey, secretKey, channel);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SetPushConsumerLogPath(CPushConsumer* consumer, const char* logPath) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
// Todo, This api should be implemented by core api.
|
||||
//((DefaultMQPushConsumer *) consumer)->setInstanceName(instanceName);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SetPushConsumerLogFileNumAndSize(CPushConsumer* consumer, int fileNum, long fileSize) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPushConsumer*)consumer)->setLogFileSizeAndNum(fileNum, fileSize);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int SetPushConsumerLogLevel(CPushConsumer* consumer, CLogLevel level) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
((DefaultMQPushConsumer*)consumer)->setLogLevel((elogLevel)level);
|
||||
return OK;
|
||||
}
|
||||
int SetPushConsumerMessageTrace(CPushConsumer* consumer, CTraceModel openTrace) {
|
||||
if (consumer == NULL) {
|
||||
return NULL_POINTER;
|
||||
}
|
||||
bool messageTrace = openTrace == OPEN ? true : false;
|
||||
((DefaultMQPushConsumer*)consumer)->setMessageTrace(messageTrace);
|
||||
return OK;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
26
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/extern/CSendResult.cpp
vendored
Normal file
26
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/extern/CSendResult.cpp
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "CSendResult.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
29
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/include/BatchMessage.h
vendored
Normal file
29
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/include/BatchMessage.h
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __BATCHMESSAGE_H__
|
||||
#define __BATCHMESSAGE_H__
|
||||
#include <string>
|
||||
#include "MQMessage.h"
|
||||
namespace rocketmq {
|
||||
class BatchMessage : public MQMessage {
|
||||
public:
|
||||
static std::string encode(std::vector<MQMessage>& msgs);
|
||||
static std::string encode(MQMessage& message);
|
||||
};
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
209
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/include/DefaultMQClient.h
vendored
Normal file
209
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/include/DefaultMQClient.h
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __DEFAULTMQADMIN_H__
|
||||
#define __DEFAULTMQADMIN_H__
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include "MQClient.h"
|
||||
#include "MQMessageExt.h"
|
||||
#include "MQMessageQueue.h"
|
||||
#include "QueryResult.h"
|
||||
#include "RocketMQClient.h"
|
||||
#include "SessionCredentials.h"
|
||||
#include "UtilAll.h"
|
||||
|
||||
namespace rocketmq {
|
||||
class MQClientFactory;
|
||||
//<!***************************************************************************
|
||||
|
||||
class DefaultMQClient {
|
||||
public:
|
||||
DefaultMQClient();
|
||||
virtual ~DefaultMQClient();
|
||||
|
||||
public:
|
||||
// clientid=processId-ipAddr@instanceName;
|
||||
std::string getClientVersionString() const;
|
||||
std::string getMQClientId() const;
|
||||
const std::string& getNamesrvAddr() const;
|
||||
void setNamesrvAddr(const std::string& namesrvAddr);
|
||||
const std::string& getNamesrvDomain() const;
|
||||
void setNamesrvDomain(const std::string& namesrvDomain);
|
||||
const std::string& getInstanceName() const;
|
||||
void setInstanceName(const std::string& instanceName);
|
||||
// nameSpace
|
||||
const std::string& getNameSpace() const;
|
||||
void setNameSpace(const std::string& nameSpace);
|
||||
const std::string& getGroupName() const;
|
||||
void setGroupName(const std::string& groupname);
|
||||
|
||||
/**
|
||||
* no realization
|
||||
*/
|
||||
void createTopic(const std::string& key, const std::string& newTopic, int queueNum);
|
||||
/**
|
||||
* search earliest msg store time for specified queue
|
||||
*
|
||||
* @param mq
|
||||
* message queue
|
||||
* @return earliest store time, ms
|
||||
*/
|
||||
int64 earliestMsgStoreTime(const MQMessageQueue& mq);
|
||||
/**
|
||||
* search maxOffset of queue
|
||||
*
|
||||
* @param mq
|
||||
* message queue
|
||||
* @return minOffset of queue
|
||||
*/
|
||||
int64 minOffset(const MQMessageQueue& mq);
|
||||
/**
|
||||
* search maxOffset of queue
|
||||
* Note: maxOffset-1 is max offset that could get msg
|
||||
* @param mq
|
||||
* message queue
|
||||
* @return maxOffset of queue
|
||||
*/
|
||||
int64 maxOffset(const MQMessageQueue& mq);
|
||||
/**
|
||||
* get queue offset by timestamp
|
||||
*
|
||||
* @param mq
|
||||
* mq queue
|
||||
* @param timestamp
|
||||
* timestamp with ms unit
|
||||
* @return queue offset according to timestamp
|
||||
*/
|
||||
int64 searchOffset(const MQMessageQueue& mq, uint64_t timestamp);
|
||||
/**
|
||||
* get whole msg info from broker by msgId
|
||||
*
|
||||
* @param msgId
|
||||
* @return MQMessageExt
|
||||
*/
|
||||
MQMessageExt* viewMessage(const std::string& msgId);
|
||||
/**
|
||||
* query message by topic and key
|
||||
*
|
||||
* @param topic
|
||||
* topic name
|
||||
* @param key
|
||||
* topic key
|
||||
* @param maxNum
|
||||
* query num
|
||||
* @param begin
|
||||
* begin timestamp
|
||||
* @param end
|
||||
* end timestamp
|
||||
* @return
|
||||
* according to QueryResult
|
||||
*/
|
||||
QueryResult queryMessage(const std::string& topic, const std::string& key, int maxNum, int64 begin, int64 end);
|
||||
|
||||
std::vector<MQMessageQueue> getTopicMessageQueueInfo(const std::string& topic);
|
||||
|
||||
// log configuration interface, default LOG_LEVEL is LOG_LEVEL_INFO, default
|
||||
// log file num is 3, each log size is 100M
|
||||
void setLogLevel(elogLevel inputLevel);
|
||||
elogLevel getLogLevel();
|
||||
void setLogFileSizeAndNum(int fileNum, long perFileSize); // perFileSize is MB unit
|
||||
|
||||
/** set TcpTransport pull thread num, which dermine the num of threads to
|
||||
distribute network data,
|
||||
1. its default value is CPU num, it must be setted before producer/consumer
|
||||
start, minimum value is CPU num;
|
||||
2. this pullThread num must be tested on your environment to find the best
|
||||
value for RT of sendMsg or delay time of consume msg before you change it;
|
||||
3. producer and consumer need different pullThread num, if set this num,
|
||||
producer and consumer must set different instanceName.
|
||||
4. configuration suggestion:
|
||||
1>. minimum RT of sendMsg:
|
||||
pullThreadNum = brokerNum*2
|
||||
**/
|
||||
void setTcpTransportPullThreadNum(int num);
|
||||
int getTcpTransportPullThreadNum() const;
|
||||
|
||||
/** timeout of tcp connect, it is same meaning for both producer and consumer;
|
||||
1. default value is 3000ms
|
||||
2. input parameter could only be milliSecond, suggestion value is
|
||||
1000-3000ms;
|
||||
**/
|
||||
void setTcpTransportConnectTimeout(uint64_t timeout); // ms
|
||||
uint64_t getTcpTransportConnectTimeout() const;
|
||||
|
||||
/** timeout of tryLock tcpTransport before sendMsg/pullMsg, if timeout,
|
||||
returns NULL
|
||||
1. paremeter unit is ms, default value is 3000ms, the minimun value is
|
||||
1000ms
|
||||
suggestion value is 3000ms;
|
||||
2. if configured with value smaller than 1000ms, the tryLockTimeout value
|
||||
will be setted to 1000ms
|
||||
**/
|
||||
void setTcpTransportTryLockTimeout(uint64_t timeout); // ms
|
||||
uint64_t getTcpTransportTryLockTimeout() const;
|
||||
|
||||
void setUnitName(std::string unitName);
|
||||
const std::string& getUnitName() const;
|
||||
|
||||
void setSessionCredentials(const std::string& input_accessKey,
|
||||
const std::string& input_secretKey,
|
||||
const std::string& input_onsChannel);
|
||||
const SessionCredentials& getSessionCredentials() const;
|
||||
|
||||
virtual void setFactory(MQClientFactory*);
|
||||
|
||||
void setEnableSsl(bool enableSsl);
|
||||
bool getEnableSsl() const;
|
||||
|
||||
void setSslPropertyFile(const std::string& sslPropertyFile);
|
||||
const std::string& getSslPropertyFile() const;
|
||||
bool getMessageTrace() const;
|
||||
void setMessageTrace(bool mMessageTrace);
|
||||
|
||||
protected:
|
||||
virtual void start();
|
||||
virtual void shutdown();
|
||||
MQClientFactory* getFactory() const;
|
||||
virtual bool isServiceStateOk();
|
||||
void showClientConfigs();
|
||||
|
||||
protected:
|
||||
std::string m_namesrvAddr;
|
||||
std::string m_namesrvDomain;
|
||||
std::string m_instanceName;
|
||||
std::string m_nameSpace;
|
||||
std::string m_GroupName;
|
||||
std::string m_sslPropertyFile{DEFAULT_SSL_PROPERTY_FILE};
|
||||
bool m_enableSsl{false};
|
||||
MQClientFactory* m_clientFactory;
|
||||
int m_serviceState;
|
||||
int m_pullThreadNum;
|
||||
uint64_t m_tcpConnectTimeout; // ms
|
||||
uint64_t m_tcpTransportTryLockTimeout; // s
|
||||
|
||||
std::string m_unitName;
|
||||
SessionCredentials m_SessionCredentials;
|
||||
bool m_messageTrace;
|
||||
};
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
68
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/include/MQConsumer.h
vendored
Normal file
68
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/include/MQConsumer.h
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __MQCONSUMER_H__
|
||||
#define __MQCONSUMER_H__
|
||||
|
||||
#include <string>
|
||||
#include "AsyncCallback.h"
|
||||
#include "ConsumeType.h"
|
||||
#include "DefaultMQClient.h"
|
||||
#include "RocketMQClient.h"
|
||||
|
||||
namespace rocketmq {
|
||||
class SubscriptionData;
|
||||
class PullRequest;
|
||||
class Rebalance;
|
||||
class ConsumerRunningInfo;
|
||||
//<!************************************************************************
|
||||
class MQConsumer : public DefaultMQClient {
|
||||
public:
|
||||
virtual ~MQConsumer() {}
|
||||
virtual bool sendMessageBack(MQMessageExt& msg, int delayLevel, std::string& brokerName) = 0;
|
||||
virtual void fetchSubscribeMessageQueues(const std::string& topic, std::vector<MQMessageQueue>& mqs) = 0;
|
||||
virtual void doRebalance() = 0;
|
||||
virtual void persistConsumerOffset() = 0;
|
||||
virtual void persistConsumerOffsetByResetOffset() = 0;
|
||||
virtual void updateTopicSubscribeInfo(const std::string& topic, std::vector<MQMessageQueue>& info) = 0;
|
||||
virtual void updateConsumeOffset(const MQMessageQueue& mq, int64 offset) = 0;
|
||||
virtual void removeConsumeOffset(const MQMessageQueue& mq) = 0;
|
||||
virtual ConsumeType getConsumeType() = 0;
|
||||
virtual ConsumeFromWhere getConsumeFromWhere() = 0;
|
||||
virtual void getSubscriptions(std::vector<SubscriptionData>&) = 0;
|
||||
virtual bool producePullMsgTask(boost::weak_ptr<PullRequest>) = 0;
|
||||
virtual Rebalance* getRebalance() const = 0;
|
||||
virtual PullResult pull(const MQMessageQueue& mq, const std::string& subExpression, int64 offset, int maxNums) = 0;
|
||||
virtual void pull(const MQMessageQueue& mq,
|
||||
const std::string& subExpression,
|
||||
int64 offset,
|
||||
int maxNums,
|
||||
PullCallback* pPullCallback) = 0;
|
||||
virtual ConsumerRunningInfo* getConsumerRunningInfo() = 0;
|
||||
|
||||
public:
|
||||
MessageModel getMessageModel() const { return m_messageModel; }
|
||||
void setMessageModel(MessageModel messageModel) { m_messageModel = messageModel; }
|
||||
bool isUseNameSpaceMode() const { return m_useNameSpaceMode; }
|
||||
|
||||
protected:
|
||||
MessageModel m_messageModel;
|
||||
bool m_useNameSpaceMode = false;
|
||||
};
|
||||
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
61
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/include/MQProducer.h
vendored
Normal file
61
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/include/MQProducer.h
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __MQPRODUCER_H__
|
||||
#define __MQPRODUCER_H__
|
||||
|
||||
#include "AsyncCallback.h"
|
||||
#include "DefaultMQClient.h"
|
||||
#include "MQMessageQueue.h"
|
||||
#include "MQSelector.h"
|
||||
#include "RocketMQClient.h"
|
||||
#include "SendResult.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!***************************************************************************
|
||||
class MQProducer : public DefaultMQClient {
|
||||
public:
|
||||
MQProducer() {}
|
||||
virtual ~MQProducer() {}
|
||||
// if setted bActiveBroker, will search brokers with best service state
|
||||
// firstly, then search brokers that had been sent failed by last time;
|
||||
virtual SendResult send(MQMessage& msg, bool bSelectActiveBroker = false) = 0;
|
||||
virtual SendResult send(MQMessage& msg, const MQMessageQueue& mq) = 0;
|
||||
// strict order msg, if send failed on seleted MessageQueue, throw exception
|
||||
// to up layer
|
||||
virtual SendResult send(MQMessage& msg, MessageQueueSelector* selector, void* arg) = 0;
|
||||
// non-strict order msg, if send failed on seleted MessageQueue, will auto
|
||||
// retry others Broker queues with autoRetryTimes;
|
||||
// if setted bActiveBroker, if send failed on seleted MessageQueue, , and then
|
||||
// search brokers with best service state, lastly will search brokers that had
|
||||
// been sent failed by last time;
|
||||
virtual SendResult send(MQMessage& msg,
|
||||
MessageQueueSelector* selector,
|
||||
void* arg,
|
||||
int autoRetryTimes,
|
||||
bool bActiveBroker = false) = 0;
|
||||
virtual void send(MQMessage& msg, SendCallback* sendCallback, bool bSelectActiveBroker = false) = 0;
|
||||
virtual void send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* sendCallback) = 0;
|
||||
virtual void send(MQMessage& msg, MessageQueueSelector* selector, void* arg, SendCallback* sendCallback) = 0;
|
||||
virtual SendResult send(std::vector<MQMessage>& msgs) = 0;
|
||||
virtual SendResult send(std::vector<MQMessage>& msgs, const MQMessageQueue& mq) = 0;
|
||||
virtual void sendOneway(MQMessage& msg, bool bSelectActiveBroker = false) = 0;
|
||||
virtual void sendOneway(MQMessage& msg, const MQMessageQueue& mq) = 0;
|
||||
virtual void sendOneway(MQMessage& msg, MessageQueueSelector* selector, void* arg) = 0;
|
||||
};
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
42
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/include/QueryResult.h
vendored
Normal file
42
source/third_party/rocketmq-client-cpp-2.2.0-source-release/src/include/QueryResult.h
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __QUERYRESULT_H__
|
||||
#define __QUERYRESULT_H__
|
||||
|
||||
#include "MQMessageExt.h"
|
||||
#include "RocketMQClient.h"
|
||||
|
||||
namespace rocketmq {
|
||||
//<!************************************************************************
|
||||
class ROCKETMQCLIENT_API QueryResult {
|
||||
public:
|
||||
QueryResult(uint64 indexLastUpdateTimestamp, const std::vector<MQMessageExt*>& messageList) {
|
||||
m_indexLastUpdateTimestamp = indexLastUpdateTimestamp;
|
||||
m_messageList = messageList;
|
||||
}
|
||||
|
||||
uint64 getIndexLastUpdateTimestamp() { return m_indexLastUpdateTimestamp; }
|
||||
|
||||
std::vector<MQMessageExt*>& getMessageList() { return m_messageList; }
|
||||
|
||||
private:
|
||||
uint64 m_indexLastUpdateTimestamp;
|
||||
std::vector<MQMessageExt*> m_messageList;
|
||||
};
|
||||
//<!***************************************************************************
|
||||
} // namespace rocketmq
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user