From e7427c68aeaa09d664864b85e5200ea24baa4e1e Mon Sep 17 00:00:00 2001 From: James Yin Date: Thu, 27 Feb 2020 16:03:30 +0800 Subject: [PATCH 01/62] reconstructed Apache RocketMQ cpp client (#231) --- .gitignore | 12 +- CMakeLists.txt | 98 +- README.md | 236 ++- cmake/BundleStaticLibrary.cmake | 134 ++ cmake/FindJsoncpp.cmake | 84 +- cmake/FindLibevent.cmake | 175 +- distribution/deploy.sh | 2 +- .../Arg_helper.cpp => example/ArgHelper.cpp | 21 +- include/Arg_helper.h => example/ArgHelper.h | 17 +- example/AsyncProducer.cpp | 139 +- example/AsyncPushConsumer.cpp | 111 -- example/BatchProducer.cpp | 130 +- example/CAsyncProducer.c | 8 +- example/CBatchProducer.c | 8 +- example/CMakeLists.txt | 16 +- example/COrderlyAsyncProducer.c | 8 +- example/OrderProducer.cpp | 108 -- example/OrderlyProducer.cpp | 103 ++ example/OrderlyPushConsumer.cpp | 121 +- example/Producer.c | 62 +- example/PullConsumeMessage.c | 9 +- example/PullConsumer.cpp | 42 +- example/PushConsumeMessage.c | 7 +- example/PushConsumer.cpp | 140 +- example/PushConsumerOrderly.c | 8 +- example/SendDelayMsg.cpp | 69 +- example/SyncProducer.cpp | 107 +- example/TransactionProducer.cpp | 100 +- example/common.h | 178 +- .../AllocateMQStrategy.h | 75 +- include/AsyncCallback.h | 58 - {src/common => include}/ClientRPCHook.h | 40 +- .../CommandCustomHeader.h | 36 +- include/ConsumeType.h | 124 +- include/DefaultMQConsumer.h | 38 + include/DefaultMQProducer.h | 257 +-- include/DefaultMQPullConsumer.h | 241 ++- include/DefaultMQPushConsumer.h | 290 ++-- include/MQAdmin.h | 103 ++ include/MQClient.h | 202 --- include/MQClientConfig.h | 96 ++ include/MQClientException.h | 73 +- include/MQConsumer.h | 113 +- include/MQMessage.h | 94 +- include/MQMessageConst.h | 64 + include/MQMessageExt.h | 121 +- include/MQMessageListener.h | 164 +- include/MQMessageQueue.h | 127 +- include/MQProducer.h | 142 +- include/MQPullConsumer.h | 103 ++ include/MQPushConsumer.h | 41 + include/MQSelector.h | 69 +- include/MQueueListener.h | 72 +- include/PullCallback.h | 44 + include/PullResult.h | 142 +- include/QueryResult.h | 84 +- include/RPCHook.h | 44 + include/RemotingCommand.h | 127 ++ include/RocketMQClient.h | 131 +- include/SendCallback.h | 45 + include/SendMessageHook.h | 94 +- include/SendResult.h | 127 +- include/SessionCredentials.h | 60 +- {src/common => include}/TopicFilterType.h | 13 +- include/TransactionListener.h | 14 +- include/TransactionMQProducer.h | 72 +- include/TransactionSendResult.h | 18 +- include/{ => c}/CBatchMessage.h | 7 +- include/{ => c}/CCommon.h | 13 +- include/{ => c}/CErrorMessage.h | 8 +- include/{ => c}/CMQException.h | 4 +- include/{ => c}/CMessage.h | 5 +- include/{ => c}/CMessageExt.h | 4 +- include/{ => c}/CMessageQueue.h | 4 +- include/{ => c}/CProducer.h | 6 +- include/{ => c}/CPullConsumer.h | 4 +- include/{ => c}/CPullResult.h | 5 +- include/{ => c}/CPushConsumer.h | 4 +- include/{ => c}/CSendResult.h | 5 +- include/{ => c}/CTransactionStatus.h | 5 +- libs/signature/CMakeLists.txt | 4 +- libs/signature/include/spas_client.h | 12 +- project/CMakeLists.txt | 58 +- src/ClientRemotingProcessor.cpp | 158 ++ src/ClientRemotingProcessor.h | 55 + src/MQAdminImpl.cpp | 136 ++ src/MQAdminImpl.h | 52 + src/MQClientAPIImpl.cpp | 1262 ++++++-------- src/MQClientAPIImpl.h | 350 ++-- src/MQClientConfig.cpp | 116 ++ src/MQClientFactory.cpp | 1211 -------------- src/MQClientFactory.h | 217 --- src/MQClientImpl.cpp | 90 + src/MQClientImpl.h | 64 + src/MQClientInstance.cpp | 962 +++++++++++ src/MQClientInstance.h | 204 +++ src/MQClientManager.cpp | 50 +- src/MQClientManager.h | 31 +- src/common/AsyncCallbackWrap.cpp | 192 --- src/common/AsyncCallbackWrap.h | 80 - src/common/ByteOrder.h | 458 +++--- src/common/ClientRPCHook.cpp | 88 +- src/common/CommunicationMode.h | 13 +- src/common/DataBlock.cpp | 239 +++ src/common/DataBlock.h | 211 +++ src/common/FilterAPI.h | 46 +- src/common/InputStream.cpp | 225 +-- src/common/InputStream.h | 387 +++-- .../common/InvokeCallback.h | 19 +- src/common/MQClient.cpp | 224 --- src/common/MQVersion.cpp | 4 +- src/common/MQVersion.h | 10 +- src/common/MemoryInputStream.cpp | 157 +- src/common/MemoryInputStream.h | 191 ++- src/common/MemoryOutputStream.cpp | 329 ++-- src/common/MemoryOutputStream.h | 259 ++- src/common/MessageAccessor.cpp | 56 - src/common/MessageSysFlag.cpp | 20 +- src/common/MessageSysFlag.h | 27 +- src/common/NameSpaceUtil.cpp | 61 +- src/common/NameSpaceUtil.h | 30 +- src/common/NamesrvConfig.h | 18 +- src/common/OutputStream.cpp | 211 +-- src/common/OutputStream.h | 295 ++-- src/common/PermName.cpp | 9 +- src/common/PermName.h | 12 +- src/common/PullCallbackWrap.cpp | 59 + src/common/{url.h => PullCallbackWrap.h} | 32 +- src/common/PullSysFlag.cpp | 5 +- src/common/PullSysFlag.h | 13 +- src/common/SendCallbackWrap.cpp | 193 +++ src/common/SendCallbackWrap.h | 72 + src/common/ServiceState.h | 13 +- src/common/ServiceThread.cpp | 86 + src/common/ServiceThread.h | 66 + src/{consumer => common}/SubscriptionData.h | 55 +- src/common/SubscriptionGroupConfig.h | 15 +- src/common/TopAddressing.cpp | 105 -- src/common/TopicConfig.cpp | 26 +- src/common/TopicConfig.h | 31 +- src/common/UtilAll.cpp | 435 +++-- src/common/UtilAll.h | 191 ++- src/common/Validators.cpp | 46 +- src/common/Validators.h | 20 +- src/common/VirtualEnvUtil.cpp | 15 +- src/common/VirtualEnvUtil.h | 13 +- src/common/big_endian.cpp | 4 +- src/common/big_endian.h | 3 +- src/common/dataBlock.cpp | 207 --- src/common/dataBlock.h | 208 --- src/common/noncopyable.h | 2 +- src/common/sync_http_client.cpp | 151 -- src/common/url.cpp | 65 - src/concurrent/concurrent_queue.hpp | 143 ++ src/concurrent/executor.hpp | 86 + src/concurrent/executor_impl.hpp | 306 ++++ src/concurrent/latch.hpp | 146 ++ src/concurrent/thread.hpp | 168 ++ src/concurrent/thread_group.hpp | 93 ++ src/concurrent/time.hpp | 51 + ...cateMQStrategy.h => AllocateMQAveragely.h} | 44 +- .../ConsumeMessageConcurrentlyService.cpp | 411 ++--- src/consumer/ConsumeMessageOrderlyService.cpp | 439 +++-- src/consumer/ConsumeMsgService.h | 224 ++- src/consumer/DefaultMQPullConsumer.cpp | 407 +---- src/consumer/DefaultMQPullConsumerImpl.cpp | 374 +++++ src/consumer/DefaultMQPullConsumerImpl.h | 173 ++ src/consumer/DefaultMQPushConsumer.cpp | 1024 +----------- src/consumer/DefaultMQPushConsumerImpl.cpp | 603 +++++++ src/consumer/DefaultMQPushConsumerImpl.h | 153 ++ src/consumer/FindBrokerResult.h | 10 +- src/consumer/MQConsumerInner.h | 49 + src/consumer/MessageQueueLock.hpp | 48 + src/consumer/OffsetStore.cpp | 402 +++-- src/consumer/OffsetStore.h | 97 +- src/consumer/ProcessQueue.cpp | 226 +++ src/consumer/ProcessQueue.h | 101 ++ src/consumer/PullAPIWrapper.cpp | 270 +-- src/consumer/PullAPIWrapper.h | 129 +- src/consumer/PullMessageService.h | 75 + src/consumer/PullRequest.cpp | 345 +--- src/consumer/PullRequest.h | 106 +- src/consumer/PullResult.cpp | 100 +- src/consumer/PullResultExt.h | 39 +- src/consumer/Rebalance.cpp | 657 -------- src/consumer/Rebalance.h | 137 -- src/consumer/RebalanceImpl.cpp | 524 ++++++ src/consumer/RebalanceImpl.h | 113 ++ src/consumer/RebalancePullImpl.cpp | 48 + src/consumer/RebalancePullImpl.h | 54 + src/consumer/RebalancePushImpl.cpp | 152 ++ src/consumer/RebalancePushImpl.h | 49 + src/consumer/RebalanceService.h | 49 + src/consumer/SubscriptionData.cpp | 67 +- src/extern/CBatchMessage.cpp | 23 +- src/extern/CErrorMessage.cpp | 8 +- src/extern/CMessage.cpp | 56 +- src/extern/CMessageExt.cpp | 15 +- src/extern/CProducer.cpp | 464 +----- src/extern/CPullConsumer.cpp | 74 +- src/extern/CPushConsumer.cpp | 103 +- src/extern/CSendResult.cpp | 11 +- .../MQClientErrorContainer.cpp | 0 .../MQClientErrorContainer.h | 1 - src/log/Logging.cpp | 121 +- src/log/Logging.h | 124 +- src/message/BatchMessage.cpp | 62 - src/message/MQDecoder.cpp | 578 ++++--- src/message/MQDecoder.h | 37 +- src/message/MQMessage.cpp | 266 ++- src/message/MQMessageExt.cpp | 187 ++- src/message/MQMessageId.h | 20 +- src/message/MQMessageQueue.cpp | 10 +- src/message/MessageAccessor.h | 51 + src/message/MessageBatch.cpp | 63 + .../MessageBatch.h} | 33 +- .../MessageClientIDSetter.cpp} | 63 +- .../MessageClientIDSetter.h} | 45 +- src/producer/DefaultMQProducer.cpp | 635 +------- src/producer/DefaultMQProducerImpl.cpp | 767 +++++++++ src/producer/DefaultMQProducerImpl.h | 155 ++ src/producer/LatencyFaultTolerancyImpl.cpp | 94 ++ src/producer/LatencyFaultTolerancyImpl.h | 87 + src/producer/MQFaultStrategy.cpp | 82 + src/producer/MQFaultStrategy.h | 66 + src/producer/MQProducerInner.h | 43 + src/producer/SendResult.cpp | 29 +- src/producer/TopicPublishInfo.h | 270 +-- src/producer/TransactionMQProducer.cpp | 200 +-- src/protocol/CommandHeader.cpp | 1447 +++++++++-------- src/protocol/CommandHeader.h | 656 ++++---- src/protocol/ConsumerRunningInfo.cpp | 106 +- src/protocol/ConsumerRunningInfo.h | 86 +- src/protocol/HeartbeatData.h | 98 +- src/protocol/KVTable.h | 21 +- src/protocol/LockBatchBody.cpp | 147 +- src/protocol/LockBatchBody.h | 78 +- src/protocol/MQProtos.h | 397 ++--- src/protocol/MessageQueue.cpp | 96 +- src/protocol/MessageQueue.h | 85 +- src/protocol/ProcessQueueInfo.h | 132 +- src/protocol/RemotingCommand.cpp | 354 ++-- src/protocol/RemotingCommand.h | 97 -- src/protocol/RemotingSerializable.cpp | 91 ++ src/protocol/RemotingSerializable.h | 45 +- src/protocol/TopicList.h | 20 +- src/protocol/TopicRouteData.h | 62 +- src/thread/disruptor/batch_descriptor.h | 70 - src/thread/disruptor/claim_strategy.h | 231 --- src/thread/disruptor/event_processor.h | 130 -- src/thread/disruptor/event_publisher.h | 50 - src/thread/disruptor/exception_handler.h | 59 - src/thread/disruptor/exceptions.h | 38 - src/thread/disruptor/interface.h | 278 ---- src/thread/disruptor/ring_buffer.h | 90 - src/thread/disruptor/sequence.h | 139 -- src/thread/disruptor/sequence_barrier.h | 92 -- src/thread/disruptor/sequencer.h | 190 --- src/thread/disruptor/utils.h | 35 - src/thread/disruptor/wait_strategy.h | 372 ----- src/thread/disruptorLFQ.h | 117 -- src/thread/task_queue.cpp | 105 -- src/thread/task_queue.h | 745 --------- src/transport/ClientRemotingProcessor.cpp | 193 --- src/transport/ClientRemotingProcessor.h | 67 - src/transport/EventLoop.cpp | 137 +- src/transport/EventLoop.h | 48 +- .../RequestProcessor.h} | 18 +- src/transport/ResponseFuture.cpp | 176 +- src/transport/ResponseFuture.h | 90 +- src/transport/SocketUtil.cpp | 182 ++- src/transport/SocketUtil.h | 59 +- src/transport/TcpRemotingClient.cpp | 861 +++++----- src/transport/TcpRemotingClient.h | 150 +- src/transport/TcpTransport.cpp | 258 ++- src/transport/TcpTransport.h | 57 +- test/CMakeLists.txt | 63 +- test/src/{message => }/BatchMessageTest.cpp | 0 test/src/MQClientAPIImpTest.cpp | 197 --- test/src/MQClientFactoryTest.cpp | 106 -- test/src/MQClientManagerTest.cpp | 49 - test/src/{producer => }/StringIdMakerTest.cpp | 0 test/src/common/MQVersionTest.cpp | 45 - test/src/common/UrlTest.cpp | 76 - test/src/common/VirtualEnvUtilTest.cpp | 33 +- test/src/extern/CMessageTest.cpp | 32 +- test/src/extern/CProducerTest.cpp | 41 +- test/src/extern/CPullConsumerTest.cpp | 37 +- test/src/extern/CPushConsumerTest.cpp | 4 - test/src/message/MQDecoderTest.cpp | 17 +- test/src/message/MQMessageExtTest.cpp | 2 +- test/src/message/MQMessageTest.cpp | 12 +- test/src/protocol/CommandHeaderTest.cpp | 368 +---- test/src/protocol/ConsumerRunningInfoTest.cpp | 123 +- test/src/protocol/LockBatchBodyTest.cpp | 22 +- .../transport/ClientRemotingProcessorTest.cpp | 5 +- 296 files changed, 19337 insertions(+), 21604 deletions(-) create mode 100644 cmake/BundleStaticLibrary.cmake rename src/common/Arg_helper.cpp => example/ArgHelper.cpp (74%) rename include/Arg_helper.h => example/ArgHelper.h (76%) delete mode 100644 example/AsyncPushConsumer.cpp delete mode 100644 example/OrderProducer.cpp create mode 100644 example/OrderlyProducer.cpp rename src/common/AsyncArg.h => include/AllocateMQStrategy.h (62%) delete mode 100644 include/AsyncCallback.h rename {src/common => include}/ClientRPCHook.h (54%) rename src/common/TopAddressing.h => include/CommandCustomHeader.h (62%) create mode 100644 include/DefaultMQConsumer.h mode change 100644 => 100755 include/DefaultMQPullConsumer.h mode change 100644 => 100755 include/DefaultMQPushConsumer.h create mode 100644 include/MQAdmin.h delete mode 100644 include/MQClient.h create mode 100644 include/MQClientConfig.h mode change 100644 => 100755 include/MQConsumer.h create mode 100644 include/MQMessageConst.h create mode 100644 include/MQPullConsumer.h create mode 100644 include/MQPushConsumer.h create mode 100755 include/PullCallback.h create mode 100644 include/RPCHook.h create mode 100644 include/RemotingCommand.h create mode 100755 include/SendCallback.h rename {src/common => include}/TopicFilterType.h (79%) rename include/{ => c}/CBatchMessage.h (92%) rename include/{ => c}/CCommon.h (94%) rename include/{ => c}/CErrorMessage.h (91%) rename include/{ => c}/CMQException.h (99%) rename include/{ => c}/CMessage.h (98%) rename include/{ => c}/CMessageExt.h (98%) rename include/{ => c}/CMessageQueue.h (97%) rename include/{ => c}/CProducer.h (99%) rename include/{ => c}/CPullConsumer.h (98%) rename include/{ => c}/CPullResult.h (97%) rename include/{ => c}/CPushConsumer.h (99%) rename include/{ => c}/CSendResult.h (97%) rename include/{ => c}/CTransactionStatus.h (96%) create mode 100644 src/ClientRemotingProcessor.cpp create mode 100644 src/ClientRemotingProcessor.h create mode 100644 src/MQAdminImpl.cpp create mode 100644 src/MQAdminImpl.h create mode 100644 src/MQClientConfig.cpp delete mode 100644 src/MQClientFactory.cpp delete mode 100644 src/MQClientFactory.h create mode 100644 src/MQClientImpl.cpp create mode 100644 src/MQClientImpl.h create mode 100644 src/MQClientInstance.cpp create mode 100644 src/MQClientInstance.h delete mode 100644 src/common/AsyncCallbackWrap.cpp delete mode 100644 src/common/AsyncCallbackWrap.h create mode 100644 src/common/DataBlock.cpp create mode 100644 src/common/DataBlock.h rename include/BatchMessage.h => src/common/InvokeCallback.h (76%) delete mode 100644 src/common/MQClient.cpp delete mode 100644 src/common/MessageAccessor.cpp create mode 100755 src/common/PullCallbackWrap.cpp rename src/common/{url.h => PullCallbackWrap.h} (62%) mode change 100644 => 100755 create mode 100755 src/common/SendCallbackWrap.cpp create mode 100755 src/common/SendCallbackWrap.h create mode 100644 src/common/ServiceThread.cpp create mode 100644 src/common/ServiceThread.h rename src/{consumer => common}/SubscriptionData.h (58%) delete mode 100644 src/common/TopAddressing.cpp delete mode 100644 src/common/dataBlock.cpp delete mode 100644 src/common/dataBlock.h delete mode 100644 src/common/sync_http_client.cpp delete mode 100644 src/common/url.cpp create mode 100644 src/concurrent/concurrent_queue.hpp create mode 100644 src/concurrent/executor.hpp create mode 100644 src/concurrent/executor_impl.hpp create mode 100644 src/concurrent/latch.hpp create mode 100644 src/concurrent/thread.hpp create mode 100644 src/concurrent/thread_group.hpp create mode 100644 src/concurrent/time.hpp rename src/consumer/{AllocateMQStrategy.h => AllocateMQAveragely.h} (61%) mode change 100644 => 100755 src/consumer/ConsumeMessageConcurrentlyService.cpp mode change 100644 => 100755 src/consumer/ConsumeMessageOrderlyService.cpp mode change 100644 => 100755 src/consumer/ConsumeMsgService.h create mode 100644 src/consumer/DefaultMQPullConsumerImpl.cpp create mode 100755 src/consumer/DefaultMQPullConsumerImpl.h create mode 100644 src/consumer/DefaultMQPushConsumerImpl.cpp create mode 100755 src/consumer/DefaultMQPushConsumerImpl.h create mode 100644 src/consumer/MQConsumerInner.h create mode 100644 src/consumer/MessageQueueLock.hpp create mode 100644 src/consumer/ProcessQueue.cpp create mode 100644 src/consumer/ProcessQueue.h create mode 100644 src/consumer/PullMessageService.h delete mode 100644 src/consumer/Rebalance.cpp delete mode 100644 src/consumer/Rebalance.h create mode 100644 src/consumer/RebalanceImpl.cpp create mode 100755 src/consumer/RebalanceImpl.h create mode 100644 src/consumer/RebalancePullImpl.cpp create mode 100755 src/consumer/RebalancePullImpl.h create mode 100644 src/consumer/RebalancePushImpl.cpp create mode 100644 src/consumer/RebalancePushImpl.h create mode 100644 src/consumer/RebalanceService.h rename src/{common => extern}/MQClientErrorContainer.cpp (100%) rename src/{common => extern}/MQClientErrorContainer.h (98%) delete mode 100644 src/message/BatchMessage.cpp create mode 100644 src/message/MessageAccessor.h create mode 100644 src/message/MessageBatch.cpp rename src/{common/MessageAccessor.h => message/MessageBatch.h} (62%) rename src/{producer/StringIdMaker.cpp => message/MessageClientIDSetter.cpp} (67%) rename src/{producer/StringIdMaker.h => message/MessageClientIDSetter.h} (58%) create mode 100644 src/producer/DefaultMQProducerImpl.cpp create mode 100644 src/producer/DefaultMQProducerImpl.h create mode 100644 src/producer/LatencyFaultTolerancyImpl.cpp create mode 100644 src/producer/LatencyFaultTolerancyImpl.h create mode 100644 src/producer/MQFaultStrategy.cpp create mode 100644 src/producer/MQFaultStrategy.h create mode 100644 src/producer/MQProducerInner.h delete mode 100644 src/protocol/RemotingCommand.h create mode 100644 src/protocol/RemotingSerializable.cpp delete mode 100755 src/thread/disruptor/batch_descriptor.h delete mode 100755 src/thread/disruptor/claim_strategy.h delete mode 100755 src/thread/disruptor/event_processor.h delete mode 100755 src/thread/disruptor/event_publisher.h delete mode 100755 src/thread/disruptor/exception_handler.h delete mode 100755 src/thread/disruptor/exceptions.h delete mode 100755 src/thread/disruptor/interface.h delete mode 100755 src/thread/disruptor/ring_buffer.h delete mode 100755 src/thread/disruptor/sequence.h delete mode 100755 src/thread/disruptor/sequence_barrier.h delete mode 100755 src/thread/disruptor/sequencer.h delete mode 100755 src/thread/disruptor/utils.h delete mode 100755 src/thread/disruptor/wait_strategy.h delete mode 100644 src/thread/disruptorLFQ.h delete mode 100644 src/thread/task_queue.cpp delete mode 100644 src/thread/task_queue.h delete mode 100644 src/transport/ClientRemotingProcessor.cpp delete mode 100644 src/transport/ClientRemotingProcessor.h rename src/{common/sync_http_client.h => transport/RequestProcessor.h} (71%) mode change 100755 => 100644 src/transport/TcpRemotingClient.cpp mode change 100644 => 100755 src/transport/TcpRemotingClient.h rename test/src/{message => }/BatchMessageTest.cpp (100%) delete mode 100644 test/src/MQClientAPIImpTest.cpp delete mode 100644 test/src/MQClientFactoryTest.cpp delete mode 100644 test/src/MQClientManagerTest.cpp rename test/src/{producer => }/StringIdMakerTest.cpp (100%) delete mode 100644 test/src/common/MQVersionTest.cpp delete mode 100644 test/src/common/UrlTest.cpp diff --git a/.gitignore b/.gitignore index 22c735062..327bb7c61 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,15 @@ -.idea +# clion +.idea/ + +# visual studio code +.vscode/ +.VSCodeCounter + +# cmake cmake-build-debug/ + +# project bin build libs/signature/lib tmp_* -Testing diff --git a/CMakeLists.txt b/CMakeLists.txt index c70b7e743..49e6a4da0 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,72 +37,28 @@ project(rocketmq-client-cpp) if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif () -set(CMAKE_CONFIGURATION_TYPES "Release") +if (NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_CONFIGURATION_TYPES "Release") +endif () set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) set(CMAKE_VERBOSE_MAKEFILE 1) -option(BUILD_ROCKETMQ_STATIC "build rocketmq-client static library" ON) -option(BUILD_ROCKETMQ_SHARED "build rocketmq-client shared library" ON) - -#Find dependency -option(Boost_USE_STATIC_LIBS "only find boost static libs" ON) # only find static libs -set(Boost_USE_MULTITHREADED ON) -set(Boost_USE_STATIC_RUNTIME ON) -if (WIN32) - find_package(Boost 1.56 REQUIRED COMPONENTS atomic thread system chrono date_time - log log_setup regex serialization filesystem locale iostreams zlib) - if (Boost_FOUND) - message(STATUS "** Boost Include dir: ${Boost_INCLUDE_DIR}") - message(STATUS "** Boost Libraries dir: ${Boost_LIBRARY_DIRS}") - message(STATUS "** Boost Libraries: ${Boost_LIBRARIES}") - include_directories(${Boost_INCLUDE_DIRS}) - endif () -else () - #find_package(Boost 1.56 REQUIRED COMPONENTS atomic thread system chrono date_time log log_setup regex serialization filesystem locale iostreams) - set(Boost_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/bin/include) - set(Boost_LIBRARY_DIRS ${PROJECT_SOURCE_DIR}/bin/lib) - set(Boost_LIBRARIES ${Boost_LIBRARY_DIRS}/libboost_atomic.a;${Boost_LIBRARY_DIRS}/libboost_thread.a;${Boost_LIBRARY_DIRS}/libboost_system.a;${Boost_LIBRARY_DIRS}/libboost_chrono.a; - ${Boost_LIBRARY_DIRS}/libboost_date_time.a;${Boost_LIBRARY_DIRS}/libboost_log.a;${Boost_LIBRARY_DIRS}/libboost_log_setup.a; - ${Boost_LIBRARY_DIRS}/libboost_regex.a;${Boost_LIBRARY_DIRS}/libboost_serialization.a;${Boost_LIBRARY_DIRS}/libboost_filesystem.a; - ${Boost_LIBRARY_DIRS}/libboost_locale.a;${Boost_LIBRARY_DIRS}/libboost_iostreams.a) - include_directories(${Boost_INCLUDE_DIRS}) -endif () -message(STATUS "** Boost_INCLUDE_DIR: ${Boost_INCLUDE_DIR}") -message(STATUS "** Boost_LIBRARIES: ${Boost_LIBRARIES}") +option(BUILD_ROCKETMQ_STATIC "build rocketmq-client static library" OFF) +option(BUILD_ROCKETMQ_SHARED "build rocketmq-client shared library" ON) -option(Libevent_USE_STATIC_LIBS "only find libevent static libs" ON) # only find static libs -if (WIN32) - find_package(Libevent 2.0.22 REQUIRED COMPONENTS) - if (LIBEVENT_FOUND) - include_directories(${LIBEVENT_INCLUDE_DIRS}) - message(STATUS "** libevent Include dir: ${LIBEVENT_INCLUDE_DIR}") - message(STATUS "** libevent Libraries: ${LIBEVENT_LIBRARIES}") - endif () -else () - #find_package(Libevent 2.0.22 REQUIRED COMPONENTS) - set(LIBEVENT_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/bin/include) - set(LIBEVENT_LIBRARIES_DIR ${PROJECT_SOURCE_DIR}/bin/lib) - set(LIBEVENT_LIBRARIES ${LIBEVENT_LIBRARIES_DIR}/libevent.a;${LIBEVENT_LIBRARIES_DIR}/libevent_core.a;${LIBEVENT_LIBRARIES_DIR}/libevent_extra.a;${LIBEVENT_LIBRARIES_DIR}/libevent_pthreads.a) - include_directories(${LIBEVENT_INCLUDE_DIRS}) -endif () +# Find dependency +#find_package(spdlog REQUIRED) +option(Libevent_USE_STATIC_LIBS "only find libevent static libs" OFF) # only find static libs +find_package(Libevent 2.0.21 REQUIRED) +include_directories(${LIBEVENT_INCLUDE_DIRS}) message(STATUS "** LIBEVENT_INCLUDE_DIR: ${LIBEVENT_INCLUDE_DIR}") message(STATUS "** LIBEVENT_LIBRARIES: ${LIBEVENT_LIBRARIES}") -option(JSONCPP_USE_STATIC_LIBS "only find jsoncpp static libs" ON) # only find static libs -if (WIN32) - find_package(Jsoncpp 0.10.6) - if (JSONCPP_FOUND) - include_directories(${JSONCPP_INCLUDE_DIRS}) - endif () -else () - set(JSONCPP_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/bin/include/jsoncpp) - set(JSONCPP_LIBRARIES_DIR ${PROJECT_SOURCE_DIR}/bin/lib) - set(JSONCPP_LIBRARIES ${JSONCPP_LIBRARIES_DIR}/libjsoncpp.a) - include_directories(${JSONCPP_INCLUDE_DIRS}) -endif () - +option(JSONCPP_USE_STATIC_LIBS "only find jsoncpp static libs" OFF) # only find static libs +find_package(Jsoncpp 0.10.6 REQUIRED) +include_directories(${JSONCPP_INCLUDE_DIRS}) message(STATUS "** JSONCPP_INCLUDE_DIRS: ${JSONCPP_INCLUDE_DIRS}") message(STATUS "** JSONCPP_LIBRARIES: ${JSONCPP_LIBRARIES}") @@ -126,14 +82,12 @@ IF (WIN32) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") ELSE () set(C_FLAGS - #-g -Wall -Wno-deprecated -fPIC -fno-strict-aliasing ) set(CXX_FLAGS - #-g -Wall -Wno-deprecated -fPIC @@ -173,8 +127,8 @@ ELSE () string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CXX_FLAGS}") string(REPLACE ";" " " CMAKE_C_FLAGS "${C_FLAGS}") - set(CMAKE_CXX_FLAGS_DEBUG "-O0 -DDEBUG") - set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DDEBUG") + set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") # Declare deplibs, so we can use list in linker later. There's probably @@ -191,24 +145,7 @@ ELSE () list(APPEND deplibs rt) endif () list(APPEND deplibs z) - # Code Coverage Configuration - add_library(coverage_config INTERFACE) - - option(CODE_COVERAGE "Enable coverage reporting" OFF) - if (CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - # Add required flags (GCC & LLVM/Clang) - target_compile_options(coverage_config INTERFACE - -O0 # no optimization - -g # generate debug info - --coverage # sets all required flags - ) - if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.13) - target_link_options(coverage_config INTERFACE --coverage) - else () - target_link_libraries(coverage_config INTERFACE --coverage) - endif () - list(APPEND deplibs coverage_config) - endif (CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + # add include dir for bsd (posix uses /usr/include/) set(CMAKE_INCLUDE_PATH "${CMAKE_INCLUDE_PATH}:/usr/local/include") ENDIF () @@ -242,8 +179,7 @@ add_subdirectory(example) option(RUN_UNIT_TEST "RUN_UNIT_TEST" OFF) if (RUN_UNIT_TEST) - message(STATUS "** RUN_UNIT_TEST: ${RUN_UNIT_TEST} Do execution testing") - enable_testing() + message(STATUS "** RUN_UNIT_TEST: Do execution testing") add_subdirectory(test) endif () diff --git a/README.md b/README.md index 9c337a414..511a59c85 100644 --- a/README.md +++ b/README.md @@ -1,78 +1,158 @@ -# RocketMQ-Client-CPP -[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) -[![TravisCI](https://travis-ci.org/apache/rocketmq-client-cpp.svg)](https://travis-ci.org/apache/rocketmq-client-cpp) -[![CodeCov](https://codecov.io/gh/apache/rocketmq-client-cpp/branch/master/graph/badge.svg)](https://codecov.io/gh/apache/rocketmq-client-cpp) -[![GitHub release](https://img.shields.io/badge/release-download-default.svg)](https://github.com/apache/rocketmq-client-cpp/releases) -[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/apache/rocketmq-client-cpp.svg)](http://isitmaintained.com/project/apache/rocketmq-client-cpp "Average time to resolve an issue") -[![Percentage of issues still open](http://isitmaintained.com/badge/open/apache/rocketmq-client-cpp.svg)](http://isitmaintained.com/project/apache/rocketmq-client-cpp "Percentage of issues still open") -![Twitter Follow](https://img.shields.io/twitter/follow/ApacheRocketMQ?style=social) - -RocketMQ-Client-CPP is the C/C++ client of Apache RocketMQ, a distributed messaging and streaming platform with low latency, high performance and reliability, trillion-level capacity and flexible scalability. - -## Features - -- produce messages, including normal and delayed messages, synchronously or asynchronously. -- consume messages, in cluster or broadcast model, concurrently or orderly -- c and c++ style API. -- cross-platform, all features are supported on Windows, Linux and Mac OS. -- automatically rebalanced, both in producing and consuming process. -- reliability, any downtime broker or name server has no impact on the client. - -## Build and Install - -### Linux and Mac OS - -**note**: make sure the following compile tools or libraries have been installed before running the build script **build.sh**. - -- compile tools: - - gcc-c++ 4.8.2: c++ compiler while need support C++11 - - cmake 2.8.0: build jsoncpp require it - - automake 1.11.1: build libevent require it - - autoconf 2.65: build libevent require it - - libtool 2.2.6: build libevent require it - -- libraries: - - bzip2-devel 1.0.6: boost depend it - - zlib-devel - -The **build.sh** script will automatically download and build the dependency libraries including libevent, json and boost. It will save libraries under rocketmq-client-cpp folder, and then build both static and shared libraries for rocketmq-client. If the dependent libraries are built failed, you could try to build it manually with sources [libevent 2.0.22](https://github.com/libevent/libevent/archive/release-2.0.22-stable.zip "lib event 2.0.22"), [jsoncpp 0.10.6](https://github.com/open-source-parsers/jsoncpp/archive/0.10.6.zip "jsoncpp 0.10.6"), [boost 1.58.0](http://sourceforge.net/projects/boost/files/boost/1.58.0/boost_1_58_0.tar.gz "boost 1.58.0") - -If your host is not available to internet to download the three library source files, you can copy the three library source files (release-2.0.22-stable.zip 0.10.6.zip and boost_1_58_0.tar.gz) to rocketmq-client-cpp root dir, then the build.sh will automatically use the three library source files to build rocketmq-client-cpp: - - sh build.sh - -Finally, both librocketmq.a and librocketmq.so are saved in rocketmq-client-cpp/bin. when using them to build application or library, besides rocketmq you should also link with following libraries -lpthread -lz -ldl -lrt. Here is an example: - - g++ -o consumer_example consumer_example.cpp -lrocketmq -lpthread -lz -ldl -lrt - -### Windows -**note**: make sure the following compile tools or libraries have been installed before running the build script **win32_build.bat**: - -- compile tools: - - vs2015: libevent,jsoncpp,zlib,boost rocket-client require it - - git: download source code - -The build script will automatically download dependent libraries including libevent json and boost to build shared library: - - win32_build.bat - - -If your host is not available to internet to download the four library source files by build script, you can copy the four library source files - -[zlib-1.2.3-src](https://codeload.github.com/jsj020122/zlib-1.2.3-src/zip/master "zlib-1.2.3-src") Extract to $(rocketmq-client-cpp root dir)/thirdparty/zlib-1.2.3-src - -[libevent-release-2.0.22](https://codeload.github.com/jsj020122/libevent-release-2.0.22/zip/master "libevent-release-2.0.22") Extract to $(rocketmq-client-cpp root dir)/thirdparty/libevent-release-2.0.22 - -[boost_1_58_0](https://codeload.github.com/jsj020122/boost_1_58_0/zip/master "boost_1_58_0") Extract to $(rocketmq-client-cpp root dir)/thirdparty/boost_1_58_0 - -[jsoncpp-0.10.6](https://codeload.github.com/jsj020122/jsoncpp-0.10.6/zip/master "jsoncpp-0.10.6") Extract to $(rocketmq-client-cpp root dir)/thirdparty/jsoncpp-0.10.6 - -And then run following command to build x86 rocketmq-client: - - win32_build.bat build - -to build x64 rocketmq-client: - - win32_build.bat build64 - - +# RocketMQ-Client-CPP +[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) +[![TravisCI](https://travis-ci.org/apache/rocketmq-client-cpp.svg)](https://travis-ci.org/apache/rocketmq-client-cpp) +[![CodeCov](https://codecov.io/gh/apache/rocketmq-client-cpp/branch/master/graph/badge.svg)](https://codecov.io/gh/apache/rocketmq-client-cpp) +[![GitHub release](https://img.shields.io/badge/release-download-default.svg)](https://github.com/apache/rocketmq-client-cpp/releases) +[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/apache/rocketmq-client-cpp.svg)](http://isitmaintained.com/project/apache/rocketmq-client-cpp "Average time to resolve an issue") +[![Percentage of issues still open](http://isitmaintained.com/badge/open/apache/rocketmq-client-cpp.svg)](http://isitmaintained.com/project/apache/rocketmq-client-cpp "Percentage of issues still open") +![Twitter Follow](https://img.shields.io/twitter/follow/ApacheRocketMQ?style=social) + +RocketMQ-Client-CPP is the C/C++ client of Apache RocketMQ, a distributed messaging and streaming platform with low latency, high performance and reliability, trillion-level capacity and flexible scalability. + +## Features + +- produce messages, including normal and delayed messages, synchronously or asynchronously. +- consume messages, in cluster or broadcast model, concurrently or orderly +- c and c++ style API. +- cross-platform, all features are supported on Windows, Linux and Mac OS. +- automatically rebalanced, both in producing and consuming process. +- reliability, any downtime broker or name server has no impact on the client. + +## Build and Install + +### CentOS + +```bash +# install toolchain +yum install -y gcc gcc-c++ cmake + +# install dependencies +yum install -y spdlog-devel libevent-devel jsoncpp-devel zlib-devel + +# configure porject +mkdir build && cd build +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DLibevent_USE_STATIC_LIBS=OFF -DJSONCPP_USE_STATIC_LIBS=OFF \ + -DBUILD_ROCKETMQ_STATIC=OFF -DBUILD_ROCKETMQ_SHARED=ON \ + -DRUN_UNIT_TEST=OFF .. + +# build librocketmq.so +make rocketmq_shared -j 6 + +# build example: SyncProducer, PushConsumer, etc. +make SyncProducer +make PushConsumer +``` + +If encounter error about "fmt/format.h" header file, modify "printf.h" as shown below. + +```bash +sed -i "s/#include \"fmt\/format.h\"/#include \"format.h\"/" /usr/include/spdlog/fmt/bundled/printf.h +``` + +### Ubuntu + +```bash +# install toolchain +apt install -y gcc g++ cmake + +# install dependencies +apt install -y libspdlog-dev libevent-dev libjsoncpp-dev zlib1g-dev + +# configure porject +mkdir build && cd build +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DLibevent_USE_STATIC_LIBS=OFF -DJSONCPP_USE_STATIC_LIBS=OFF \ + -DBUILD_ROCKETMQ_STATIC=OFF -DBUILD_ROCKETMQ_SHARED=ON \ + -DRUN_UNIT_TEST=OFF .. + +# build librocketmq.so +make rocketmq_shared -j 6 + +# build example: SyncProducer, PushConsumer, etc. +make SyncProducer +make PushConsumer +``` + +### macOS + +```bash +# install toolchain +brew install cmake + +# dependencies +brew install spdlog libevent jsoncpp zlib + +# configure porject +mkdir build && cd build +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DLibevent_USE_STATIC_LIBS=OFF -DJSONCPP_USE_STATIC_LIBS=OFF \ + -DBUILD_ROCKETMQ_STATIC=OFF -DBUILD_ROCKETMQ_SHARED=ON \ + -DRUN_UNIT_TEST=OFF .. + +# build librocketmq.so +make rocketmq_shared -j 4 + +# build example: SyncProducer, PushConsumer, etc. +make SyncProducer +make PushConsumer +``` + +## Build and Install (Old SDK) + +### Linux and Mac OS + +**note**: make sure the following compile tools or libraries have been installed before running the build script **build.sh**. + +- compile tools: + - gcc-c++ 4.8.2: c++ compiler while need support C++11 + - cmake 2.8.0: build jsoncpp require it + - automake 1.11.1: build libevent require it + - autoconf 2.65: build libevent require it + - libtool 2.2.6: build libevent require it + +- libraries: + - bzip2-devel 1.0.6: boost depend it + - zlib-devel + +The **build.sh** script will automatically download and build the dependency libraries including libevent, json and boost. It will save libraries under rocketmq-client-cpp folder, and then build both static and shared libraries for rocketmq-client. If the dependent libraries are built failed, you could try to build it manually with sources [libevent 2.0.22](https://github.com/libevent/libevent/archive/release-2.0.22-stable.zip "lib event 2.0.22"), [jsoncpp 0.10.6](https://github.com/open-source-parsers/jsoncpp/archive/0.10.6.zip "jsoncpp 0.10.6"), [boost 1.58.0](http://sourceforge.net/projects/boost/files/boost/1.58.0/boost_1_58_0.tar.gz "boost 1.58.0") + +If your host is not available to internet to download the three library source files, you can copy the three library source files (release-2.0.22-stable.zip 0.10.6.zip and boost_1_58_0.tar.gz) to rocketmq-client-cpp root dir, then the build.sh will automatically use the three library source files to build rocketmq-client-cpp: + + sh build.sh + +Finally, both librocketmq.a and librocketmq.so are saved in rocketmq-client-cpp/bin. when using them to build application or library, besides rocketmq you should also link with following libraries -lpthread -lz -ldl -lrt. Here is an example: + + g++ -o consumer_example consumer_example.cpp -lrocketmq -lpthread -lz -ldl -lrt + +### Windows +**note**: make sure the following compile tools or libraries have been installed before running the build script **win32_build.bat**: + +- compile tools: + - vs2015: libevent,jsoncpp,zlib,boost rocket-client require it + - git: download source code + +The build script will automatically download dependent libraries including libevent json and boost to build shared library: + + win32_build.bat + + +If your host is not available to internet to download the four library source files by build script, you can copy the four library source files + +[zlib-1.2.3-src](https://codeload.github.com/jsj020122/zlib-1.2.3-src/zip/master "zlib-1.2.3-src") Extract to $(rocketmq-client-cpp root dir)/thirdparty/zlib-1.2.3-src + +[libevent-release-2.0.22](https://codeload.github.com/jsj020122/libevent-release-2.0.22/zip/master "libevent-release-2.0.22") Extract to $(rocketmq-client-cpp root dir)/thirdparty/libevent-release-2.0.22 + +[boost_1_58_0](https://codeload.github.com/jsj020122/boost_1_58_0/zip/master "boost_1_58_0") Extract to $(rocketmq-client-cpp root dir)/thirdparty/boost_1_58_0 + +[jsoncpp-0.10.6](https://codeload.github.com/jsj020122/jsoncpp-0.10.6/zip/master "jsoncpp-0.10.6") Extract to $(rocketmq-client-cpp root dir)/thirdparty/jsoncpp-0.10.6 + +And then run following command to build x86 rocketmq-client: + + win32_build.bat build + +to build x64 rocketmq-client: + + win32_build.bat build64 + + diff --git a/cmake/BundleStaticLibrary.cmake b/cmake/BundleStaticLibrary.cmake new file mode 100644 index 000000000..4ab9a24b1 --- /dev/null +++ b/cmake/BundleStaticLibrary.cmake @@ -0,0 +1,134 @@ +# 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. + +# ref: https://cristianadam.eu/20190501/bundling-together-static-libraries-with-cmake/ + +set(STATIC_LIBRARY_REGEX "${CMAKE_STATIC_LIBRARY_SUFFIX}") +string(REPLACE ".", "\\.", STATIC_LIBRARY_REGEX ${STATIC_LIBRARY_REGEX}) +set(STATIC_LIBRARY_REGEX "^.+${STATIC_LIBRARY_REGEX}$") + +function(bundle_static_library tgt_name bundled_tgt_name) + list(APPEND static_libs ${tgt_name}) + set(static_libraries) + + function(_recursively_collect_dependencies input_target) + set(_input_link_libraries LINK_LIBRARIES) + get_target_property(_input_type ${input_target} TYPE) + if(${_input_type} STREQUAL "INTERFACE_LIBRARY") + set(_input_link_libraries INTERFACE_LINK_LIBRARIES) + endif() + get_target_property(public_dependencies ${input_target} + ${_input_link_libraries}) + foreach(dependency IN LISTS public_dependencies) + if(TARGET ${dependency}) + get_target_property(alias ${dependency} ALIASED_TARGET) + if(TARGET ${alias}) + set(dependency ${alias}) + endif() + get_target_property(_type ${dependency} TYPE) + if(${_type} STREQUAL "STATIC_LIBRARY") + list(APPEND static_libs ${dependency}) + endif() + + get_property(library_already_added GLOBAL + PROPERTY _${tgt_name}_static_bundle_${dependency}) + if(NOT library_already_added) + set_property(GLOBAL PROPERTY _${tgt_name}_static_bundle_${dependency} + ON) + _recursively_collect_dependencies(${dependency}) + endif() + else() + string(REGEX MATCH ${STATIC_LIBRARY_REGEX} IS_STATIC_LIBRARY ${dependency}) + if(IS_STATIC_LIBRARY) + list(APPEND static_libs ${dependency}) + endif() + endif() + endforeach() + set(static_libs + ${static_libs} + PARENT_SCOPE) + endfunction() + + _recursively_collect_dependencies(${tgt_name}) + + list(REMOVE_DUPLICATES static_libs) + + set(bundled_tgt_full_name + ${LIBRARY_OUTPUT_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}${bundled_tgt_name}${CMAKE_STATIC_LIBRARY_SUFFIX} + ) + + if(CMAKE_CXX_COMPILER_ID MATCHES "^(Clang|GNU)$") + file(WRITE ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in + "CREATE ${bundled_tgt_full_name}\n") + + foreach(tgt IN LISTS static_libs) + if(TARGET ${tgt}) + file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in + "ADDLIB $\n") + else() + file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in + "ADDLIB ${tgt}\n") + endif() + endforeach() + + file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in "SAVE\n") + file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in "END\n") + + file( + GENERATE + OUTPUT ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri + INPUT ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in) + + set(ar_tool ${CMAKE_AR}) + if(CMAKE_INTERPROCEDURAL_OPTIMIZATION) + set(ar_tool ${CMAKE_CXX_COMPILER_AR}) + endif() + + message( + STATUS "** Bundled static library: ${bundled_tgt_full_name}") + add_custom_command( + OUTPUT ${bundled_tgt_full_name} + COMMAND ${ar_tool} -M < ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri + COMMENT "Bundling ${bundled_tgt_name}" + VERBATIM) + elseif(MSVC) + find_program(lib_tool lib) + + foreach(tgt IN LISTS static_libs) + list(APPEND static_libs_full_names $) + endforeach() + + add_custom_command( + OUTPUT ${bundled_tgt_full_name} + COMMAND ${lib_tool} /NOLOGO /OUT:${bundled_tgt_full_name} + ${static_libs_full_names} + COMMENT "Bundling ${bundled_tgt_name}" + VERBATIM) + else() + message(FATAL_ERROR "Unknown bundle scenario!") + endif() + + add_custom_target("${bundled_tgt_name}_" ALL DEPENDS ${bundled_tgt_full_name}) + add_dependencies("${bundled_tgt_name}_" ${tgt_name}) + + add_library(${bundled_tgt_name} STATIC IMPORTED) + set_target_properties( + ${bundled_tgt_name} + PROPERTIES IMPORTED_LOCATION ${bundled_tgt_full_name} + INTERFACE_INCLUDE_DIRECTORIES + $) + add_dependencies(${bundled_tgt_name} "${bundled_tgt_name}_") + +endfunction() diff --git a/cmake/FindJsoncpp.cmake b/cmake/FindJsoncpp.cmake index 963211811..cdef2b1ca 100755 --- a/cmake/FindJsoncpp.cmake +++ b/cmake/FindJsoncpp.cmake @@ -30,66 +30,70 @@ # JSONCPP_LIBRARIES, where to find the jsoncpp library. # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES -if( JSONCPP_USE_STATIC_LIBS ) - set(_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES}) - if(WIN32) +if (JSONCPP_USE_STATIC_LIBS) + set(_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES}) + if (WIN32) list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .lib .a) - else() + else () set(CMAKE_FIND_LIBRARY_SUFFIXES .a) - endif() -else() - set(_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES}) - if(WIN32) + endif () +else () + set(_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES}) + if (WIN32) list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .dll .so) - else() + elseif (APPLE) + set(CMAKE_FIND_LIBRARY_SUFFIXES .dylib) + else () set(CMAKE_FIND_LIBRARY_SUFFIXES .so) - endif() -endif() + endif () +endif () -FIND_PATH(JSONCPP_INCLUDE_DIRS -NAMES - json.h - json/json.h -PATHS - ${CMAKE_SOURCE_DIR}/bin/include - C:/jsoncpp/include - ${CMAKE_SOURCE_DIR}/win32-deps/include - C:/jsoncpp-0.10.6/include -PATH_SUFFIXES jsoncpp -) +set(JSONCPP_INCLUDE_SEARCH_PATH ${CMAKE_SOURCE_DIR}/bin/include /usr/local/include C:/jsoncpp/include + ${CMAKE_SOURCE_DIR}/win32-deps/include C:/jsoncpp-0.10.6/include) +set(JSONCPP_LIBRARIE_SEARCH_PATH ${CMAKE_SOURCE_DIR}/bin/lib /usr/local/lib C:/jsoncpp/lib + ${CMAKE_SOURCE_DIR}/win32-deps/lib C:/jsoncpp-0.10.6/) +if (JSONCPP_ROOT) + list(INSERT JSONCPP_INCLUDE_SEARCH_PATH 0 ${JSONCPP_ROOT}/include) + list(INSERT JSONCPP_LIBRARIE_SEARCH_PATH 0 ${JSONCPP_ROOT}/lib) +endif () + +find_path(JSONCPP_INCLUDE_DIRS + NAMES json.h json/json.h + PATHS ${JSONCPP_INCLUDE_SEARCH_PATH} + PATH_SUFFIXES jsoncpp) find_library(JSONCPP_LIBRARIES - NAMES jsoncpp - PATHS ${CMAKE_SOURCE_DIR}/bin/lib C:/jsoncpp/lib ${CMAKE_SOURCE_DIR}/win32-deps/lib C:/jsoncpp-0.10.6/ -) + NAMES jsoncpp + PATHS ${JSONCPP_LIBRARIE_SEARCH_PATH}) + IF (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS) SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARIES}) SET(JSONCPP_FOUND "YES") ELSE (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS) - SET(JSONCPP_FOUND "NO") + SET(JSONCPP_FOUND "NO") ENDIF (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS) IF (JSONCPP_FOUND) - IF (NOT JSONCPP_FIND_QUIETLY) - MESSAGE(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}") - ENDIF (NOT JSONCPP_FIND_QUIETLY) + IF (NOT JSONCPP_FIND_QUIETLY) + MESSAGE(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}") + ENDIF (NOT JSONCPP_FIND_QUIETLY) ELSE (JSONCPP_FOUND) - IF (JSONCPP_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find JSONCPP library include: ${JSONCPP_INCLUDE_DIRS}, lib: ${JSONCPP_LIBRARIES}") - ENDIF (JSONCPP_FIND_REQUIRED) + IF (JSONCPP_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find JSONCPP library include: ${JSONCPP_INCLUDE_DIRS}, lib: ${JSONCPP_LIBRARIES}") + ENDIF (JSONCPP_FIND_REQUIRED) ENDIF (JSONCPP_FOUND) # Deprecated declarations. -SET (NATIVE_JSONCPP_INCLUDE_PATH ${JSONCPP_INCLUDE_DIRS} ) -GET_FILENAME_COMPONENT (NATIVE_JSONCPP_LIB_PATH ${JSONCPP_LIBRARIES} PATH) +SET(NATIVE_JSONCPP_INCLUDE_PATH ${JSONCPP_INCLUDE_DIRS}) +GET_FILENAME_COMPONENT(NATIVE_JSONCPP_LIB_PATH ${JSONCPP_LIBRARIES} PATH) MARK_AS_ADVANCED( - JSONCPP_LIBRARIES - JSONCPP_INCLUDE_DIRS - ) + JSONCPP_LIBRARIES + JSONCPP_INCLUDE_DIRS +) # Restore the original find library ordering -if( JSONCPP_USE_STATIC_LIBS ) - set(CMAKE_FIND_LIBRARY_SUFFIXES ${_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) -endif() +if (JSONCPP_USE_STATIC_LIBS) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) +endif () diff --git a/cmake/FindLibevent.cmake b/cmake/FindLibevent.cmake index c013d4981..0165e7027 100755 --- a/cmake/FindLibevent.cmake +++ b/cmake/FindLibevent.cmake @@ -41,112 +41,125 @@ find_package(PkgConfig QUIET) pkg_check_modules(PC_LIBEVENT QUIET libevent) # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES -if( Libevent_USE_STATIC_LIBS ) - set(_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES}) - if(WIN32) +if (Libevent_USE_STATIC_LIBS) + set(_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES}) + if (WIN32) list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .lib .a) - else() + else () set(CMAKE_FIND_LIBRARY_SUFFIXES .a) - endif() -else() - set(_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES}) - if(WIN32) + endif () +else () + set(_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES}) + if (WIN32) list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .dll .so) - else() + elseif (APPLE) + set(CMAKE_FIND_LIBRARY_SUFFIXES .dylib) + else () set(CMAKE_FIND_LIBRARY_SUFFIXES .so) - endif() -endif() + endif () +endif () + +set(LIBEVENT_INCLUDE_SEARCH_PATH ${CMAKE_SOURCE_DIR}/bin/include /usr/local/include C:/libevent/include + ${CMAKE_SOURCE_DIR}/win32-deps/include) +set(LIBEVENT_LIBRARIE_SEARCH_PATH ${CMAKE_SOURCE_DIR}/bin/lib /usr/local/lib C:/libevent-2.0.22-stable + C:/libevent-2.0.22-stable/lib C:/libevent/lib ${CMAKE_SOURCE_DIR}/win32-deps/lib) +if (LIBEVENT_ROOT) + list(INSERT LIBEVENT_INCLUDE_SEARCH_PATH 0 ${JSONCPP_ROOT}/include) + list(INSERT LIBEVENT_LIBRARIE_SEARCH_PATH 0 ${JSONCPP_ROOT}/lib) +endif () + # Look for the Libevent 2.0 or 1.4 headers find_path(LIBEVENT_INCLUDE_DIR - NAMES - WIN32-Code/event2/event-config.h - event2/event-config.h - event-config.h - PATHS ${CMAKE_SOURCE_DIR}/bin/include C:/libevent/include ${CMAKE_SOURCE_DIR}/win32-deps/include - HINTS - ${PC_LIBEVENT_INCLUDE_DIRS} -) + NAMES WIN32-Code/event2/event-config.h event2/event-config.h event-config.h + PATHS ${LIBEVENT_INCLUDE_SEARCH_PATH} + HINTS ${PC_LIBEVENT_INCLUDE_DIRS}) # ------------------------------------------------------------------------ # Prefix initialization # ------------------------------------------------------------------------ set(Libevent_LIB_PREFIX "") set(LIBEVENT_EVENT_CONFIG_DIR ${LIBEVENT_INCLUDE_DIR}) -if(WIN32) - set(Libevent_LIB_PREFIX "lib") - set(LIBEVENT_EVENT_CONFIG_DIR "${LIBEVENT_INCLUDE_DIR}/../WIN32-Code/") -endif() +if (WIN32) + set(Libevent_LIB_PREFIX "lib") + set(LIBEVENT_EVENT_CONFIG_DIR "${LIBEVENT_INCLUDE_DIR}/../WIN32-Code/") +endif () -if(LIBEVENT_INCLUDE_DIR) - set(_version_regex "^#define[ \t]+_EVENT_VERSION[ \t]+\"([^\"]+)\".*") - if(EXISTS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h") - # Libevent 2.0 - file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h" - LIBEVENT_VERSION REGEX "${_version_regex}") - else() - # Libevent 1.4 - if(EXISTS "${LIBEVENT_EVENT_CONFIG_DIR}/event-config.h") - file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event-config.h" - LIBEVENT_VERSION REGEX "${_version_regex}") - endif() - endif() - string(REGEX REPLACE "${_version_regex}" "\\1" - LIBEVENT_VERSION "${LIBEVENT_VERSION}") - unset(_version_regex) -endif() +if (LIBEVENT_INCLUDE_DIR) + set(_version_regex "^#define[ \t]+_EVENT_VERSION[ \t]+\"([^\"]+)\".*") + if (EXISTS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h") + # Libevent 2.0 + file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h" + LIBEVENT_VERSION REGEX "${_version_regex}") + if (NOT LIBEVENT_VERSION) + # Libevent 2.1 + set(_version_regex "^#define[ \t]+EVENT__VERSION[ \t]+\"([^\"]+)\".*") + file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h" + LIBEVENT_VERSION REGEX "${_version_regex}") + endif () + else () + # Libevent 1.4 + if (EXISTS "${LIBEVENT_EVENT_CONFIG_DIR}/event-config.h") + file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event-config.h" + LIBEVENT_VERSION REGEX "${_version_regex}") + endif () + endif () + string(REGEX REPLACE "${_version_regex}" "\\1" + LIBEVENT_VERSION "${LIBEVENT_VERSION}") + unset(_version_regex) +endif () set(_LIBEVENT_REQUIRED_VARS) -if(WIN32) - set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extras) -else() - set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extra pthreads) -endif() -message(status "** libevent components: ${Libevent_FIND_COMPONENTS}") -foreach(COMPONENT ${Libevent_FIND_COMPONENTS}) - set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event") - # Note: compare two variables to avoid a CMP0054 policy warning - if(COMPONENT STREQUAL _LIBEVENT_LIBNAME) +if (WIN32) + set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extras) +else () + set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extra pthreads) +endif () +message(STATUS "** libevent components: ${Libevent_FIND_COMPONENTS}") +foreach (COMPONENT ${Libevent_FIND_COMPONENTS}) set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event") - else() - set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event_${COMPONENT}") - endif() - string(TOUPPER "${COMPONENT}" COMPONENT_UPPER) - message(status "** ${_LIBEVENT_LIBNAME}") - find_library(LIBEVENT_${COMPONENT_UPPER}_LIBRARY - NAMES ${_LIBEVENT_LIBNAME} - PATHS ${CMAKE_SOURCE_DIR}/bin/lib C:/libevent-2.0.22-stable C:/libevent-2.0.22-stable/lib C:/libevent/lib ${CMAKE_SOURCE_DIR}/win32-deps/lib - HINTS ${PC_LIBEVENT_LIBRARY_DIRS} - ) - if(LIBEVENT_${COMPONENT_UPPER}_LIBRARY) - set(Libevent_${COMPONENT}_FOUND 1) - endif() - list(APPEND _LIBEVENT_REQUIRED_VARS LIBEVENT_${COMPONENT_UPPER}_LIBRARY) -endforeach() + # Note: compare two variables to avoid a CMP0054 policy warning + if (COMPONENT STREQUAL _LIBEVENT_LIBNAME) + set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event") + else () + set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event_${COMPONENT}") + endif () + string(TOUPPER "${COMPONENT}" COMPONENT_UPPER) + message(STATUS "** ${_LIBEVENT_LIBNAME}") + find_library(LIBEVENT_${COMPONENT_UPPER}_LIBRARY + NAMES ${_LIBEVENT_LIBNAME} + PATHS ${LIBEVENT_LIBRARIE_SEARCH_PATH} + HINTS ${PC_LIBEVENT_LIBRARY_DIRS} + ) + if (LIBEVENT_${COMPONENT_UPPER}_LIBRARY) + set(Libevent_${COMPONENT}_FOUND 1) + endif () + list(APPEND _LIBEVENT_REQUIRED_VARS LIBEVENT_${COMPONENT_UPPER}_LIBRARY) +endforeach () unset(_LIBEVENT_LIBNAME) include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set LIBEVENT_FOUND to TRUE # if all listed variables are TRUE and the requested version matches. find_package_handle_standard_args(Libevent REQUIRED_VARS - ${_LIBEVENT_REQUIRED_VARS} - LIBEVENT_INCLUDE_DIR - VERSION_VAR LIBEVENT_VERSION - HANDLE_COMPONENTS) + ${_LIBEVENT_REQUIRED_VARS} + LIBEVENT_INCLUDE_DIR + VERSION_VAR LIBEVENT_VERSION + HANDLE_COMPONENTS) -if(LIBEVENT_FOUND) - set(LIBEVENT_INCLUDE_DIRS ${LIBEVENT_INCLUDE_DIR}) - set(LIBEVENT_LIBRARIES) - foreach(COMPONENT ${Libevent_FIND_COMPONENTS}) - string(TOUPPER "${COMPONENT}" COMPONENT_UPPER) - list(APPEND LIBEVENT_LIBRARIES ${LIBEVENT_${COMPONENT_UPPER}_LIBRARY}) - set(LIBEVENT_${COMPONENT_UPPER}_FOUND ${Libevent_${COMPONENT}_FOUND}) - endforeach() -endif() +if (LIBEVENT_FOUND) + set(LIBEVENT_INCLUDE_DIRS ${LIBEVENT_INCLUDE_DIR}) + set(LIBEVENT_LIBRARIES) + foreach (COMPONENT ${Libevent_FIND_COMPONENTS}) + string(TOUPPER "${COMPONENT}" COMPONENT_UPPER) + list(APPEND LIBEVENT_LIBRARIES ${LIBEVENT_${COMPONENT_UPPER}_LIBRARY}) + set(LIBEVENT_${COMPONENT_UPPER}_FOUND ${Libevent_${COMPONENT}_FOUND}) + endforeach () +endif () mark_as_advanced(LIBEVENT_INCLUDE_DIR ${_LIBEVENT_REQUIRED_VARS}) # Restore the original find library ordering -if( Libevent_USE_STATIC_LIBS ) - set(CMAKE_FIND_LIBRARY_SUFFIXES ${_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) -endif() +if (Libevent_USE_STATIC_LIBS) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) +endif () unset(_LIBEVENT_REQUIRED_VARS) diff --git a/distribution/deploy.sh b/distribution/deploy.sh index 726c182f4..7af6e309f 100755 --- a/distribution/deploy.sh +++ b/distribution/deploy.sh @@ -16,7 +16,7 @@ # limitations under the License. -VERSION="1.2.4" +VERSION="1.2.3" PKG_NAME="rocketmq-client-cpp" CWD_DIR=$(cd "$(dirname "$0")"; pwd) DEPLOY_BUILD_HOME=${CWD_DIR}/${PKG_NAME} diff --git a/src/common/Arg_helper.cpp b/example/ArgHelper.cpp similarity index 74% rename from src/common/Arg_helper.cpp rename to example/ArgHelper.cpp index 61ac54936..150623313 100644 --- a/src/common/Arg_helper.cpp +++ b/example/ArgHelper.cpp @@ -14,32 +14,32 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "ArgHelper.h" -#include "Arg_helper.h" #include "UtilAll.h" namespace rocketmq { -// v; +ArgHelper::ArgHelper(std::string arg_str_) { + std::vector v; UtilAll::Split(v, arg_str_, " "); m_args.insert(m_args.end(), v.begin(), v.end()); } -string Arg_helper::get_option(int idx_) const { +std::string ArgHelper::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 { +bool ArgHelper::is_enable_option(std::string opt_) const { for (size_t i = 0; i < m_args.size(); ++i) { if (opt_ == m_args[i]) { return true; @@ -48,8 +48,8 @@ bool Arg_helper::is_enable_option(string opt_) const { return false; } -string Arg_helper::get_option_value(string opt_) const { - string ret = ""; +std::string ArgHelper::get_option_value(std::string opt_) const { + std::string ret = ""; for (size_t i = 0; i < m_args.size(); ++i) { if (opt_ == m_args[i]) { size_t value_idx = ++i; @@ -63,5 +63,4 @@ string Arg_helper::get_option_value(string opt_) const { return ret; } -// #include + #include "RocketMQClient.h" namespace rocketmq { -// m_args; }; -// -#include -#include - -#include -#include -#include -#include -#include -#include - #include "common.h" +#include "concurrent/latch.hpp" using namespace rocketmq; -boost::atomic g_quit; -std::mutex g_mtx; -std::condition_variable g_finished; -SendCallback* g_callback = NULL; TpsReportService g_tps; +latch* g_finish = nullptr; + +std::atomic g_success(0); +std::atomic g_failed(0); + +class MyAutoDeleteSendCallback : public AutoDeleteSendCallback { + public: + MyAutoDeleteSendCallback(MQMessage* msg) : m_msg(msg) {} + virtual ~MyAutoDeleteSendCallback() { delete m_msg; } -class MySendCallback : public SendCallback { - virtual void onSuccess(SendResult& sendResult) { - g_msgCount--; + void onSuccess(SendResult& sendResult) override { + g_success++; + g_finish->count_down(); g_tps.Increment(); - if (g_msgCount.load() <= 0) { - std::unique_lock lck(g_mtx); - g_finished.notify_one(); - } } - virtual void onException(MQException& e) { cout << "send Exception\n"; } -}; -class MyAutoDeleteSendCallback : public AutoDeleteSendCallBack { - public: - virtual ~MyAutoDeleteSendCallback() {} - virtual void onSuccess(SendResult& sendResult) { - g_msgCount--; - if (g_msgCount.load() <= 0) { - std::unique_lock lck(g_mtx); - g_finished.notify_one(); - } + void onException(MQException& e) noexcept override { + g_failed++; + g_finish->count_down(); + // std::cout << "send Exception: " << e << std::endl; } - virtual void onException(MQException& e) { std::cout << "send Exception" << e << "\n"; } + + private: + MQMessage* m_msg; }; void AsyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) { - while (!g_quit.load()) { - if (g_msgCount.load() <= 0) { - std::unique_lock lck(g_mtx); - g_finished.notify_one(); - } - MQMessage msg(info->topic, // topic - "*", // tag - info->body); // body + while (g_msgCount.fetch_sub(1) > 0) { + auto* msg = new MQMessage(info->topic, // topic + "*", // tag + info->body); // body - if (info->IsAutoDeleteSendCallback) { - g_callback = new MyAutoDeleteSendCallback(); // auto delete - } + SendCallback* callback = new MyAutoDeleteSendCallback(msg); try { - producer->send(msg, g_callback); - } catch (MQException& e) { - std::cout << e << endl; // if catch excepiton , need re-send this msg by - // service + producer->send(msg, callback); // auto delete + } catch (std::exception& e) { + std::cout << "[BUG]:" << e.what() << std::endl; + throw e; } } } @@ -88,48 +68,53 @@ int main(int argc, char* argv[]) { if (!ParseArgs(argc, argv, &info)) { exit(-1); } - - DefaultMQProducer producer("please_rename_unique_group_name"); - if (!info.IsAutoDeleteSendCallback) { - g_callback = new MySendCallback(); - } - PrintRocketmqSendAndConsumerArgs(info); - if (!info.namesrv.empty()) - producer.setNamesrvAddr(info.namesrv); + auto* producer = new DefaultMQProducer(info.groupname); + producer->setNamesrvAddr(info.namesrv); + producer->setGroupName(info.groupname); + producer->setSendMsgTimeout(3000); + producer->setRetryTimes(info.retrytimes); + producer->setRetryTimes4Async(info.retrytimes); + producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker); + producer->setTcpTransportTryLockTimeout(1000); + producer->setTcpTransportConnectTimeout(400); + producer->start(); - producer.setGroupName(info.groupname); - producer.setInstanceName(info.groupname); - producer.setNamesrvDomain(info.namesrv_domain); - producer.start(); - g_tps.start(); std::vector> work_pool; - auto start = std::chrono::system_clock::now(); int msgcount = g_msgCount.load(); - for (int j = 0; j < info.thread_count; j++) { - std::shared_ptr th = std::make_shared(AsyncProducerWorker, &info, &producer); + g_finish = new latch(msgcount); + g_tps.start(); + + auto start = std::chrono::system_clock::now(); + + int threadCount = info.thread_count; + for (int j = 0; j < threadCount; j++) { + std::shared_ptr th = std::make_shared(AsyncProducerWorker, &info, producer); work_pool.push_back(th); } - { - std::unique_lock lck(g_mtx); - g_finished.wait(lck); - g_quit.store(true); + for (size_t th = 0; th != work_pool.size(); ++th) { + work_pool[th]->join(); } + g_finish->wait(); + auto end = std::chrono::system_clock::now(); auto duration = std::chrono::duration_cast(end - start); - std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms \n" - << "========================finished==============================\n"; + std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms" << std::endl + << "========================finished=============================" << std::endl + << "success: " << g_success << ", failed: " << g_failed << std::endl; - producer.shutdown(); - for (size_t th = 0; th != work_pool.size(); ++th) { - work_pool[th]->join(); - } - if (!info.IsAutoDeleteSendCallback) { - delete g_callback; + try { + producer->shutdown(); + } catch (std::exception& e) { + std::cout << "encounter exception: " << e.what() << std::endl; } + + delete producer; + delete g_finish; + return 0; } diff --git a/example/AsyncPushConsumer.cpp b/example/AsyncPushConsumer.cpp deleted file mode 100644 index 414f96739..000000000 --- a/example/AsyncPushConsumer.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* -* 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 -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "common.h" - -std::mutex g_mtx; -std::condition_variable g_finished; -TpsReportService g_tps; -using namespace rocketmq; - -class MyMsgListener : public MessageListenerConcurrently { - public: - MyMsgListener() {} - virtual ~MyMsgListener() {} - - virtual ConsumeStatus consumeMessage(const std::vector& msgs) { - g_msgCount.store(g_msgCount.load() - msgs.size()); - for (size_t i = 0; i < msgs.size(); ++i) { - g_tps.Increment(); - } - - if (g_msgCount.load() <= 0) { - std::unique_lock lck(g_mtx); - g_finished.notify_one(); - } - return CONSUME_SUCCESS; - } -}; - -int main(int argc, char* argv[]) { - RocketmqSendAndConsumerArgs info; - if (!ParseArgs(argc, argv, &info)) { - exit(-1); - } - PrintRocketmqSendAndConsumerArgs(info); - DefaultMQPushConsumer consumer("please_rename_unique_group_name"); - DefaultMQProducer producer("please_rename_unique_group_name"); - - producer.setNamesrvAddr(info.namesrv); - producer.setGroupName("msg-persist-group_producer_sandbox"); - producer.setNamesrvDomain(info.namesrv_domain); - producer.start(); - - consumer.setNamesrvAddr(info.namesrv); - consumer.setGroupName(info.groupname); - consumer.setNamesrvDomain(info.namesrv_domain); - consumer.setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET); - - consumer.setInstanceName(info.groupname); - - consumer.subscribe(info.topic, "*"); - consumer.setConsumeThreadCount(15); - consumer.setTcpTransportTryLockTimeout(1000); - consumer.setTcpTransportConnectTimeout(400); - - MyMsgListener msglistener; - consumer.registerMessageListener(&msglistener); - - try { - consumer.start(); - } catch (MQClientException& e) { - cout << e << endl; - } - g_tps.start(); - - int msgcount = g_msgCount.load(); - for (int i = 0; i < msgcount; ++i) { - MQMessage msg(info.topic, // topic - "*", // tag - info.body); // body - - try { - producer.send(msg); - } catch (MQException& e) { - std::cout << e << endl; // if catch excepiton , need re-send this msg by - // service - } - } - - { - std::unique_lock lck(g_mtx); - g_finished.wait(lck); - } - producer.shutdown(); - consumer.shutdown(); - return 0; -} \ No newline at end of file diff --git a/example/BatchProducer.cpp b/example/BatchProducer.cpp index d889ea91f..12e95f7e5 100644 --- a/example/BatchProducer.cpp +++ b/example/BatchProducer.cpp @@ -1,75 +1,55 @@ /* -* 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + * 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 "common.h" using namespace rocketmq; -using namespace std; -boost::atomic g_quit; -std::mutex g_mtx; -std::condition_variable g_finished; + TpsReportService g_tps; void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) { - while (!g_quit.load()) { - if (g_msgCount.load() <= 0) { - std::unique_lock lck(g_mtx); - g_finished.notify_one(); - break; - } - - vector msgs; + while (g_msgCount.fetch_sub(1) > 0) { + std::vector msgs; MQMessage msg1(info->topic, "*", info->body); - msg1.setProperty("property1", "value1"); + msg1.putProperty("property1", "value1"); MQMessage msg2(info->topic, "*", info->body); - msg2.setProperty("property1", "value1"); - msg2.setProperty("property2", "value2"); + msg2.putProperty("property1", "value1"); + msg2.putProperty("property2", "value2"); MQMessage msg3(info->topic, "*", info->body); - msg3.setProperty("property1", "value1"); - msg3.setProperty("property2", "value2"); - msg3.setProperty("property3", "value3"); - msgs.push_back(msg1); - msgs.push_back(msg2); - msgs.push_back(msg3); + msg3.putProperty("property1", "value1"); + msg3.putProperty("property2", "value2"); + msg3.putProperty("property3", "value3"); + msgs.push_back(&msg1); + msgs.push_back(&msg2); + msgs.push_back(&msg3); + try { auto start = std::chrono::system_clock::now(); SendResult sendResult = producer->send(msgs); - g_tps.Increment(); - --g_msgCount; auto end = std::chrono::system_clock::now(); + + g_tps.Increment(); + auto duration = std::chrono::duration_cast(end - start); if (duration.count() >= 500) { - std::cout << "send RT more than: " << duration.count() << " ms with msgid: " << sendResult.getMsgId() << endl; + std::cout << "send RT more than: " << duration.count() << "ms with msgid: " << sendResult.getMsgId() + << std::endl; } } catch (const MQException& e) { std::cout << "send failed: " << e.what() << std::endl; - std::unique_lock lck(g_mtx); - g_finished.notify_one(); - return; } } } @@ -80,45 +60,43 @@ int main(int argc, char* argv[]) { exit(-1); } PrintRocketmqSendAndConsumerArgs(info); - DefaultMQProducer producer("please_rename_unique_group_name"); - producer.setNamesrvAddr(info.namesrv); - producer.setNamesrvDomain(info.namesrv_domain); - producer.setGroupName(info.groupname); - producer.setInstanceName(info.groupname); - producer.setSessionCredentials("mq acesskey", "mq secretkey", "ALIYUN"); - producer.setSendMsgTimeout(500); - producer.setTcpTransportTryLockTimeout(1000); - producer.setTcpTransportConnectTimeout(400); - - producer.start(); + + auto* producer = new DefaultMQProducer(info.groupname); + producer->setNamesrvAddr(info.namesrv); + producer->setGroupName(info.groupname); + producer->setSendMsgTimeout(3000); + producer->setRetryTimes(info.retrytimes); + producer->setRetryTimes4Async(info.retrytimes); + producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker); + producer->setTcpTransportTryLockTimeout(1000); + producer->setTcpTransportConnectTimeout(400); + producer->start(); + std::vector> work_pool; - auto start = std::chrono::system_clock::now(); int msgcount = g_msgCount.load(); g_tps.start(); + auto start = std::chrono::system_clock::now(); + int threadCount = info.thread_count; for (int j = 0; j < threadCount; j++) { - std::shared_ptr th = std::make_shared(SyncProducerWorker, &info, &producer); + std::shared_ptr th = std::make_shared(SyncProducerWorker, &info, producer); work_pool.push_back(th); } - { - std::unique_lock lck(g_mtx); - g_finished.wait(lck); - g_quit.store(true); + for (size_t th = 0; th != work_pool.size(); ++th) { + work_pool[th]->join(); } auto end = std::chrono::system_clock::now(); auto duration = std::chrono::duration_cast(end - start); - std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms \n" - << "========================finished==============================\n"; + std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms" << std::endl + << "========================finished=============================" << std::endl; - for (size_t th = 0; th != work_pool.size(); ++th) { - work_pool[th]->join(); - } + producer->shutdown(); - producer.shutdown(); + delete producer; return 0; } diff --git a/example/CAsyncProducer.c b/example/CAsyncProducer.c index 2d2af61d5..7f58c2929 100644 --- a/example/CAsyncProducer.c +++ b/example/CAsyncProducer.c @@ -14,12 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include -#include "CProducer.h" -#include "CCommon.h" -#include "CMessage.h" -#include "CSendResult.h" + #ifdef _WIN32 #include #else @@ -27,6 +23,8 @@ #include #endif +#include "c/CProducer.h" + void thread_sleep(unsigned milliseconds) { #ifdef _WIN32 Sleep(milliseconds); diff --git a/example/CBatchProducer.c b/example/CBatchProducer.c index 148d9f068..de40e0434 100644 --- a/example/CBatchProducer.c +++ b/example/CBatchProducer.c @@ -14,14 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include #include -#include "CBatchMessage.h" -#include "CCommon.h" -#include "CMessage.h" -#include "CProducer.h" -#include "CSendResult.h" + +#include "c/CProducer.h" void StartSendMessage(CProducer* producer) { int i = 0; diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index aecec5cf2..6ef72a805 100755 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -18,17 +18,13 @@ project(example) set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin) include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories(${Boost_INCLUDE_DIRS}) +include_directories(${CMAKE_SOURCE_DIR}/src) -link_directories(${Boost_LIBRARY_DIRS}) link_directories(${LIBEVENT_LIBRARY}) link_directories(${JSONCPP_LIBRARY}) -#if (BUILD_ROCKETMQ_SHARED) -# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBOOST_ALL_DYN_LINK -shared ") -#endif() - -file(GLOB files "*.c*") +file(GLOB files RELATIVE "${PROJECT_SOURCE_DIR}" "*.c*") +list(REMOVE_ITEM files "ArgHelper.cpp") foreach(file ${files}) get_filename_component(basename ${file} NAME_WE) add_executable(${basename} ${file}) @@ -42,11 +38,9 @@ foreach(file ${files}) if (MSVC) if (BUILD_ROCKETMQ_SHARED) - target_link_libraries (${basename} rocketmq_shared ${deplibs} - ${Boost_LIBRARIES} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES}) + target_link_libraries (${basename} rocketmq_shared ${deplibs} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES}) else() - target_link_libraries (${basename} rocketmq_static ${deplibs} - ${Boost_LIBRARIES} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES}) + target_link_libraries (${basename} rocketmq_static ${deplibs} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES}) endif() else() if (BUILD_ROCKETMQ_SHARED) diff --git a/example/COrderlyAsyncProducer.c b/example/COrderlyAsyncProducer.c index 48a822cec..9cf04f0ba 100644 --- a/example/COrderlyAsyncProducer.c +++ b/example/COrderlyAsyncProducer.c @@ -14,12 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include -#include "CProducer.h" -#include "CCommon.h" -#include "CMessage.h" -#include "CSendResult.h" + #ifdef _WIN32 #include #else @@ -27,6 +23,8 @@ #include #endif +#include "c/CProducer.h" + void thread_sleep(unsigned milliseconds) { #ifdef _WIN32 Sleep(milliseconds); diff --git a/example/OrderProducer.cpp b/example/OrderProducer.cpp deleted file mode 100644 index 613add4b8..000000000 --- a/example/OrderProducer.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* -* 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 -#include -#include - -#include -#include -#include -#include -#include - -#include "common.h" - -using namespace rocketmq; - -std::condition_variable g_finished; -std::mutex g_mtx; -boost::atomic g_quit(false); - -class SelectMessageQueueByHash : public MessageQueueSelector { - public: - MQMessageQueue select(const std::vector& mqs, const MQMessage& msg, void* arg) { - int orderId = *static_cast(arg); - int index = orderId % mqs.size(); - return mqs[index]; - } -}; - -SelectMessageQueueByHash g_mySelector; - -void ProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) { - while (!g_quit.load()) { - if (g_msgCount.load() <= 0) { - std::unique_lock lck(g_mtx); - g_finished.notify_one(); - } - MQMessage msg(info->topic, // topic - "*", // tag - info->body); // body - - int orderId = 1; - SendResult sendResult = - producer->send(msg, &g_mySelector, static_cast(&orderId), info->retrytimes, info->SelectUnactiveBroker); - --g_msgCount; - } -} - -int main(int argc, char* argv[]) { - RocketmqSendAndConsumerArgs info; - if (!ParseArgs(argc, argv, &info)) { - exit(-1); - } - - DefaultMQProducer producer("please_rename_unique_group_name"); - PrintRocketmqSendAndConsumerArgs(info); - - producer.setNamesrvAddr(info.namesrv); - producer.setNamesrvDomain(info.namesrv_domain); - producer.setGroupName(info.groupname); - producer.setInstanceName(info.groupname); - - producer.start(); - - int msgcount = g_msgCount.load(); - std::vector> work_pool; - - int threadCount = info.thread_count; - for (int j = 0; j < threadCount; j++) { - std::shared_ptr th = std::make_shared(ProducerWorker, &info, &producer); - work_pool.push_back(th); - } - - auto start = std::chrono::system_clock::now(); - { - std::unique_lock lck(g_mtx); - g_finished.wait(lck); - g_quit.store(true); - } - - auto end = std::chrono::system_clock::now(); - auto duration = std::chrono::duration_cast(end - start); - - std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms \n" - << "========================finished==============================\n"; - - for (size_t th = 0; th != work_pool.size(); ++th) { - work_pool[th]->join(); - } - - producer.shutdown(); - - return 0; -} diff --git a/example/OrderlyProducer.cpp b/example/OrderlyProducer.cpp new file mode 100644 index 000000000..237532b9d --- /dev/null +++ b/example/OrderlyProducer.cpp @@ -0,0 +1,103 @@ +/* + * 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 "common.h" + +using namespace rocketmq; + +TpsReportService g_tps; + +class SelectMessageQueueByHash : public MessageQueueSelector { + public: + MQMessageQueue select(const std::vector& mqs, const MQMessage& msg, void* arg) { + int orderId = *static_cast(arg); + int index = orderId % mqs.size(); + return mqs[index]; + } +}; + +SelectMessageQueueByHash g_mySelector; + +void ProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) { + while (g_msgCount.fetch_sub(1) > 0) { + MQMessage msg(info->topic, // topic + "*", // tag + info->body); // body + try { + auto start = std::chrono::system_clock::now(); + int orderId = 1; + SendResult sendResult = producer->send(&msg, &g_mySelector, static_cast(&orderId), info->retrytimes); + auto end = std::chrono::system_clock::now(); + + g_tps.Increment(); + + auto duration = std::chrono::duration_cast(end - start); + if (duration.count() >= 500) { + std::cout << "send RT more than: " << duration.count() << "ms with msgid: " << sendResult.getMsgId() + << std::endl; + } + } catch (const MQException& e) { + std::cout << "send failed: " << e.what() << std::endl; + } + } +} + +int main(int argc, char* argv[]) { + RocketmqSendAndConsumerArgs info; + if (!ParseArgs(argc, argv, &info)) { + exit(-1); + } + PrintRocketmqSendAndConsumerArgs(info); + + auto* producer = new DefaultMQProducer(info.groupname); + producer->setNamesrvAddr(info.namesrv); + producer->setGroupName(info.groupname); + producer->setSendMsgTimeout(3000); + producer->setRetryTimes(info.retrytimes); + producer->setRetryTimes4Async(info.retrytimes); + producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker); + producer->setTcpTransportTryLockTimeout(1000); + producer->setTcpTransportConnectTimeout(400); + producer->start(); + + std::vector> work_pool; + int msgcount = g_msgCount.load(); + g_tps.start(); + + auto start = std::chrono::system_clock::now(); + + int threadCount = info.thread_count; + for (int j = 0; j < threadCount; j++) { + std::shared_ptr th = std::make_shared(ProducerWorker, &info, producer); + work_pool.push_back(th); + } + + for (size_t th = 0; th != work_pool.size(); ++th) { + work_pool[th]->join(); + } + + auto end = std::chrono::system_clock::now(); + auto duration = std::chrono::duration_cast(end - start); + + std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms" << std::endl + << "========================finished=============================" << std::endl; + + producer->shutdown(); + + delete producer; + + return 0; +} diff --git a/example/OrderlyPushConsumer.cpp b/example/OrderlyPushConsumer.cpp index c8a9eaa10..2d8a54120 100644 --- a/example/OrderlyPushConsumer.cpp +++ b/example/OrderlyPushConsumer.cpp @@ -1,56 +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. -*/ -#include -#include - -#include -#include -#include -#include -#include -#include -#include - + * 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 "common.h" +#include "concurrent/latch.hpp" using namespace rocketmq; -std::condition_variable g_finished; -std::mutex g_mtx; -boost::atomic g_consumedCount(0); -boost::atomic g_quit(false); TpsReportService g_tps; +latch g_finished(1); class MyMsgListener : public MessageListenerOrderly { public: MyMsgListener() {} virtual ~MyMsgListener() {} - virtual ConsumeStatus consumeMessage(const vector& msgs) { - if (g_consumedCount.load() >= g_msgCount) { - std::unique_lock lK(g_mtx); - g_quit.store(true); - g_finished.notify_one(); + virtual ConsumeStatus consumeMessage(const std::vector& msgs) { + auto old = g_msgCount.fetch_sub(msgs.size()); + if (old > 0) { + for (size_t i = 0; i < msgs.size(); ++i) { + g_tps.Increment(); + // std::cout << msgs[i]->getMsgId() << std::endl; + // std::cout << "msg body: " << msgs[i].getBody() << std::endl; + } + if (old <= msgs.size()) { + g_finished.count_down(); + } + return CONSUME_SUCCESS; + } else { + return RECONSUME_LATER; } - for (size_t i = 0; i < msgs.size(); i++) { - ++g_consumedCount; - g_tps.Increment(); - } - return CONSUME_SUCCESS; } }; @@ -60,53 +51,33 @@ int main(int argc, char* argv[]) { exit(-1); } PrintRocketmqSendAndConsumerArgs(info); - DefaultMQPushConsumer consumer("please_rename_unique_group_name"); - DefaultMQProducer producer("please_rename_unique_group_name"); - - producer.setNamesrvAddr(info.namesrv); - producer.setGroupName("msg-persist-group_producer_sandbox"); - producer.start(); - consumer.setNamesrvAddr(info.namesrv); - consumer.setNamesrvDomain(info.namesrv_domain); - consumer.setGroupName(info.groupname); - consumer.setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET); - consumer.subscribe(info.topic, "*"); - consumer.setConsumeThreadCount(info.thread_count); - consumer.setConsumeMessageBatchMaxSize(31); - if (info.syncpush) - consumer.setAsyncPull(false); + auto* consumer = new DefaultMQPushConsumer(info.groupname); + consumer->setNamesrvAddr(info.namesrv); + consumer->setGroupName(info.groupname); + consumer->setTcpTransportTryLockTimeout(1000); + consumer->setTcpTransportConnectTimeout(400); + consumer->setConsumeThreadNum(info.thread_count); + consumer->setConsumeMessageBatchMaxSize(31); + consumer->setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET); + consumer->subscribe(info.topic, "*"); MyMsgListener msglistener; - consumer.registerMessageListener(&msglistener); + consumer->registerMessageListener(&msglistener); + g_tps.start(); try { - consumer.start(); + consumer->start(); } catch (MQClientException& e) { std::cout << e << std::endl; } - int msgcount = g_msgCount.load(); - for (int i = 0; i < msgcount; ++i) { - MQMessage msg(info.topic, // topic - "*", // tag - info.body); // body + g_finished.wait(); - try { - producer.send(msg); - } catch (MQException& e) { - std::cout << e << endl; // if catch excepiton , need re-send this msg by - // service - } - } + consumer->shutdown(); - while (!g_quit.load()) { - std::unique_lock lk(g_mtx); - g_finished.wait(lk); - } + delete consumer; - producer.shutdown(); - consumer.shutdown(); return 0; } diff --git a/example/Producer.c b/example/Producer.c index 9ae23a94d..86939923c 100644 --- a/example/Producer.c +++ b/example/Producer.c @@ -1,37 +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. - */ - +* 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 -#include "CCommon.h" -#include "CMessage.h" -#include "CProducer.h" -#include "CSendResult.h" + #ifdef _WIN32 #include #else -#include #include +#include #endif -void thread_sleep(unsigned int milliseconds) { +#include "c/CProducer.h" + +void thread_sleep(unsigned milliseconds) { #ifdef _WIN32 Sleep(milliseconds); #else - usleep(milliseconds * 1000); // suspend execution for microsecond intervals + usleep(milliseconds * 1000); // takes microseconds #endif } @@ -42,32 +40,26 @@ void StartSendMessage(CProducer* producer) { SetMessageTags(msg, "Test_Tag"); SetMessageKeys(msg, "Test_Keys"); CSendResult result; - for (i = 0; i < 3; i++) { + for (i = 0; i < 10; i++) { memset(body, 0, sizeof(body)); snprintf(body, sizeof(body), "new message body, index %d", i); SetMessageBody(msg, body); - int status = SendMessageSync(producer, msg, &result); - if (status == OK) { - printf("send message[%d] result status:%d, msgId:%s\n", i, (int)result.sendStatus, result.msgId); - } else { - printf("send message[%d] failed !\n", i); - } + SendMessageSync(producer, msg, &result); + printf("send message[%d] result status:%d, msgId:%s\n", i, (int)result.sendStatus, result.msgId); thread_sleep(1000); } DestroyMessage(msg); } int main(int argc, char* argv[]) { + printf("Producer Initializing.....\n"); CProducer* producer = CreateProducer("Group_producer"); SetProducerNameServerAddress(producer, "127.0.0.1:9876"); StartProducer(producer); - printf("Producer initialized. \n"); - + printf("Producer start.....\n"); StartSendMessage(producer); - ShutdownProducer(producer); DestroyProducer(producer); - printf("Producer stopped !\n"); - + printf("Producer Shutdown!\n"); return 0; } diff --git a/example/PullConsumeMessage.c b/example/PullConsumeMessage.c index 0868d08d0..297754367 100644 --- a/example/PullConsumeMessage.c +++ b/example/PullConsumeMessage.c @@ -14,13 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include -#include "CPullConsumer.h" -#include "CCommon.h" -#include "CMessageExt.h" -#include "CPullResult.h" -#include "CMessageQueue.h" + #ifdef _WIN32 #include #else @@ -28,6 +23,8 @@ #include #endif +#include "c/CPullConsumer.h" + void thread_sleep(unsigned milliseconds) { #ifdef _WIN32 Sleep(milliseconds); diff --git a/example/PullConsumer.cpp b/example/PullConsumer.cpp index 52e9094d6..6046d6c60 100644 --- a/example/PullConsumer.cpp +++ b/example/PullConsumer.cpp @@ -1,20 +1,19 @@ /* -* 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. -*/ - + * 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 #include @@ -35,7 +34,7 @@ void putMessageQueueOffset(MQMessageQueue mq, uint64_t offset) { } uint64_t getMessageQueueOffset(MQMessageQueue mq) { - map::iterator it = g_offseTable.find(mq); + auto it = g_offseTable.find(mq); if (it != g_offseTable.end()) { return it->second; } @@ -50,9 +49,7 @@ int main(int argc, char* argv[]) { PrintRocketmqSendAndConsumerArgs(info); DefaultMQPullConsumer consumer("please_rename_unique_group_name"); consumer.setNamesrvAddr(info.namesrv); - consumer.setNamesrvDomain(info.namesrv_domain); consumer.setGroupName(info.groupname); - consumer.setInstanceName(info.groupname); consumer.registerMessageQueueListener(info.topic, NULL); consumer.start(); std::vector mqs; @@ -61,10 +58,10 @@ int main(int argc, char* argv[]) { consumer.fetchSubscribeMessageQueues(info.topic, mqs); auto iter = mqs.begin(); for (; iter != mqs.end(); ++iter) { - std::cout << "mq:" << (*iter).toString() << endl; + std::cout << "mq:" << iter->toString() << std::endl; } } catch (MQException& e) { - std::cout << e << endl; + std::cout << e << std::endl; } auto start = std::chrono::system_clock::now(); @@ -89,7 +86,7 @@ int main(int argc, char* argv[]) { putMessageQueueOffset(mq, result.nextBeginOffset); PrintPullResult(&result); } else { - cout << "broker timeout occur" << endl; + std::cout << "broker timeout occur" << std::endl; } switch (result.pullStatus) { case FOUND: @@ -117,5 +114,6 @@ int main(int argc, char* argv[]) { << "========================finished==============================\n"; consumer.shutdown(); + return 0; } diff --git a/example/PushConsumeMessage.c b/example/PushConsumeMessage.c index 2cb9c3f49..de8b647c7 100644 --- a/example/PushConsumeMessage.c +++ b/example/PushConsumeMessage.c @@ -14,11 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include -#include "CPushConsumer.h" -#include "CCommon.h" -#include "CMessageExt.h" + #ifdef _WIN32 #include #else @@ -26,6 +23,8 @@ #include #endif +#include "c/CPushConsumer.h" + void thread_sleep(unsigned milliseconds) { #ifdef _WIN32 Sleep(milliseconds); diff --git a/example/PushConsumer.cpp b/example/PushConsumer.cpp index f0d4926cf..9aba07c5b 100644 --- a/example/PushConsumer.cpp +++ b/example/PushConsumer.cpp @@ -1,56 +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. -*/ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - + * 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 "common.h" - -std::mutex g_mtx; -std::condition_variable g_finished; -TpsReportService g_tps; +#include "concurrent/latch.hpp" using namespace rocketmq; +TpsReportService g_tps; +latch g_finished(1); + class MyMsgListener : public MessageListenerConcurrently { public: MyMsgListener() {} virtual ~MyMsgListener() {} - virtual ConsumeStatus consumeMessage(const std::vector& msgs) { - g_msgCount.store(g_msgCount.load() - msgs.size()); - for (size_t i = 0; i < msgs.size(); ++i) { - g_tps.Increment(); - // cout << "msg body: "<< msgs[i].getBody() << endl; - } - - if (g_msgCount.load() <= 0) { - std::unique_lock lck(g_mtx); - g_finished.notify_one(); + virtual ConsumeStatus consumeMessage(const std::vector& msgs) { + auto old = g_msgCount.fetch_sub(msgs.size()); + if (old > 0) { + for (size_t i = 0; i < msgs.size(); ++i) { + g_tps.Increment(); + // std::cout << msgs[i]->getMsgId() << std::endl; + // std::cout << "msg body: " << msgs[i].getBody() << std::endl; + } + if (old <= msgs.size()) { + g_finished.count_down(); + } + return CONSUME_SUCCESS; + } else { + return RECONSUME_LATER; } - return CONSUME_SUCCESS; } }; @@ -60,66 +51,37 @@ int main(int argc, char* argv[]) { exit(-1); } PrintRocketmqSendAndConsumerArgs(info); - DefaultMQPushConsumer consumer("please_rename_unique_group_name"); - DefaultMQProducer producer("please_rename_unique_group_name"); - producer.setSessionCredentials("AccessKey", "SecretKey", "ALIYUN"); - producer.setTcpTransportTryLockTimeout(1000); - producer.setTcpTransportConnectTimeout(400); - producer.setNamesrvDomain(info.namesrv_domain); - producer.setNamesrvAddr(info.namesrv); - producer.setGroupName("msg-persist-group_producer_sandbox"); - producer.start(); - consumer.setNamesrvAddr(info.namesrv); - consumer.setGroupName(info.groupname); - consumer.setSessionCredentials("AccessKey", "SecretKey", "ALIYUN"); - consumer.setConsumeThreadCount(info.thread_count); - consumer.setNamesrvDomain(info.namesrv_domain); - consumer.setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET); + auto* consumer = new DefaultMQPushConsumer(info.groupname); + consumer->setNamesrvAddr(info.namesrv); + consumer->setGroupName(info.groupname); + consumer->setTcpTransportTryLockTimeout(1000); + consumer->setTcpTransportConnectTimeout(400); + consumer->setConsumeThreadNum(info.thread_count); + consumer->setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET); - if (info.syncpush) - consumer.setAsyncPull(false); // set sync pull if (info.broadcasting) { - consumer.setMessageModel(rocketmq::BROADCASTING); + consumer->setMessageModel(rocketmq::BROADCASTING); } - consumer.setInstanceName(info.groupname); - - consumer.subscribe(info.topic, "*"); - consumer.setConsumeThreadCount(15); - consumer.setTcpTransportTryLockTimeout(1000); - consumer.setTcpTransportConnectTimeout(400); + consumer->subscribe(info.topic, "*"); MyMsgListener msglistener; - consumer.registerMessageListener(&msglistener); + consumer->registerMessageListener(&msglistener); + + g_tps.start(); try { - consumer.start(); + consumer->start(); } catch (MQClientException& e) { - cout << e << endl; + std::cout << e << std::endl; } - g_tps.start(); - int msgcount = g_msgCount.load(); - for (int i = 0; i < msgcount; ++i) { - MQMessage msg(info.topic, // topic - "*", // tag - info.body); // body + g_finished.wait(); - // std::this_thread::sleep_for(std::chrono::seconds(100000)); - try { - producer.send(msg); - } catch (MQException& e) { - std::cout << e << endl; // if catch excepiton , need re-send this msg by - // service - } - } + consumer->shutdown(); + + delete consumer; - { - std::unique_lock lck(g_mtx); - g_finished.wait(lck); - } - producer.shutdown(); - consumer.shutdown(); return 0; } diff --git a/example/PushConsumerOrderly.c b/example/PushConsumerOrderly.c index 4b2c2bbbd..2fd9c6f9a 100644 --- a/example/PushConsumerOrderly.c +++ b/example/PushConsumerOrderly.c @@ -14,13 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include + #ifndef WIN32 #include #endif -#include -#include "CPushConsumer.h" -#include "CCommon.h" -#include "CMessageExt.h" + +#include "c/CPushConsumer.h" int doConsumeMessage(struct CPushConsumer* consumer, CMessageExt* msgExt) { printf("Hello,doConsumeMessage by Application!\n"); diff --git a/example/SendDelayMsg.cpp b/example/SendDelayMsg.cpp index 248642780..3a5b6ce20 100644 --- a/example/SendDelayMsg.cpp +++ b/example/SendDelayMsg.cpp @@ -1,31 +1,19 @@ /* -* 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 -#include -#include - -#include -#include -#include -#include -#include -#include -#include - + * 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 "common.h" using namespace rocketmq; @@ -36,31 +24,30 @@ int main(int argc, char* argv[]) { exit(-1); } PrintRocketmqSendAndConsumerArgs(info); - DefaultMQProducer producer("please_rename_unique_group_name"); - producer.setNamesrvAddr(info.namesrv); - producer.setNamesrvDomain(info.namesrv_domain); - producer.setGroupName(info.groupname); - producer.setInstanceName(info.groupname); - - producer.setSendMsgTimeout(500); - producer.setTcpTransportTryLockTimeout(1000); - producer.setTcpTransportConnectTimeout(400); - producer.start(); + auto* producer = new DefaultMQProducer(info.groupname); + producer->setNamesrvAddr(info.namesrv); + producer->setGroupName(info.groupname); + producer->setSendMsgTimeout(3000); + producer->setTcpTransportTryLockTimeout(1000); + producer->setTcpTransportConnectTimeout(400); + producer->start(); MQMessage msg(info.topic, // topic "*", // tag info.body); // body - // messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h - // 2h + // messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h msg.setDelayTimeLevel(5); // 1m try { - SendResult sendResult = producer.send(msg, info.SelectUnactiveBroker); + SendResult sendResult = producer->send(&msg); } catch (const MQException& e) { std::cout << "send failed: " << std::endl; } - producer.shutdown(); + producer->shutdown(); + + delete producer; + return 0; } diff --git a/example/SyncProducer.cpp b/example/SyncProducer.cpp index 0edb6dc8e..d840fdd3d 100644 --- a/example/SyncProducer.cpp +++ b/example/SyncProducer.cpp @@ -1,61 +1,44 @@ /* -* 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 -#include -#include - -#include -#include -#include -#include -#include -#include -#include - + * 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 "common.h" using namespace rocketmq; -boost::atomic g_quit; -std::mutex g_mtx; -std::condition_variable g_finished; TpsReportService g_tps; void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) { - while (!g_quit.load()) { - if (g_msgCount.load() <= 0) { - std::unique_lock lck(g_mtx); - g_finished.notify_one(); - } + while (g_msgCount.fetch_sub(1) > 0) { MQMessage msg(info->topic, // topic "*", // tag info->body); // body try { auto start = std::chrono::system_clock::now(); - SendResult sendResult = producer->send(msg, info->SelectUnactiveBroker); - g_tps.Increment(); - --g_msgCount; + SendResult sendResult = producer->send(&msg); auto end = std::chrono::system_clock::now(); + + g_tps.Increment(); + auto duration = std::chrono::duration_cast(end - start); if (duration.count() >= 500) { - std::cout << "send RT more than: " << duration.count() << " ms with msgid: " << sendResult.getMsgId() << endl; + std::cout << "send RT more than: " << duration.count() << "ms with msgid: " << sendResult.getMsgId() + << std::endl; } } catch (const MQException& e) { - std::cout << "send failed: " << std::endl; + std::cout << "send failed: " << e.what() << std::endl; } } } @@ -66,45 +49,43 @@ int main(int argc, char* argv[]) { exit(-1); } PrintRocketmqSendAndConsumerArgs(info); - DefaultMQProducer producer("please_rename_unique_group_name"); - producer.setNamesrvAddr(info.namesrv); - producer.setNamesrvDomain(info.namesrv_domain); - producer.setGroupName(info.groupname); - producer.setInstanceName(info.groupname); - producer.setSessionCredentials("mq acesskey", "mq secretkey", "ALIYUN"); - producer.setSendMsgTimeout(500); - producer.setTcpTransportTryLockTimeout(1000); - producer.setTcpTransportConnectTimeout(400); - - producer.start(); + + auto* producer = new DefaultMQProducer(info.groupname); + producer->setNamesrvAddr(info.namesrv); + producer->setGroupName(info.groupname); + producer->setSendMsgTimeout(3000); + producer->setRetryTimes(info.retrytimes); + producer->setRetryTimes4Async(info.retrytimes); + producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker); + producer->setTcpTransportTryLockTimeout(1000); + producer->setTcpTransportConnectTimeout(400); + producer->start(); + std::vector> work_pool; - auto start = std::chrono::system_clock::now(); int msgcount = g_msgCount.load(); g_tps.start(); + auto start = std::chrono::system_clock::now(); + int threadCount = info.thread_count; for (int j = 0; j < threadCount; j++) { - std::shared_ptr th = std::make_shared(SyncProducerWorker, &info, &producer); + std::shared_ptr th = std::make_shared(SyncProducerWorker, &info, producer); work_pool.push_back(th); } - { - std::unique_lock lck(g_mtx); - g_finished.wait(lck); - g_quit.store(true); + for (size_t th = 0; th != work_pool.size(); ++th) { + work_pool[th]->join(); } auto end = std::chrono::system_clock::now(); auto duration = std::chrono::duration_cast(end - start); - std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms \n" - << "========================finished==============================\n"; + std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms" << std::endl + << "========================finished=============================" << std::endl; - for (size_t th = 0; th != work_pool.size(); ++th) { - work_pool[th]->join(); - } + producer->shutdown(); - producer.shutdown(); + delete producer; return 0; } diff --git a/example/TransactionProducer.cpp b/example/TransactionProducer.cpp index 1aabb0887..f6985f980 100644 --- a/example/TransactionProducer.cpp +++ b/example/TransactionProducer.cpp @@ -14,73 +14,49 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#include -#include -#include -#include -#include -#include -#include "TransactionListener.h" -#include "TransactionMQProducer.h" -#include "TransactionSendResult.h" #include "common.h" using namespace rocketmq; -std::atomic g_quit; -std::mutex g_mtx; -std::condition_variable g_finished; TpsReportService g_tps; class MyTransactionListener : public TransactionListener { virtual LocalTransactionState executeLocalTransaction(const MQMessage& msg, void* arg) { - if (!arg) { - std::cout << "executeLocalTransaction transactionId:" << msg.getTransactionId() - << ", return state: COMMIT_MESAGE " << endl; - return LocalTransactionState::COMMIT_MESSAGE; - } - - LocalTransactionState state = (LocalTransactionState)(*(int*)arg % 3); + LocalTransactionState state = (LocalTransactionState)(((intptr_t)arg) % 3); std::cout << "executeLocalTransaction transactionId:" << msg.getTransactionId() << ", return state: " << state - << endl; + << std::endl; return state; } virtual LocalTransactionState checkLocalTransaction(const MQMessageExt& msg) { - std::cout << "checkLocalTransaction enter msg:" << msg.toString() << endl; + std::cout << "checkLocalTransaction enter msg:" << msg.toString() << std::endl; return LocalTransactionState::COMMIT_MESSAGE; } }; void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, TransactionMQProducer* producer) { - while (!g_quit.load()) { - if (g_msgCount.load() <= 0) { - std::this_thread::sleep_for(std::chrono::seconds(60)); - std::unique_lock lck(g_mtx); - g_finished.notify_one(); - break; - } - + int old = g_msgCount.fetch_sub(1); + while (old > 0) { MQMessage msg(info->topic, // topic "*", // tag info->body); // body try { auto start = std::chrono::system_clock::now(); - std::cout << "before sendMessageInTransaction" << endl; - LocalTransactionState state = LocalTransactionState::UNKNOWN; - TransactionSendResult sendResult = producer->sendMessageInTransaction(msg, &state); - std::cout << "after sendMessageInTransaction msgId: " << sendResult.getMsgId() << endl; - g_tps.Increment(); - --g_msgCount; + intptr_t arg = old - 1; + TransactionSendResult sendResult = producer->sendMessageInTransaction(&msg, (void*)arg); auto end = std::chrono::system_clock::now(); + + g_tps.Increment(); + auto duration = std::chrono::duration_cast(end - start); if (duration.count() >= 500) { - std::cout << "send RT more than: " << duration.count() << " ms with msgid: " << sendResult.getMsgId() << endl; + std::cout << "send RT more than: " << duration.count() << "ms with msgid: " << sendResult.getMsgId() + << std::endl; } } catch (const MQException& e) { std::cout << "send failed: " << e.what() << std::endl; } + old = g_msgCount.fetch_sub(1); } } @@ -90,46 +66,48 @@ int main(int argc, char* argv[]) { exit(-1); } PrintRocketmqSendAndConsumerArgs(info); - TransactionMQProducer producer("please_rename_unique_group_name"); - producer.setNamesrvAddr(info.namesrv); - producer.setNamesrvDomain(info.namesrv_domain); - producer.setGroupName(info.groupname); - producer.setInstanceName(info.groupname); - producer.setSessionCredentials("mq acesskey", "mq secretkey", "ALIYUN"); - producer.setSendMsgTimeout(500); - producer.setTcpTransportTryLockTimeout(1000); - producer.setTcpTransportConnectTimeout(400); - producer.setLogLevel(eLOG_LEVEL_DEBUG); - producer.setTransactionListener(new MyTransactionListener()); - producer.start(); + + auto* producer = new TransactionMQProducer(info.groupname); + producer->setNamesrvAddr(info.namesrv); + producer->setGroupName(info.groupname); + producer->setSendMsgTimeout(3000); + producer->setRetryTimes(info.retrytimes); + producer->setRetryTimes4Async(info.retrytimes); + producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker); + producer->setTcpTransportTryLockTimeout(1000); + producer->setTcpTransportConnectTimeout(400); + + MyTransactionListener myListener; + producer->setTransactionListener(&myListener); + + producer->start(); + std::vector> work_pool; - auto start = std::chrono::system_clock::now(); int msgcount = g_msgCount.load(); g_tps.start(); + auto start = std::chrono::system_clock::now(); + int threadCount = info.thread_count; for (int j = 0; j < threadCount; j++) { - std::shared_ptr th = std::make_shared(SyncProducerWorker, &info, &producer); + std::shared_ptr th = std::make_shared(SyncProducerWorker, &info, producer); work_pool.push_back(th); } - { - std::unique_lock lck(g_mtx); - g_finished.wait(lck); - g_quit.store(true); + for (size_t th = 0; th != work_pool.size(); ++th) { + work_pool[th]->join(); } auto end = std::chrono::system_clock::now(); auto duration = std::chrono::duration_cast(end - start); - std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms \n" - << "========================finished==============================\n"; + std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms" << std::endl + << "========================finished=============================" << std::endl; - for (size_t th = 0; th != work_pool.size(); ++th) { - work_pool[th]->join(); - } + std::this_thread::sleep_for(std::chrono::seconds(30)); + producer->shutdown(); - producer.shutdown(); + delete producer; return 0; } diff --git a/example/common.h b/example/common.h index 5b674c37e..db242f785 100644 --- a/example/common.h +++ b/example/common.h @@ -1,102 +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. -*/ + * 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_EXAMPLE_COMMON_H_ #define ROCKETMQ_CLIENT4CPP_EXAMPLE_COMMON_H_ -#include -#include -#include -#include +#include +#include #include +#include #include #include -#include -#include "Arg_helper.h" +#ifndef WIN32 +#include +#else +#include "ArgHelper.h" +#endif + #include "DefaultMQProducer.h" +#include "TransactionMQProducer.h" #include "DefaultMQPullConsumer.h" #include "DefaultMQPushConsumer.h" -using namespace std; -boost::atomic g_msgCount(1); +std::atomic g_msgCount(1); class RocketmqSendAndConsumerArgs { public: RocketmqSendAndConsumerArgs() : body("msgbody for test"), - thread_count(boost::thread::hardware_concurrency()), + thread_count(1), broadcasting(false), - syncpush(false), - SelectUnactiveBroker(false), - IsAutoDeleteSendCallback(false), - retrytimes(5), - PrintMoreInfo(false) {} + selectUnactiveBroker(false), + isAutoDeleteSendCallback(true), + retrytimes(1), + printMoreInfo(false) {} public: std::string namesrv; - std::string namesrv_domain; std::string groupname; std::string topic; std::string body; int thread_count; bool broadcasting; - bool syncpush; - bool SelectUnactiveBroker; // default select active broker - bool IsAutoDeleteSendCallback; - int retrytimes; // default retry 5 times; - bool PrintMoreInfo; + bool selectUnactiveBroker; // default select active broker + bool isAutoDeleteSendCallback; + int retrytimes; // default retry 1 times; + bool printMoreInfo; }; class TpsReportService { public: - TpsReportService() : tps_interval_(1), quit_flag_(false), tps_count_(0) {} + TpsReportService() : tps_interval_(1), quit_flag_(false), tps_count_(0), all_count_(0) {} + void start() { - if (tps_thread_ == NULL) { - std::cout << "tps_thread_ is null" << std::endl; - return; + if (tps_thread_ == nullptr) { + tps_thread_.reset(new std::thread(std::bind(&TpsReportService::TpsReport, this))); } - tps_thread_.reset(new boost::thread(boost::bind(&TpsReportService::TpsReport, this))); } ~TpsReportService() { quit_flag_.store(true); - if (tps_thread_ == NULL) { + + if (tps_thread_ == nullptr) { std::cout << "tps_thread_ is null" << std::endl; return; } - if (tps_thread_->joinable()) + + if (tps_thread_->joinable()) { tps_thread_->join(); + } } void Increment() { ++tps_count_; } void TpsReport() { while (!quit_flag_.load()) { - boost::this_thread::sleep_for(tps_interval_); - std::cout << "tps: " << tps_count_.load() << std::endl; - tps_count_.store(0); + std::this_thread::sleep_for(tps_interval_); + auto tps = tps_count_.exchange(0); + all_count_ += tps; + std::cout << "all: " << all_count_ << ", tps: " << tps << std::endl; } } private: - boost::chrono::seconds tps_interval_; - boost::shared_ptr tps_thread_; - boost::atomic quit_flag_; - boost::atomic tps_count_; + std::chrono::seconds tps_interval_; + std::shared_ptr tps_thread_; + std::atomic quit_flag_; + std::atomic tps_count_; + uint64_t all_count_; }; /* @@ -111,53 +115,46 @@ static void PrintResult(rocketmq::SendResult* result) { void PrintPullResult(rocketmq::PullResult* result) { std::cout << result->toString() << std::endl; if (result->pullStatus == rocketmq::FOUND) { - std::cout << result->toString() << endl; - std::vector::iterator it = result->msgFoundList.begin(); - for (; it != result->msgFoundList.end(); ++it) { - cout << "=======================================================" << endl << (*it).toString() << endl; + std::cout << result->toString() << std::endl; + for (auto& msg : result->msgFoundList) { + std::cout << "=======================================================" << std::endl + << msg->toString() << std::endl; } } } static void PrintRocketmqSendAndConsumerArgs(const RocketmqSendAndConsumerArgs& info) { - std::cout << "nameserver: " << info.namesrv << endl - << "topic: " << info.topic << endl - << "groupname: " << info.groupname << endl - << "produce content: " << info.body << endl - << "msg count: " << g_msgCount.load() << endl - << "thread count: " << info.thread_count << endl; + std::cout << "nameserver: " << info.namesrv << std::endl + << "topic: " << info.topic << std::endl + << "groupname: " << info.groupname << std::endl + << "produce content: " << info.body << std::endl + << "msg count: " << g_msgCount.load() << std::endl + << "thread count: " << info.thread_count << std::endl; } static void help() { - std::cout << "need option,like follow: \n" - << "-n nameserver addr, if not set -n and -i ,no nameSrv will be got \n" - "-i nameserver domain name, if not set -n and -i ,no nameSrv will be " - "got \n" - "-g groupname \n" - "-t msg topic \n" - "-m messagecout(default value: 1) \n" - "-c content(default value: only test ) \n" - "-b (BROADCASTING model, default value: CLUSTER) \n" - "-s sync push(default is async push)\n" - "-r setup retry times(default value: 5 times)\n" + std::cout << "need option, like follow:\n" + "-n nameserver addr, if not set -n and -i ,no nameSrv will be got\n" + "-g groupname\n" + "-t msg topic\n" + "-m messagecout(default value: 1)\n" + "-c content(default value: \"msgbody for test\")\n" + "-b (BROADCASTING model, default value: CLUSTER)\n" + "-r setup retry times(default value: 1)\n" "-u select active broker to send msg(default value: false)\n" - "-d use AutoDeleteSendcallback by cpp client(defalut value: false) \n" - "-T thread count of send msg or consume msg(defalut value: system cpu " - "core number) \n" - "-v print more details information \n"; + "-d use AutoDeleteSendcallback by cpp client(defalut value: false)\n" + "-T thread count of send msg or consume msg(defalut value: 1)\n" + "-v print more details information\n"; } static bool ParseArgs(int argc, char* argv[], RocketmqSendAndConsumerArgs* info) { #ifndef WIN32 int ch; - while ((ch = getopt(argc, argv, "n:i:g:t:m:c:b:s:h:r:T:bu")) != -1) { + while ((ch = getopt(argc, argv, "n:g:t:m:c:b:h:r:T:bu")) != -1) { switch (ch) { case 'n': info->namesrv.insert(0, optarg); break; - case 'i': - info->namesrv_domain.insert(0, optarg); - break; case 'g': info->groupname.insert(0, optarg); break; @@ -173,20 +170,17 @@ static bool ParseArgs(int argc, char* argv[], RocketmqSendAndConsumerArgs* info) case 'b': info->broadcasting = true; break; - case 's': - info->syncpush = true; - break; case 'r': info->retrytimes = atoi(optarg); break; case 'u': - info->SelectUnactiveBroker = true; + info->selectUnactiveBroker = true; break; case 'T': info->thread_count = atoi(optarg); break; case 'v': - info->PrintMoreInfo = true; + info->printMoreInfo = true; break; case 'h': help(); @@ -199,29 +193,31 @@ static bool ParseArgs(int argc, char* argv[], RocketmqSendAndConsumerArgs* info) #else rocketmq::Arg_helper arg_help(argc, argv); info->namesrv = arg_help.get_option_value("-n"); - info->namesrv_domain = arg_help.get_option_value("-i"); info->groupname = arg_help.get_option_value("-g"); info->topic = arg_help.get_option_value("-t"); info->broadcasting = atoi(arg_help.get_option_value("-b").c_str()); string msgContent(arg_help.get_option_value("-c")); - if (!msgContent.empty()) + if (!msgContent.empty()) { info->body = msgContent; - info->syncpush = atoi(arg_help.get_option_value("-s").c_str()); + } int retrytimes = atoi(arg_help.get_option_value("-r").c_str()); - if (retrytimes > 0) + if (retrytimes > 0) { info->retrytimes = retrytimes; - info->SelectUnactiveBroker = atoi(arg_help.get_option_value("-u").c_str()); + } + info->selectUnactiveBroker = atoi(arg_help.get_option_value("-u").c_str()); int thread_count = atoi(arg_help.get_option_value("-T").c_str()); - if (thread_count > 0) + if (thread_count > 0) { info->thread_count = thread_count; - info->PrintMoreInfo = atoi(arg_help.get_option_value("-v").c_str()); + } + info->printMoreInfo = atoi(arg_help.get_option_value("-v").c_str()); g_msgCount = atoi(arg_help.get_option_value("-m").c_str()); #endif - if (info->groupname.empty() || info->topic.empty() || (info->namesrv_domain.empty() && info->namesrv.empty())) { + if (info->groupname.empty() || info->topic.empty() || info->namesrv.empty()) { std::cout << "please use -g to setup groupname and -t setup topic \n"; help(); return false; } return true; } + #endif // ROCKETMQ_CLIENT4CPP_EXAMPLE_COMMON_H_ diff --git a/src/common/AsyncArg.h b/include/AllocateMQStrategy.h similarity index 62% rename from src/common/AsyncArg.h rename to include/AllocateMQStrategy.h index fc358cb0b..03436541b 100644 --- a/src/common/AsyncArg.h +++ b/include/AllocateMQStrategy.h @@ -1,36 +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 _AsyncArg_H_ -#define _AsyncArg_H_ - -#include "MQMessageQueue.h" -#include "PullAPIWrapper.h" -#include "SubscriptionData.h" - -namespace rocketmq { -// +#include + +#include "MQMessageQueue.h" + +namespace rocketmq { + +class ROCKETMQCLIENT_API AllocateMQStrategy { + public: + virtual ~AllocateMQStrategy() = default; + + virtual void allocate(const std::string& currentCID, + std::vector& mqAll, + std::vector& cidAll, + std::vector& outReuslt) = 0; +}; + +} // namespace rocketmq + +#endif // __ALLOCATE_MQ_STRATEGY_H__ diff --git a/include/AsyncCallback.h b/include/AsyncCallback.h deleted file mode 100644 index d9dbfe315..000000000 --- a/include/AsyncCallback.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 __SENDCALLBACK_H__ -#define __SENDCALLBACK_H__ - -#include "MQClientException.h" -#include "PullResult.h" -#include "RocketMQClient.h" -#include "SendResult.h" - -namespace rocketmq { -// -#include #include #include -#include "Logging.h" -#include "UtilAll.h" + +#include "RocketMQClient.h" + +namespace Json { +class Value; +} namespace rocketmq { -class TopAddressing { - public: - TopAddressing(string unitName); - virtual ~TopAddressing(); +class ROCKETMQCLIENT_API CommandCustomHeader { public: - virtual string fetchNSAddr(const string& NSDomain); + virtual ~CommandCustomHeader() = default; - private: - string clearNewLine(const string& str); - void updateNameServerAddressList(const string& adds); - int IsIPAddr(const char* sValue); + // write CustomHeader to extFields (map) + virtual void Encode(Json::Value& extFields) {} - private: - boost::mutex m_addrLock; - list m_addrs; - string m_unitName; + virtual void SetDeclaredFieldOfCommandHeader(std::map& requestMap) {} }; + } // namespace rocketmq -#endif + +#endif // __COMMAND_CUSTOM_HEADER_H__ diff --git a/include/ConsumeType.h b/include/ConsumeType.h index 4cbe5cd70..ab5482925 100644 --- a/include/ConsumeType.h +++ b/include/ConsumeType.h @@ -1,61 +1,63 @@ -/* - * 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 __CONSUMETYPE_H__ -#define __CONSUMETYPE_H__ - -namespace rocketmq { -//& msgs); - virtual SendResult send(std::vector& msgs, const MQMessageQueue& mq); - virtual void send(MQMessage& msg, SendCallback* pSendCallback, bool bSelectActiveBroker = false); - virtual void send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* pSendCallback); - virtual void send(MQMessage& msg, MessageQueueSelector* selector, void* arg, SendCallback* pSendCallback); - virtual void sendOneway(MQMessage& msg, bool bSelectActiveBroker = false); - virtual void sendOneway(MQMessage& msg, const MQMessageQueue& mq); - virtual void sendOneway(MQMessage& msg, MessageQueueSelector* selector, void* arg); - //& msgs); - bool dealWithNameSpace(); - - private: - int m_sendMsgTimeout; - int m_compressMsgBodyOverHowmuch; - int m_maxMessageSize; //= 0 && compressLevel <= 9) || compressLevel == -1) { + m_compressLevel = compressLevel; + } + } + + // set and get timeout of per msg + int getSendMsgTimeout() const { return m_sendMsgTimeout; } + void setSendMsgTimeout(int sendMsgTimeout) { m_sendMsgTimeout = sendMsgTimeout; } + + // set msg max retry times, default retry times is 5 + int getRetryTimes() const { return m_retryTimes; } + void setRetryTimes(int times) { m_retryTimes = std::min(std::max(0, times), 15); } + + int getRetryTimes4Async() const { return m_retryTimes4Async; } + void setRetryTimes4Async(int times) { m_retryTimes4Async = std::min(std::max(0, times), 15); } + + bool isRetryAnotherBrokerWhenNotStoreOK() const { return m_retryAnotherBrokerWhenNotStoreOK; } + void setRetryAnotherBrokerWhenNotStoreOK(bool retryAnotherBrokerWhenNotStoreOK) { + m_retryAnotherBrokerWhenNotStoreOK = retryAnotherBrokerWhenNotStoreOK; + } + + virtual bool isSendLatencyFaultEnable() const = 0; + virtual void setSendLatencyFaultEnable(bool sendLatencyFaultEnable) = 0; + + protected: + int m_maxMessageSize; // default: 4 MB + int m_compressMsgBodyOverHowmuch; // default: 4 KB + int m_compressLevel; + int m_sendMsgTimeout; + int m_retryTimes; + int m_retryTimes4Async; + bool m_retryAnotherBrokerWhenNotStoreOK; +}; + +class ROCKETMQCLIENT_API DefaultMQProducer : public MQProducer, public DefaultMQProducerConfig { + public: + DefaultMQProducer(const std::string& groupname); + DefaultMQProducer(const std::string& groupname, RPCHookPtr rpcHook); + virtual ~DefaultMQProducer(); + + public: // MQProducer + void start() override; + void shutdown() override; + + // Sync: caller will be responsible for the lifecycle of messages. + SendResult send(MQMessagePtr msg) override; + SendResult send(MQMessagePtr msg, long timeout) override; + SendResult send(MQMessagePtr msg, const MQMessageQueue& mq) override; + SendResult send(MQMessagePtr msg, const MQMessageQueue& mq, long timeout) override; + + // Async: don't delete msg object, until callback occur. + void send(MQMessagePtr msg, SendCallback* sendCallback) noexcept override; + void send(MQMessagePtr msg, SendCallback* sendCallback, long timeout) noexcept override; + void send(MQMessagePtr msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept override; + void send(MQMessagePtr msg, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) noexcept override; + + // Oneyway: same as sync send, but don't care its result. + void sendOneway(MQMessagePtr msg) override; + void sendOneway(MQMessagePtr msg, const MQMessageQueue& mq) override; + + // Select + SendResult send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) override; + SendResult send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg, long timeout) override; + void send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg, SendCallback* sendCallback) noexcept override; + void send(MQMessagePtr msg, + MessageQueueSelector* selector, + void* arg, + SendCallback* sendCallback, + long timeout) noexcept override; + void sendOneway(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) override; + + // Transaction + TransactionSendResult sendMessageInTransaction(MQMessagePtr msg, void* arg) override; + + // Batch: power by sync send, caller will be responsible for the lifecycle of messages. + SendResult send(std::vector& msgs) override; + SendResult send(std::vector& msgs, long timeout) override; + SendResult send(std::vector& msgs, const MQMessageQueue& mq) override; + SendResult send(std::vector& msgs, const MQMessageQueue& mq, long timeout) override; + + public: // DefaultMQProducerConfig + bool isSendLatencyFaultEnable() const override; + void setSendLatencyFaultEnable(bool sendLatencyFaultEnable) override; + + public: + void setRPCHook(std::shared_ptr rpcHook); + + protected: + std::shared_ptr m_producerDelegate; +}; + +} // namespace rocketmq + +#endif // __DEFAULT_MQ_PRODUCER_H__ diff --git a/include/DefaultMQPullConsumer.h b/include/DefaultMQPullConsumer.h old mode 100644 new mode 100755 index 8e1612d2c..1bd7affd4 --- a/include/DefaultMQPullConsumer.h +++ b/include/DefaultMQPullConsumer.h @@ -1,148 +1,93 @@ -/* - * 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 __DEFAULTMQPULLCONSUMER_H__ -#define __DEFAULTMQPULLCONSUMER_H__ - -#include -#include -#include "MQConsumer.h" -#include "MQMessageQueue.h" -#include "MQueueListener.h" -#include "RocketMQClient.h" - -namespace rocketmq { -class Rebalance; -class SubscriptionData; -class OffsetStore; -class PullAPIWrapper; -class ConsumerRunningInfo; -//& mqs); - virtual void doRebalance(); - virtual void persistConsumerOffset(); - virtual void persistConsumerOffsetByResetOffset(); - virtual void updateTopicSubscribeInfo(const std::string& topic, std::vector& info); - virtual ConsumeType getConsumeType(); - virtual ConsumeFromWhere getConsumeFromWhere(); - virtual void getSubscriptions(std::vector&); - virtual void updateConsumeOffset(const MQMessageQueue& mq, int64 offset); - virtual void removeConsumeOffset(const MQMessageQueue& mq); - virtual bool producePullMsgTask(boost::weak_ptr pullRequest); - virtual Rebalance* getRebalance() const; - // 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 m_registerTopics; - - MQueueListener* m_pMessageQueueListener; - OffsetStore* m_pOffsetStore; - Rebalance* m_pRebalance; - PullAPIWrapper* m_pPullAPIWrapper; -}; -// +#include + +#include "AllocateMQStrategy.h" +#include "DefaultMQConsumer.h" +#include "MQPullConsumer.h" +#include "RPCHook.h" + +namespace rocketmq { + +class ROCKETMQCLIENT_API DefaultMQPullConsumerConfig : public DefaultMQConsumerConfig { + public: + DefaultMQPullConsumerConfig(); + virtual ~DefaultMQPullConsumerConfig() = default; + + AllocateMQStrategy* getAllocateMQStrategy() { return m_allocateMQStrategy.get(); } + void setAllocateMQStrategy(AllocateMQStrategy* strategy) { m_allocateMQStrategy.reset(strategy); } + + protected: + std::unique_ptr m_allocateMQStrategy; +}; + +class ROCKETMQCLIENT_API DefaultMQPullConsumer : public MQPullConsumer, public DefaultMQPullConsumerConfig { + public: + DefaultMQPullConsumer(const std::string& groupname); + DefaultMQPullConsumer(const std::string& groupname, RPCHookPtr rpcHook); + virtual ~DefaultMQPullConsumer(); + + public: // MQConsumer + void start() override; + void shutdown() override; + + bool sendMessageBack(MQMessageExt& msg, int delayLevel) override; + bool sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) override; + void fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) override; + + public: // MQPullConsumer + void registerMessageQueueListener(const std::string& topic, MQueueListener* pListener) override; + + PullResult pull(const MQMessageQueue& mq, const std::string& subExpression, int64_t offset, int maxNums) override; + + void pull(const MQMessageQueue& mq, + const std::string& subExpression, + int64_t offset, + int maxNums, + PullCallback* pullCallback) override; + + PullResult pullBlockIfNotFound(const MQMessageQueue& mq, + const std::string& subExpression, + int64_t offset, + int maxNums) override; + + void pullBlockIfNotFound(const MQMessageQueue& mq, + const std::string& subExpression, + int64_t offset, + int maxNums, + PullCallback* pullCallback) override; + + void updateConsumeOffset(const MQMessageQueue& mq, int64_t offset) override; + + int64_t fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore) override; + + void fetchMessageQueuesInBalance(const std::string& topic, std::vector& mqs) override; + + public: + void setRPCHook(std::shared_ptr rpcHook); + + protected: + std::shared_ptr m_pullConsumerDelegate; +}; + +} // namespace rocketmq + +#endif // __DEFAULT_MQ_PULL_CONSUMER_H__ diff --git a/include/DefaultMQPushConsumer.h b/include/DefaultMQPushConsumer.h old mode 100644 new mode 100755 index 7f69258c8..1caf98f1b --- a/include/DefaultMQPushConsumer.h +++ b/include/DefaultMQPushConsumer.h @@ -1,165 +1,125 @@ -/* - * 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 __DEFAULTMQPUSHCONSUMER_H__ -#define __DEFAULTMQPUSHCONSUMER_H__ - -#include -#include -#include -#include -#include -#include -#include -#include "AsyncCallback.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; -//& mqs); - virtual void doRebalance(); - virtual void persistConsumerOffset(); - virtual void persistConsumerOffsetByResetOffset(); - virtual void updateTopicSubscribeInfo(const std::string& topic, std::vector& info); - virtual ConsumeType getConsumeType(); - virtual ConsumeFromWhere getConsumeFromWhere(); - void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere); - virtual void getSubscriptions(std::vector&); - 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(); - //); - virtual bool producePullMsgTaskLater(boost::weak_ptr, int millis); - static void static_triggerNextPullRequest(void* context, - boost::asio::deadline_timer* t, - boost::weak_ptr); - void triggerNextPullRequest(boost::asio::deadline_timer* t, boost::weak_ptr); - void runPullMsgQueue(TaskQueue* pTaskQueue); - void pullMessage(boost::weak_ptr pullrequest); - void pullMessageAsync(boost::weak_ptr pullrequest); - void setAsyncPull(bool asyncFlag); - AsyncPullCallback* getAsyncPullCallBack(boost::weak_ptr, 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; - - private: - void checkConfig(); - void copySubscription(); - void updateTopicSubscribeInfoWhenSubscriptionChanged(); - bool dealWithNameSpace(); - - private: - uint64_t m_startTime; - ConsumeFromWhere m_consumeFromWhere; - std::map 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 m_async_service_thread; - - typedef std::map PullMAP; - PullMAP m_PullCallback; - bool m_asyncPull; - int m_asyncPullTimeout; - int m_pullMsgThreadPoolNum; - - private: - TaskQueue* m_pullmsgQueue; - std::unique_ptr m_pullmsgThread; -}; -// 0) { + m_consumeThreadNum = threadNum; + } + } + + /** + * the pull number of message size by each pullMsg for orderly consume, default value is 1 + */ + int getConsumeMessageBatchMaxSize() const { return m_consumeMessageBatchMaxSize; } + void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) { + if (consumeMessageBatchMaxSize >= 1) { + m_consumeMessageBatchMaxSize = consumeMessageBatchMaxSize; + } + } + + /** + * max cache msg size per Queue in memory if consumer could not consume msgs immediately, + * default maxCacheMsgSize per Queue is 1000, set range is:1~65535 + */ + int getMaxCacheMsgSizePerQueue() const { return m_maxMsgCacheSize; } + void setMaxCacheMsgSizePerQueue(int maxCacheSize) { + if (maxCacheSize > 0 && maxCacheSize < 65535) { + m_maxMsgCacheSize = maxCacheSize; + } + } + + int getAsyncPullTimeout() const { return m_asyncPullTimeout; } + void setAsyncPullTimeout(int asyncPullTimeout) { m_asyncPullTimeout = asyncPullTimeout; } + + int getMaxReconsumeTimes() { return m_maxReconsumeTimes; } + void setMaxReconsumeTimes(int maxReconsumeTimes) { m_maxReconsumeTimes = maxReconsumeTimes; } + + AllocateMQStrategy* getAllocateMQStrategy() { return m_allocateMQStrategy.get(); } + void setAllocateMQStrategy(AllocateMQStrategy* strategy) { m_allocateMQStrategy.reset(strategy); } + + protected: + ConsumeFromWhere m_consumeFromWhere; + std::string m_consumeTimestamp; + + int m_consumeThreadNum; + int m_consumeMessageBatchMaxSize; + int m_maxMsgCacheSize; + + int m_asyncPullTimeout; // 30s + int m_maxReconsumeTimes; + + std::unique_ptr m_allocateMQStrategy; +}; + +class ROCKETMQCLIENT_API DefaultMQPushConsumer : public MQPushConsumer, public DefaultMQPushConsumerConfig { + public: + DefaultMQPushConsumer(const std::string& groupname); + DefaultMQPushConsumer(const std::string& groupname, RPCHookPtr rpcHook); + virtual ~DefaultMQPushConsumer(); + + public: // MQConsumer + void start() override; + void shutdown() override; + + bool sendMessageBack(MQMessageExt& msg, int delayLevel) override; + bool sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) override; + void fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) override; + + public: // MQPushConsumer + void registerMessageListener(MQMessageListener* messageListener) override; + void registerMessageListener(MessageListenerConcurrently* messageListener) override; + void registerMessageListener(MessageListenerOrderly* messageListener) override; + + void subscribe(const std::string& topic, const std::string& subExpression) override; + + void suspend() override; + void resume() override; + + public: + void setRPCHook(std::shared_ptr rpcHook); + + protected: + std::shared_ptr m_pushConsumerDelegate; +}; + +} // namespace rocketmq + +#endif // __DEFAULT_MQ_PUSH_CONSUMER_H__ diff --git a/include/MQAdmin.h b/include/MQAdmin.h new file mode 100644 index 000000000..50179ce30 --- /dev/null +++ b/include/MQAdmin.h @@ -0,0 +1,103 @@ +/* + * 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_ADMIN_H__ +#define __MQ_ADMIN_H__ + +#include "MQMessageExt.h" +#include "MQMessageQueue.h" +#include "QueryResult.h" + +namespace rocketmq { + +/** + * MQ Admin API + */ +class ROCKETMQCLIENT_API MQAdmin { + public: + virtual ~MQAdmin() = default; + + /** + * Creates an topic + * + * @param key accesskey + * @param newTopic topic name + * @param queueNum topic's queue number + */ + virtual void createTopic(const std::string& key, const std::string& newTopic, int queueNum) = 0; + + /** + * Gets the message queue offset according to some time in milliseconds
+ * be cautious to call because of more IO overhead + * + * @param mq Instance of MessageQueue + * @param timestamp from when in milliseconds. + * @return offset + */ + virtual int64_t searchOffset(const MQMessageQueue& mq, uint64_t timestamp) = 0; + + /** + * Gets the max offset + * + * @param mq Instance of MessageQueue + * @return the max offset + */ + virtual int64_t maxOffset(const MQMessageQueue& mq) = 0; + + /** + * Gets the minimum offset + * + * @param mq Instance of MessageQueue + * @return the minimum offset + */ + virtual int64_t minOffset(const MQMessageQueue& mq) = 0; + + /** + * Gets the earliest stored message time + * + * @param mq Instance of MessageQueue + * @return the time in microseconds + */ + virtual int64_t earliestMsgStoreTime(const MQMessageQueue& mq) = 0; + + /** + * Query message according to message id + * + * @param offsetMsgId message id + * @return message + */ + virtual MQMessageExtPtr viewMessage(const std::string& offsetMsgId) = 0; + + /** + * Query messages + * + * @param topic message topic + * @param key message key index word + * @param maxNum max message number + * @param begin from when + * @param end to when + * @return Instance of QueryResult + */ + virtual QueryResult queryMessage(const std::string& topic, + const std::string& key, + int maxNum, + int64_t begin, + int64_t end) = 0; +}; + +} // namespace rocketmq + +#endif // __MQ_ADMIN_H__ diff --git a/include/MQClient.h b/include/MQClient.h deleted file mode 100644 index 0e23339de..000000000 --- a/include/MQClient.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * 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 __MQADMIN_H__ -#define __MQADMIN_H__ -#include -#include -#include -#include -#include -#include -#include "MQMessageExt.h" -#include "MQMessageQueue.h" -#include "QueryResult.h" -#include "RocketMQClient.h" -#include "SessionCredentials.h" - -namespace rocketmq { -class MQClientFactory; -// 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); - const 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 - const 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 - const uint64_t getTcpTransportTryLockTimeout() const; - - void setUnitName(std::string unitName); - const std::string& getUnitName(); - - void setSessionCredentials(const std::string& input_accessKey, - const std::string& input_secretKey, - const std::string& input_onsChannel); - const SessionCredentials& getSessionCredentials() const; - - protected: - virtual void start(); - virtual void shutdown(); - MQClientFactory* getFactory() const; - virtual bool isServiceStateOk(); - - protected: - std::string m_namesrvAddr; - std::string m_namesrvDomain; - std::string m_instanceName; - std::string m_nameSpace; - std::string m_GroupName; - 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; -}; -// + +#include "RocketMQClient.h" + +namespace rocketmq { + +/** + * MQ Client Config + */ +class ROCKETMQCLIENT_API MQClientConfig { + public: + MQClientConfig(); + virtual ~MQClientConfig() = default; + + // clientId=processId-ipAddr@instanceName + std::string buildMQClientId() const; + + // groupName + const std::string& getGroupName() const; + void setGroupName(const std::string& groupname); + + const std::string& getNamesrvAddr() const; + void setNamesrvAddr(const std::string& namesrvAddr); + + const std::string& getInstanceName() const; + void setInstanceName(const std::string& instanceName); + + void changeInstanceNameToPID(); + + /** + * 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 + **/ + int getTcpTransportWorkerThreadNum() const; + void setTcpTransportWorkerThreadNum(int num); + + /** + * 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; + **/ + uint64_t getTcpTransportConnectTimeout() const; + void setTcpTransportConnectTimeout(uint64_t timeout); // ms + + /** + * 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 + **/ + uint64_t getTcpTransportTryLockTimeout() const; + void setTcpTransportTryLockTimeout(uint64_t timeout); // ms + + const std::string& getUnitName() const; + void setUnitName(std::string unitName); + + protected: + std::string m_namesrvAddr; + std::string m_instanceName; + std::string m_groupName; + std::string m_unitName; + + int m_tcpWorkerThreadNum; + uint64_t m_tcpConnectTimeout; // ms + uint64_t m_tcpTransportTryLockTimeout; // s +}; + +} // namespace rocketmq + +#endif // __MQ_CLIENT_CONFIG_H__ diff --git a/include/MQClientException.h b/include/MQClientException.h index ad642cb7f..56deb7a4a 100644 --- a/include/MQClientException.h +++ b/include/MQClientException.h @@ -14,47 +14,42 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQCLIENTEXCEPTION_H__ -#define __MQCLIENTEXCEPTION_H__ +#ifndef __MQ_CLIENT_EXCEPTION_H__ +#define __MQ_CLIENT_EXCEPTION_H__ -#include #include #include #include #include -#include "CCommon.h" + #include "RocketMQClient.h" namespace rocketmq { -// line:" << line; - m_msg = ss.str(); - } catch (...) { - } - } + MQException(const std::string& msg, int error, const char* file, int line) noexcept + : m_error(error), m_line(line), m_msg(msg), m_file(file), m_type("MQException") {} - MQException(const std::string& msg, int error, const char* file, const char* type, int line) throw() - : m_error(error), m_line(line), m_file(file), m_type(type) { - try { + MQException(const std::string& msg, int error, const char* file, const char* type, int line) noexcept + : m_error(error), m_line(line), m_msg(msg), m_file(file), m_type(type) {} + + virtual ~MQException() noexcept = default; + + const char* what() const noexcept override { + if (m_what_.empty()) { std::stringstream ss; - ss << "msg: " << msg << ",error:" << error << ",in file <" << file << "> line:" << line; - m_msg = ss.str(); - } catch (...) { + ss << "[" << m_type << "] msg: " << m_msg << ", error: " << m_error << ", in <" << m_file << ":" << m_line << ">"; + m_what_ = ss.str(); } + return m_what_.c_str(); } - virtual ~MQException() throw() {} - const char* what() const throw() { return m_msg.c_str(); } - int GetError() const throw() { return m_error; } - virtual const char* GetType() const throw() { return m_type.c_str(); } + int GetError() const noexcept { return m_error; } int GetLine() { return m_line; } + const char* GetMsg() { return m_msg.c_str(); } const char* GetFile() { return m_file.c_str(); } + const char* GetType() const noexcept { return m_type.c_str(); } protected: int m_error; @@ -62,30 +57,42 @@ class ROCKETMQCLIENT_API MQException : public std::exception { std::string m_msg; std::string m_file; std::string m_type; + + mutable std::string m_what_; }; inline std::ostream& operator<<(std::ostream& os, const MQException& e) { - os << "Type: " << e.GetType() << " , " << e.what(); + os << e.what(); return os; } -#define DEFINE_MQCLIENTEXCEPTION(name) \ - class ROCKETMQCLIENT_API name : public MQException { \ - public: \ - name(const std::string& msg, int error, const char* file, int line) throw() \ - : MQException(msg, error, file, #name, line) {} \ - virtual const char* GetType() const throw() { return m_type.c_str(); } \ +#define DEFINE_MQCLIENTEXCEPTION2(name, super) \ + class ROCKETMQCLIENT_API name : public super { \ + public: \ + name(const std::string& msg, int error, const char* file, int line) noexcept \ + : super(msg, error, file, #name, line) {} \ + \ + protected: \ + name(const std::string& msg, int error, const char* file, const char* type, int line) noexcept \ + : super(msg, error, file, type, line) {} \ }; +#define DEFINE_MQCLIENTEXCEPTION(name) DEFINE_MQCLIENTEXCEPTION2(name, MQException) + DEFINE_MQCLIENTEXCEPTION(MQClientException) DEFINE_MQCLIENTEXCEPTION(MQBrokerException) DEFINE_MQCLIENTEXCEPTION(InterruptedException) DEFINE_MQCLIENTEXCEPTION(RemotingException) +DEFINE_MQCLIENTEXCEPTION2(RemotingCommandException, RemotingException) +DEFINE_MQCLIENTEXCEPTION2(RemotingConnectException, RemotingException) +DEFINE_MQCLIENTEXCEPTION2(RemotingSendRequestException, RemotingException) +DEFINE_MQCLIENTEXCEPTION2(RemotingTimeoutException, RemotingException) +DEFINE_MQCLIENTEXCEPTION2(RemotingTooMuchRequestException, RemotingException) DEFINE_MQCLIENTEXCEPTION(UnknownHostException) #define THROW_MQEXCEPTION(e, msg, err) throw e(msg, err, __FILE__, __LINE__) #define NEW_MQEXCEPTION(e, msg, err) e(msg, err, __FILE__, __LINE__) -// -#include "AsyncCallback.h" -#include "ConsumeType.h" -#include "MQClient.h" -#include "RocketMQClient.h" - -namespace rocketmq { -class SubscriptionData; -class PullRequest; -class Rebalance; -class ConsumerRunningInfo; -//& mqs) = 0; - virtual void doRebalance() = 0; - virtual void persistConsumerOffset() = 0; - virtual void persistConsumerOffsetByResetOffset() = 0; - virtual void updateTopicSubscribeInfo(const std::string& topic, std::vector& 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&) = 0; - virtual bool producePullMsgTask(boost::weak_ptr) = 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; -}; - -// +#include + +#include "MQMessageExt.h" + +namespace rocketmq { + +/** + * MQ Consumer API + */ +class ROCKETMQCLIENT_API MQConsumer { + public: + virtual ~MQConsumer() = default; + + public: // MQConsumer in Java + virtual void start() = 0; + virtual void shutdown() = 0; + + virtual bool sendMessageBack(MQMessageExt& msg, int delayLevel) = 0; + virtual bool sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) = 0; + virtual void fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) = 0; +}; + +} // namespace rocketmq + +#endif // __MQ_CONSUMER_H__ diff --git a/include/MQMessage.h b/include/MQMessage.h index 70fab3613..a2a819e4e 100644 --- a/include/MQMessage.h +++ b/include/MQMessage.h @@ -14,17 +14,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MESSAGE_H__ -#define __MESSAGE_H__ +#ifndef __MQ_MESSAGE_H__ +#define __MQ_MESSAGE_H__ #include +#include #include #include #include -#include "RocketMQClient.h" + +#include "MQMessageConst.h" namespace rocketmq { -// MQMessagePtr2; + class ROCKETMQCLIENT_API MQMessage { public: MQMessage(); @@ -38,12 +44,14 @@ class ROCKETMQCLIENT_API MQMessage { const std::string& body, bool waitStoreMsgOK); - virtual ~MQMessage(); MQMessage(const MQMessage& other); MQMessage& operator=(const MQMessage& other); - void setProperty(const std::string& name, const std::string& value); + virtual ~MQMessage(); + const std::string& getProperty(const std::string& name) const; + void putProperty(const std::string& name, const std::string& value); + void clearProperty(const std::string& name); const std::string& getTopic() const; void setTopic(const std::string& topic); @@ -65,79 +73,35 @@ class ROCKETMQCLIENT_API MQMessage { int getFlag() const; void setFlag(int flag); - int getSysFlag() const; - void setSysFlag(int sysFlag); - const std::string& getBody() const; - void setBody(const char* body, int len); void setBody(const std::string& body); + void setBody(std::string&& body); + + const std::string& getTransactionId() const; + void setTransactionId(const std::string& transactionId); - void setTransactionId(const std::string& id) { m_transactionId = id; } - std::string getTransactionId() const { return m_transactionId; } + const std::map& getProperties() const; + void setProperties(const std::map& properties); + void setProperties(std::map&& properties); - std::map getProperties() const; - void setProperties(std::map& properties); + virtual bool isBatch() { return false; } - const std::string toString() const { + virtual std::string toString() const { std::stringstream ss; - std::string tags = getTags(); - ss << "Message [topic=" << m_topic << ", flag=" << m_flag << ", tag=" << tags << "]"; + ss << "Message [topic=" << m_topic << ", flag=" << m_flag << ", tag=" << getTags() << ", transactionId='" + << m_transactionId + "']"; return ss.str(); } protected: - friend class MQDecoder; - void setPropertyInternal(const std::string& name, const std::string& value); - void setPropertiesInternal(std::map& properties); - - void Init(const std::string& topic, - const std::string& tags, - const std::string& keys, - const int flag, - const std::string& body, - bool waitStoreMsgOK); - - public: - static const std::string PROPERTY_KEYS; - static const std::string PROPERTY_TAGS; - static const std::string PROPERTY_WAIT_STORE_MSG_OK; - static const std::string PROPERTY_DELAY_TIME_LEVEL; - static const std::string PROPERTY_RETRY_TOPIC; - static const std::string PROPERTY_REAL_TOPIC; - static const std::string PROPERTY_REAL_QUEUE_ID; - static const std::string PROPERTY_TRANSACTION_PREPARED; - static const std::string PROPERTY_PRODUCER_GROUP; - static const std::string PROPERTY_MIN_OFFSET; - static const std::string PROPERTY_MAX_OFFSET; - - static const std::string PROPERTY_BUYER_ID; - static const std::string PROPERTY_ORIGIN_MESSAGE_ID; - static const std::string PROPERTY_TRANSFER_FLAG; - static const std::string PROPERTY_CORRECTION_FLAG; - static const std::string PROPERTY_MQ2_FLAG; - static const std::string PROPERTY_RECONSUME_TIME; - static const std::string PROPERTY_MSG_REGION; - static const std::string PROPERTY_TRACE_SWITCH; - static const std::string PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX; - static const std::string PROPERTY_MAX_RECONSUME_TIMES; - static const std::string PROPERTY_CONSUME_START_TIMESTAMP; - static const std::string PROPERTY_TRANSACTION_PREPARED_QUEUE_OFFSET; - static const std::string PROPERTY_TRANSACTION_CHECK_TIMES; - static const std::string PROPERTY_CHECK_IMMUNITY_TIME_IN_SECONDS; - - static const std::string KEY_SEPARATOR; - - protected: - int m_sysFlag; - - private: std::string m_topic; int m_flag; + std::map m_properties; std::string m_body; std::string m_transactionId; - std::map m_properties; }; -// + +#include "RocketMQClient.h" + +namespace rocketmq { + +class ROCKETMQCLIENT_API MQMessageConst { + public: + static const std::string PROPERTY_KEYS; + static const std::string PROPERTY_TAGS; + static const std::string PROPERTY_WAIT_STORE_MSG_OK; + static const std::string PROPERTY_DELAY_TIME_LEVEL; + static const std::string PROPERTY_RETRY_TOPIC; + static const std::string PROPERTY_REAL_TOPIC; + static const std::string PROPERTY_REAL_QUEUE_ID; + static const std::string PROPERTY_TRANSACTION_PREPARED; + static const std::string PROPERTY_PRODUCER_GROUP; + static const std::string PROPERTY_MIN_OFFSET; + static const std::string PROPERTY_MAX_OFFSET; + + static const std::string PROPERTY_BUYER_ID; + static const std::string PROPERTY_ORIGIN_MESSAGE_ID; + static const std::string PROPERTY_TRANSFER_FLAG; + static const std::string PROPERTY_CORRECTION_FLAG; + static const std::string PROPERTY_MQ2_FLAG; + static const std::string PROPERTY_RECONSUME_TIME; + static const std::string PROPERTY_MSG_REGION; + static const std::string PROPERTY_TRACE_SWITCH; + static const std::string PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX; + static const std::string PROPERTY_MAX_RECONSUME_TIMES; + static const std::string PROPERTY_CONSUME_START_TIMESTAMP; + static const std::string PROPERTY_TRANSACTION_PREPARED_QUEUE_OFFSET; + static const std::string PROPERTY_TRANSACTION_CHECK_TIMES; + static const std::string PROPERTY_CHECK_IMMUNITY_TIME_IN_SECONDS; + static const std::string PROPERTY_INSTANCE_ID; + + // sdk internal use only + static const std::string PROPERTY_ALREADY_COMPRESSED_FLAG; + + static const std::string KEY_SEPARATOR; +}; + +} // namespace rocketmq + +#endif // __MQ_MESSAGE_CONST_H__ diff --git a/include/MQMessageExt.h b/include/MQMessageExt.h index 8970282d3..f14204501 100644 --- a/include/MQMessageExt.h +++ b/include/MQMessageExt.h @@ -14,104 +14,119 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MESSAGEEXT_H__ -#define __MESSAGEEXT_H__ +#ifndef __MQ_MESSAGE_EXT_H__ +#define __MQ_MESSAGE_EXT_H__ #ifdef WIN32 -#include +// clang-format off #include +#include +// clang-format on #else #include #endif #include "MQMessage.h" -#include "RocketMQClient.h" +#include "TopicFilterType.h" namespace rocketmq { -// MQMessageExtPtr2; + +// message extend class, which was generated on broker class ROCKETMQCLIENT_API MQMessageExt : public MQMessage { public: MQMessageExt(); MQMessageExt(int queueId, - int64 bornTimestamp, + int64_t bornTimestamp, sockaddr bornHost, - int64 storeTimestamp, + int64_t storeTimestamp, sockaddr storeHost, std::string msgId); virtual ~MQMessageExt(); - static int parseTopicFilterType(int sysFlag); + static TopicFilterType parseTopicFilterType(int32_t sysFlag); - int getQueueId() const; - void setQueueId(int queueId); + int32_t getStoreSize() const; + void setStoreSize(int32_t storeSize); - int64 getBornTimestamp() const; - void setBornTimestamp(int64 bornTimestamp); + int32_t getBodyCRC() const; + void setBodyCRC(int32_t bodyCRC); - sockaddr getBornHost() const; - std::string getBornHostString() const; - std::string getBornHostNameString() const; - void setBornHost(const sockaddr& bornHost); + int32_t getQueueId() const; + void setQueueId(int32_t queueId); - int64 getStoreTimestamp() const; - void setStoreTimestamp(int64 storeTimestamp); + int64_t getQueueOffset() const; + void setQueueOffset(int64_t queueOffset); - sockaddr getStoreHost() const; - std::string getStoreHostString() const; - void setStoreHost(const sockaddr& storeHost); + int64_t getCommitLogOffset() const; + void setCommitLogOffset(int64_t physicOffset); - const std::string& getMsgId() const; - void setMsgId(const std::string& msgId); + int32_t getSysFlag() const; + void setSysFlag(int32_t sysFlag); - const std::string& getOffsetMsgId() const; - void setOffsetMsgId(const std::string& offsetMsgId); + int64_t getBornTimestamp() const; + void setBornTimestamp(int64_t bornTimestamp); - int getBodyCRC() const; - void setBodyCRC(int bodyCRC); + const sockaddr& getBornHost() const; + std::string getBornHostString() const; + void setBornHost(const sockaddr& bornHost); - int64 getQueueOffset() const; - void setQueueOffset(int64 queueOffset); + int64_t getStoreTimestamp() const; + void setStoreTimestamp(int64_t storeTimestamp); - int64 getCommitLogOffset() const; - void setCommitLogOffset(int64 physicOffset); + const sockaddr& getStoreHost() const; + std::string getStoreHostString() const; + void setStoreHost(const sockaddr& storeHost); - int getStoreSize() const; - void setStoreSize(int storeSize); + int32_t getReconsumeTimes() const; + void setReconsumeTimes(int32_t reconsumeTimes); - int getReconsumeTimes() const; - void setReconsumeTimes(int reconsumeTimes); + int64_t getPreparedTransactionOffset() const; + void setPreparedTransactionOffset(int64_t preparedTransactionOffset); - int64 getPreparedTransactionOffset() const; - void setPreparedTransactionOffset(int64 preparedTransactionOffset); + virtual const std::string& getMsgId() const; + virtual void setMsgId(const std::string& msgId); - std::string toString() const { + std::string toString() const override { std::stringstream ss; ss << "MessageExt [queueId=" << m_queueId << ", storeSize=" << m_storeSize << ", queueOffset=" << m_queueOffset << ", sysFlag=" << m_sysFlag << ", bornTimestamp=" << m_bornTimestamp << ", bornHost=" << getBornHostString() - << ", storeTimestamp=" << m_storeTimestamp << ", storeHost=" << getStoreHostString() << ", msgId=" << m_msgId + << ", storeTimestamp=" << m_storeTimestamp << ", storeHost=" << getStoreHostString() << ", msgId=" << getMsgId() << ", commitLogOffset=" << m_commitLogOffset << ", bodyCRC=" << m_bodyCRC << ", reconsumeTimes=" << m_reconsumeTimes << ", preparedTransactionOffset=" << m_preparedTransactionOffset - << ", " << MQMessage::toString() << "]"; + << ", toString()=" << MQMessage::toString() << "]"; return ss.str(); } private: - int64 m_queueOffset; - int64 m_commitLogOffset; - int64 m_bornTimestamp; - int64 m_storeTimestamp; - int64 m_preparedTransactionOffset; - int m_queueId; - int m_storeSize; - int m_bodyCRC; - int m_reconsumeTimes; + int32_t m_storeSize; + int32_t m_bodyCRC; + int32_t m_queueId; + int64_t m_queueOffset; + int64_t m_commitLogOffset; + int32_t m_sysFlag; + int64_t m_bornTimestamp; sockaddr m_bornHost; + int64_t m_storeTimestamp; sockaddr m_storeHost; + int32_t m_reconsumeTimes; + int64_t m_preparedTransactionOffset; std::string m_msgId; - std::string m_offsetMsgId; }; -// -#include "MQMessageExt.h" -#include "MQMessageQueue.h" - -namespace rocketmq { -//& msgs) = 0; - virtual MessageListenerType getMessageListenerType() { return messageListenerDefaultly; } -}; - -class ROCKETMQCLIENT_API MessageListenerOrderly : public MQMessageListener { - public: - virtual ~MessageListenerOrderly() {} - virtual ConsumeStatus consumeMessage(const std::vector& msgs) = 0; - virtual MessageListenerType getMessageListenerType() { return messageListenerOrderly; } -}; - -class ROCKETMQCLIENT_API MessageListenerConcurrently : public MQMessageListener { - public: - virtual ~MessageListenerConcurrently() {} - virtual ConsumeStatus consumeMessage(const std::vector& msgs) = 0; - virtual MessageListenerType getMessageListenerType() { return messageListenerConcurrently; } -}; - -// + +#include "MQMessageExt.h" + +namespace rocketmq { + +enum ConsumeStatus { + // consume success, msg will be cleard from memory + CONSUME_SUCCESS, + // consume fail, but will be re-consume by call messageLisenter again + RECONSUME_LATER +}; + +/*enum ConsumeOrderlyStatus +{*/ +/** + * Success consumption + */ +// SUCCESS, +/** + * Rollback consumption(only for binlog consumption) + */ +// ROLLBACK, +/** + * Commit offset(only for binlog consumption) + */ +// COMMIT, +/** + * Suspend current queue a moment + */ +// SUSPEND_CURRENT_QUEUE_A_MOMENT +/*};*/ + +enum MessageListenerType { messageListenerDefaultly = 0, messageListenerOrderly = 1, messageListenerConcurrently = 2 }; + +class ROCKETMQCLIENT_API MQMessageListener { + public: + virtual ~MQMessageListener() = default; + virtual MessageListenerType getMessageListenerType() { return messageListenerDefaultly; } + + virtual ConsumeStatus consumeMessage(const std::vector& msgs) { + std::vector msgs2; + msgs2.reserve(msgs.size()); + for (auto& msg : msgs) { + msgs2.push_back(msg.get()); + } + return consumeMessage(msgs2); + } + + // SDK will be responsible for the lifecycle of messages. + virtual ConsumeStatus consumeMessage(const std::vector& msgs) = 0; +}; + +class ROCKETMQCLIENT_API MessageListenerConcurrently : virtual public MQMessageListener { + public: + MessageListenerType getMessageListenerType() override final { return messageListenerConcurrently; } +}; + +class ROCKETMQCLIENT_API MessageListenerOrderly : virtual public MQMessageListener { + public: + MessageListenerType getMessageListenerType() override final { return messageListenerOrderly; } +}; + +} // namespace rocketmq + +#endif // __MESSAGE_LISTENER_H__ diff --git a/include/MQMessageQueue.h b/include/MQMessageQueue.h index aa8003547..a37cdf579 100644 --- a/include/MQMessageQueue.h +++ b/include/MQMessageQueue.h @@ -1,63 +1,64 @@ -/* - * 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 __MQMESSAGEQUEUE_H__ -#define __MQMESSAGEQUEUE_H__ - -#include -#include -#include -#include "RocketMQClient.h" - -namespace rocketmq { -// +#include + +#include "RocketMQClient.h" + +namespace rocketmq { + +/** + * MQ(T,B,ID) + */ +class ROCKETMQCLIENT_API MQMessageQueue { + public: + MQMessageQueue(); + MQMessageQueue(const std::string& topic, const std::string& brokerName, int queueId); + MQMessageQueue(const MQMessageQueue& other); + MQMessageQueue& operator=(const MQMessageQueue& other); + + const std::string& getTopic() const; + void setTopic(const std::string& topic); + + const std::string& getBrokerName() const; + void setBrokerName(const std::string& brokerName); + + int getQueueId() const; + void setQueueId(int queueId); + + bool operator==(const MQMessageQueue& mq) const; + bool operator<(const MQMessageQueue& mq) const; + int compareTo(const MQMessageQueue& mq) const; + + std::string toString() const { + std::stringstream ss; + ss << "MessageQueue [topic=" << m_topic << ", brokerName=" << m_brokerName << ", queueId=" << m_queueId << "]"; + return ss.str(); + } + + private: + std::string m_topic; + std::string m_brokerName; + int m_queueId; +}; + +} // namespace rocketmq + +#endif // __MQ_MESSAGE_QUEUE_H__ diff --git a/include/MQProducer.h b/include/MQProducer.h index 03e6b197f..36878d98f 100644 --- a/include/MQProducer.h +++ b/include/MQProducer.h @@ -1,61 +1,81 @@ -/* - * 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 "MQClient.h" -#include "MQMessageQueue.h" -#include "MQSelector.h" -#include "RocketMQClient.h" -#include "SendResult.h" - -namespace rocketmq { -//& msgs) = 0; - virtual SendResult send(std::vector& 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; -}; -//& msgs) = 0; + virtual SendResult send(std::vector& msgs, long timeout) = 0; + virtual SendResult send(std::vector& msgs, const MQMessageQueue& mq) = 0; + virtual SendResult send(std::vector& msgs, const MQMessageQueue& mq, long timeout) = 0; +}; + +} // namespace rocketmq + +#endif // __MQ_PRODUCER_H__ diff --git a/include/MQPullConsumer.h b/include/MQPullConsumer.h new file mode 100644 index 000000000..557143127 --- /dev/null +++ b/include/MQPullConsumer.h @@ -0,0 +1,103 @@ +/* + * 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_PULL_CONSUMER_H__ +#define __MQ_PULL_CONSUMER_H__ + +#include "MQConsumer.h" +#include "MQueueListener.h" +#include "PullCallback.h" + +namespace rocketmq { + +class ROCKETMQCLIENT_API MQPullConsumer : public MQConsumer { + public: + virtual void registerMessageQueueListener(const std::string& topic, MQueueListener* pListener) = 0; + + /** + * pull msg 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 + * accroding to PullResult + */ + virtual PullResult pull(const MQMessageQueue& mq, const std::string& subExpression, int64_t offset, int maxNums) = 0; + + virtual void pull(const MQMessageQueue& mq, + const std::string& subExpression, + int64_t offset, + int maxNums, + PullCallback* pullCallback) = 0; + + /** + * 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 + */ + virtual PullResult pullBlockIfNotFound(const MQMessageQueue& mq, + const std::string& subExpression, + int64_t offset, + int maxNums) = 0; + + virtual void pullBlockIfNotFound(const MQMessageQueue& mq, + const std::string& subExpression, + int64_t offset, + int maxNums, + PullCallback* pullCallback) = 0; + + virtual void updateConsumeOffset(const MQMessageQueue& mq, int64_t offset) = 0; + + /** + * Fetch the offset + * + * @param mq + * @param fromStore + * @return + */ + virtual int64_t fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore) = 0; + + /** + * Fetch the message queues according to the topic + * + * @param topic Message Topic + * @return + */ + virtual void fetchMessageQueuesInBalance(const std::string& topic, std::vector& mqs) = 0; +}; + +} // namespace rocketmq + +#endif // __MQ_PULL_CONSUMER_H__ diff --git a/include/MQPushConsumer.h b/include/MQPushConsumer.h new file mode 100644 index 000000000..76d5f9386 --- /dev/null +++ b/include/MQPushConsumer.h @@ -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 __MQ_PUSH_CONSUMER_H__ +#define __MQ_PUSH_CONSUMER_H__ + +#include "MQConsumer.h" +#include "MQMessageListener.h" + +namespace rocketmq { + +class ROCKETMQCLIENT_API MQPushConsumer : public MQConsumer { + public: // MQPushConsumer in Java + // [[deprecated]] + virtual void registerMessageListener(MQMessageListener* messageListener) = 0; + virtual void registerMessageListener(MessageListenerConcurrently* messageListener) = 0; + virtual void registerMessageListener(MessageListenerOrderly* messageListener) = 0; + + virtual void subscribe(const std::string& topic, const std::string& subExpression) = 0; + // virtual void subscribe(const std::string& topic, MessageSelector* selector) = 0; + + virtual void suspend() = 0; + virtual void resume() = 0; +}; + +} // namespace rocketmq + +#endif // __MQ_PUSH_CONSUMER_H__ diff --git a/include/MQSelector.h b/include/MQSelector.h index bba578154..f5de65452 100644 --- a/include/MQSelector.h +++ b/include/MQSelector.h @@ -1,32 +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. - */ -#ifndef _MQSELECTOR_H_ -#define _MQSELECTOR_H_ -#include "MQMessage.h" -#include "MQMessageQueue.h" -#include "RocketMQClient.h" - -namespace rocketmq { -//& mqs, const MQMessage& msg, void* arg) = 0; -}; -//& mqs, const MQMessage& msg, void* arg) = 0; +}; + +} // namespace rocketmq + +#endif // __MQ_SELECTOR_H__ diff --git a/include/MQueueListener.h b/include/MQueueListener.h index eef959041..11842aa1f 100644 --- a/include/MQueueListener.h +++ b/include/MQueueListener.h @@ -1,34 +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 __MESSAGEQUEUELISTENER_H__ -#define __MESSAGEQUEUELISTENER_H__ - -#include -#include "RocketMQClient.h" - -namespace rocketmq { -//& mqAll, - std::vector& mqDivided) = 0; -}; -// +#include + +#include "MQMessageQueue.h" + +namespace rocketmq { + +class ROCKETMQCLIENT_API MQueueListener { + public: + virtual ~MQueueListener() = default; + + virtual void messageQueueChanged(const std::string& topic, + std::vector& mqAll, + std::vector& mqDivided) = 0; +}; + +} // namespace rocketmq + +#endif // __MQ_LISTENER_H__ diff --git a/include/PullCallback.h b/include/PullCallback.h new file mode 100755 index 000000000..16fe81e05 --- /dev/null +++ b/include/PullCallback.h @@ -0,0 +1,44 @@ +/* + * 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 __PULL_CALLBACK_H__ +#define __PULL_CALLBACK_H__ + +#include "MQClientException.h" +#include "PullResult.h" + +namespace rocketmq { + +enum PullCallbackType { PULL_CALLBACK_TYPE_SIMPLE = 0, PULL_CALLBACK_TYPE_AUTO_DELETE = 1 }; + +class ROCKETMQCLIENT_API PullCallback { + public: + virtual ~PullCallback() = default; + + virtual void onSuccess(PullResult& pullResult) = 0; + virtual void onException(MQException& e) noexcept = 0; + + virtual PullCallbackType getPullCallbackType() const { return PULL_CALLBACK_TYPE_SIMPLE; } +}; + +class ROCKETMQCLIENT_API AutoDeletePullCallback : public PullCallback { + public: + PullCallbackType getPullCallbackType() const override final { return PULL_CALLBACK_TYPE_AUTO_DELETE; } +}; + +} // namespace rocketmq + +#endif // __PULL_CALLBACK_H__ diff --git a/include/PullResult.h b/include/PullResult.h index 61eedf0a8..d43fda23e 100644 --- a/include/PullResult.h +++ b/include/PullResult.h @@ -1,68 +1,74 @@ -/* - * 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 __PULLRESULT_H__ -#define __PULLRESULT_H__ - -#include -#include "MQMessageExt.h" -#include "RocketMQClient.h" - -namespace rocketmq { -//& src); - - virtual ~PullResult(); - - std::string toString() { - std::stringstream ss; - ss << "PullResult [ pullStatus=" << EnumStrings[pullStatus] << ", nextBeginOffset=" << nextBeginOffset - << ", minOffset=" << minOffset << ", maxOffset=" << maxOffset << ", msgFoundList=" << msgFoundList.size() - << " ]"; - return ss.str(); - } - - public: - PullStatus pullStatus; - int64 nextBeginOffset; - int64 minOffset; - int64 maxOffset; - std::vector msgFoundList; -}; -// +#include + +#include "MQMessageExt.h" + +namespace rocketmq { + +enum PullStatus { + FOUND, + NO_NEW_MSG, + NO_MATCHED_MSG, + OFFSET_ILLEGAL, + BROKER_TIMEOUT // indicate pull request timeout or received NULL response +}; + +static const char* EnumStrings[] = {"FOUND", "NO_NEW_MSG", "NO_MATCHED_MSG", "OFFSET_ILLEGAL", "BROKER_TIMEOUT"}; + +class ROCKETMQCLIENT_API PullResult { + public: + PullResult(); + PullResult(PullStatus status); + PullResult(PullStatus pullStatus, int64_t nextBeginOffset, int64_t minOffset, int64_t maxOffset); + + PullResult(PullStatus pullStatus, + int64_t nextBeginOffset, + int64_t minOffset, + int64_t maxOffset, + const std::vector& src); + PullResult(PullStatus pullStatus, + int64_t nextBeginOffset, + int64_t minOffset, + int64_t maxOffset, + std::vector&& src); + + virtual ~PullResult(); + + std::string toString() const { + std::stringstream ss; + ss << "PullResult [ pullStatus=" << EnumStrings[pullStatus] << ", nextBeginOffset=" << nextBeginOffset + << ", minOffset=" << minOffset << ", maxOffset=" << maxOffset << ", msgFoundList=" << msgFoundList.size() + << " ]"; + return ss.str(); + } + + public: + PullStatus pullStatus; + int64_t nextBeginOffset; + int64_t minOffset; + int64_t maxOffset; + std::vector msgFoundList; +}; + +} // namespace rocketmq + +#endif // __PULL_RESULT_H__ diff --git a/include/QueryResult.h b/include/QueryResult.h index b7c369799..958a499b1 100644 --- a/include/QueryResult.h +++ b/include/QueryResult.h @@ -1,42 +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 { -//& messageList) { - m_indexLastUpdateTimestamp = indexLastUpdateTimestamp; - m_messageList = messageList; - } - - uint64 getIndexLastUpdateTimestamp() { return m_indexLastUpdateTimestamp; } - - std::vector& getMessageList() { return m_messageList; } - - private: - uint64 m_indexLastUpdateTimestamp; - std::vector m_messageList; -}; -//& messageList) { + m_indexLastUpdateTimestamp = indexLastUpdateTimestamp; + m_messageList = messageList; + } + + uint64_t getIndexLastUpdateTimestamp() { return m_indexLastUpdateTimestamp; } + + std::vector& getMessageList() { return m_messageList; } + + private: + uint64_t m_indexLastUpdateTimestamp; + std::vector m_messageList; +}; + +} // namespace rocketmq + +#endif // __QUERY_RESULT_H__ diff --git a/include/RPCHook.h b/include/RPCHook.h new file mode 100644 index 000000000..5ee88b6e3 --- /dev/null +++ b/include/RPCHook.h @@ -0,0 +1,44 @@ +/* + * 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 __RPC_HOOK_H__ +#define __RPC_HOOK_H__ + +#include +#include + +#include "RemotingCommand.h" + +namespace rocketmq { + +class RPCHook; +typedef std::shared_ptr RPCHookPtr; + +class ROCKETMQCLIENT_API RPCHook { + public: + RPCHook() = default; + virtual ~RPCHook() = default; + + virtual void doBeforeRequest(const std::string& remoteAddr, RemotingCommand& request, bool toSent) = 0; + virtual void doAfterResponse(const std::string& remoteAddr, + RemotingCommand& request, + RemotingCommand* response, + bool toSent) = 0; +}; + +} // namespace rocketmq + +#endif // __RPC_HOOK_H__ diff --git a/include/RemotingCommand.h b/include/RemotingCommand.h new file mode 100644 index 000000000..e204445a8 --- /dev/null +++ b/include/RemotingCommand.h @@ -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. + */ +#ifndef __REMOTING_COMMAND_H__ +#define __REMOTING_COMMAND_H__ + +#include +#include +#include + +#include "CommandCustomHeader.h" +#include "MQClientException.h" + +namespace rocketmq { + +class MemoryBlock; +typedef MemoryBlock* MemoryBlockPtr; +typedef std::shared_ptr MemoryBlockPtr2; + +class ROCKETMQCLIENT_API RemotingCommand { + public: + static int32_t createNewRequestId(); + + public: + RemotingCommand() : m_code(0) {} + RemotingCommand(int32_t code, CommandCustomHeader* customHeader = nullptr); + RemotingCommand(int32_t code, + const std::string& language, + int32_t version, + int32_t opaque, + int32_t flag, + const std::string& remark, + CommandCustomHeader* customHeader); + RemotingCommand(RemotingCommand&& command); + + virtual ~RemotingCommand(); + + int32_t getCode() const; + void setCode(int32_t code); + + int32_t getVersion() const; + + int32_t getOpaque() const; + void setOpaque(int32_t opaque); + + int32_t getFlag() const; + + const std::string& getRemark() const; + void setRemark(const std::string& mark); + + bool isResponseType(); + void markResponseType(); + + bool isOnewayRPC(); + void markOnewayRPC(); + + void addExtField(const std::string& key, const std::string& value); + + CommandCustomHeader* readCustomHeader() const; + + MemoryBlockPtr2 getBody(); + void setBody(MemoryBlock* body); + void setBody(MemoryBlockPtr2 body); + void setBody(const std::string& body); + + public: + MemoryBlockPtr encode(); + + template + H* decodeCommandCustomHeader(bool useCache); + + template + H* decodeCommandCustomHeader(); + + static RemotingCommand* Decode(MemoryBlockPtr2& package); + + std::string toString() const; + + private: + int32_t m_code; + std::string m_language; + int32_t m_version; + int32_t m_opaque; + int32_t m_flag; + std::string m_remark; + std::map m_extFields; + std::unique_ptr m_customHeader; // transient + + MemoryBlockPtr2 m_body; // transient +}; + +template +H* RemotingCommand::decodeCommandCustomHeader(bool useCache) { + auto* cache = m_customHeader.get(); + if (cache != nullptr && useCache && std::type_index(typeid(*cache)) == std::type_index(typeid(H))) { + return static_cast(m_customHeader.get()); + } + return decodeCommandCustomHeader(); +} + +template +H* RemotingCommand::decodeCommandCustomHeader() { + try { + H* header = H::Decode(m_extFields); + m_customHeader.reset(header); + return header; + } catch (std::exception& e) { + THROW_MQEXCEPTION(RemotingCommandException, e.what(), -1); + } +} + +} // namespace rocketmq + +#endif // __REMOTING_COMMAND_H__ diff --git a/include/RocketMQClient.h b/include/RocketMQClient.h index 26ae37921..09be80128 100644 --- a/include/RocketMQClient.h +++ b/include/RocketMQClient.h @@ -1,55 +1,76 @@ -/* - * 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 __ROCKETMQCLIENT_H__ -#define __ROCKETMQCLIENT_H__ - -#ifdef WIN32 -#ifdef ROCKETMQCLIENT_EXPORTS -#ifdef _WINDLL -#define ROCKETMQCLIENT_API __declspec(dllexport) -#else -#define ROCKETMQCLIENT_API -#endif -#else -#ifdef ROCKETMQCLIENT_IMPORT -#define ROCKETMQCLIENT_API __declspec(dllimport) -#else -#define ROCKETMQCLIENT_API -#endif -#endif -#else -#define ROCKETMQCLIENT_API -#endif - -/** A platform-independent 8-bit signed integer type. */ -typedef signed char int8; -/** A platform-independent 8-bit unsigned integer type. */ -typedef unsigned char uint8; -/** A platform-independent 16-bit signed integer type. */ -typedef signed short int16; -/** A platform-independent 16-bit unsigned integer type. */ -typedef unsigned short uint16; -/** A platform-independent 32-bit signed integer type. */ -typedef signed int int32; -/** A platform-independent 32-bit unsigned integer type. */ -typedef unsigned int uint32; -/** A platform-independent 64-bit integer type. */ -typedef long long int64; -/** A platform-independent 64-bit unsigned integer type. */ -typedef unsigned long long uint64; - -#endif +/* + * 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_CLIENT_H__ +#define __ROCKETMQ_CLIENT_H__ + +#include + +#ifdef WIN32 +#ifdef ROCKETMQCLIENT_EXPORTS +#ifdef _WINDLL +#define ROCKETMQCLIENT_API __declspec(dllexport) +#else // _WINDLL +#define ROCKETMQCLIENT_API +#endif // _WINDLL +#else // ROCKETMQCLIENT_EXPORTS +#ifdef ROCKETMQCLIENT_IMPORT +#define ROCKETMQCLIENT_API __declspec(dllimport) +#else // ROCKETMQCLIENT_IMPORT +#define ROCKETMQCLIENT_API +#endif // ROCKETMQCLIENT_IMPORT +#endif // ROCKETMQCLIENT_EXPORTS +#else // WIN32 +#define ROCKETMQCLIENT_API +#endif // WIN32 + +/** A platform-independent 8-bit signed integer type. */ +typedef int8_t int8; + +/** A platform-independent 8-bit unsigned integer type. */ +typedef uint8_t uint8; + +/** A platform-independent 16-bit signed integer type. */ +typedef int16_t int16; + +/** A platform-independent 16-bit unsigned integer type. */ +typedef uint16_t uint16; + +/** A platform-independent 32-bit signed integer type. */ +typedef int32_t int32; + +/** A platform-independent 32-bit unsigned integer type. */ +typedef uint32_t uint32; + +/** A platform-independent 64-bit integer type. */ +typedef int64_t int64; + +/** A platform-independent 64-bit unsigned integer type. */ +typedef uint64_t uint64; + +#ifdef WIN32 +#define SIZET_FMT "%lu" +#else +#define SIZET_FMT "%zu" +#endif + +#ifdef WIN32 +#define FILE_SEPARATOR "\\" +#else +#define FILE_SEPARATOR "/" +#endif + +#endif // __ROCKETMQ_CLIENT_H__ diff --git a/include/SendCallback.h b/include/SendCallback.h new file mode 100755 index 000000000..7370250d4 --- /dev/null +++ b/include/SendCallback.h @@ -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 __SEND_CALLBACK_H__ +#define __SEND_CALLBACK_H__ + +#include "MQClientException.h" +#include "SendResult.h" + +namespace rocketmq { + +enum SendCallbackType { SEND_CALLBACK_TYPE_SIMPLE = 0, SEND_CALLBACK_TYPE_ATUO_DELETE = 1 }; + +class ROCKETMQCLIENT_API SendCallback { + public: + virtual ~SendCallback() = default; + + virtual void onSuccess(SendResult& sendResult) = 0; + virtual void onException(MQException& e) noexcept = 0; + + virtual SendCallbackType getSendCallbackType() const { return SEND_CALLBACK_TYPE_SIMPLE; } +}; + +// async SendCallback will be deleted automatically by rocketmq cpp after invoke callback interface +class ROCKETMQCLIENT_API AutoDeleteSendCallback : public SendCallback { + public: + SendCallbackType getSendCallbackType() const override final { return SEND_CALLBACK_TYPE_ATUO_DELETE; } +}; + +} // namespace rocketmq + +#endif // __SEND_CALLBACK_H__ diff --git a/include/SendMessageHook.h b/include/SendMessageHook.h index 1af0e9203..5152889b5 100644 --- a/include/SendMessageHook.h +++ b/include/SendMessageHook.h @@ -1,47 +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 __SENDMESSAGEHOOK_H__ -#define __SENDMESSAGEHOOK_H__ - -#include "MQClientException.h" -#include "MQMessage.h" -#include "RocketMQClient.h" - -namespace rocketmq { -// #include "RocketMQClient.h" namespace rocketmq { -class SessionCredentials { +class ROCKETMQCLIENT_API SessionCredentials { public: static const std::string AccessKey; static const std::string SecretKey; @@ -30,44 +31,37 @@ class SessionCredentials { static const std::string SignatureMethod; static const std::string ONSChannelKey; - SessionCredentials(std::string input_accessKey, std::string input_secretKey, const std::string& input_authChannel) - : accessKey(input_accessKey), secretKey(input_secretKey), authChannel(input_authChannel) {} - SessionCredentials() : authChannel("ALIYUN") {} - ~SessionCredentials() {} + SessionCredentials() : authChannel_("ALIYUN") {} + SessionCredentials(const std::string& accessKey, const std::string& secretKey, const std::string& authChannel) + : accessKey_(accessKey), secretKey_(secretKey), authChannel_(authChannel) {} - std::string getAccessKey() const { return accessKey; } + ~SessionCredentials() = default; - void setAccessKey(std::string input_accessKey) { accessKey = input_accessKey; } + const std::string& getAccessKey() const { return accessKey_; } + void setAccessKey(const std::string& accessKey) { accessKey_ = accessKey; } - std::string getSecretKey() const { return secretKey; } + const std::string& getSecretKey() const { return secretKey_; } + void setSecretKey(const std::string& secretKey) { secretKey_ = secretKey; } - void setSecretKey(std::string input_secretKey) { secretKey = input_secretKey; } + const std::string& getSignature() const { return signature_; } + void setSignature(const std::string& signature) { signature_ = signature; } - std::string getSignature() const { return signature; } + const std::string& getSignatureMethod() const { return signatureMethod_; } + void setSignatureMethod(const std::string& signatureMethod) { signatureMethod_ = signatureMethod; } - void setSignature(std::string input_signature) { signature = input_signature; } + const std::string& getAuthChannel() const { return authChannel_; } + void setAuthChannel(const std::string& channel) { authChannel_ = channel; } - std::string getSignatureMethod() const { return signatureMethod; } - - void setSignatureMethod(std::string input_signatureMethod) { signatureMethod = input_signatureMethod; } - - std::string getAuthChannel() const { return authChannel; } - - void setAuthChannel(std::string input_channel) { authChannel = input_channel; } - - bool isValid() const { - if (accessKey.empty() || secretKey.empty() || authChannel.empty()) - return false; - - return true; - } + bool isValid() const { return !accessKey_.empty() && !secretKey_.empty() && !authChannel_.empty(); } private: - std::string accessKey; - std::string secretKey; - std::string signature; - std::string signatureMethod; - std::string authChannel; + std::string accessKey_; + std::string secretKey_; + std::string signature_; + std::string signatureMethod_; + std::string authChannel_; }; + } // namespace rocketmq -#endif + +#endif // __SESSION_CREDENTIALS_H__ diff --git a/src/common/TopicFilterType.h b/include/TopicFilterType.h similarity index 79% rename from src/common/TopicFilterType.h rename to include/TopicFilterType.h index 9055003a2..9f57a4266 100644 --- a/src/common/TopicFilterType.h +++ b/include/TopicFilterType.h @@ -14,11 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __TOPICFILTERTYPE_H__ -#define __TOPICFILTERTYPE_H__ +#ifndef __TOPIC_FILTER_TYPE_H__ +#define __TOPIC_FILTER_TYPE_H__ namespace rocketmq { -// -#include -#include -#include -#include -#include -#include #include "DefaultMQProducer.h" -#include "MQMessageExt.h" #include "TransactionListener.h" -#include "TransactionSendResult.h" namespace rocketmq { -class ROCKETMQCLIENT_API TransactionMQProducer : public DefaultMQProducer { +class ROCKETMQCLIENT_API TransactionMQProducerConfig { public: - TransactionMQProducer(const std::string& producerGroup) - : DefaultMQProducer(producerGroup), m_thread_num(1), m_ioServiceWork(m_ioService) {} - virtual ~TransactionMQProducer() {} - void start(); - void shutdown(); - std::shared_ptr getTransactionListener() { return m_transactionListener; } - void setTransactionListener(TransactionListener* listener) { m_transactionListener.reset(listener); } - TransactionSendResult sendMessageInTransaction(MQMessage& msg, void* arg); - void checkTransactionState(const std::string& addr, - const MQMessageExt& message, - long tranStateTableOffset, - long commitLogOffset, - const std::string& msgId, - const std::string& transactionId, - const std::string& offsetMsgId); + TransactionMQProducerConfig(); + virtual ~TransactionMQProducerConfig() = default; - private: - void initTransactionEnv(); - void destroyTransactionEnv(); - void endTransaction(SendResult& sendResult, LocalTransactionState& localTransactionState); - void checkTransactionStateImpl(const std::string& addr, - const MQMessageExt& message, - long tranStateTableOffset, - long commitLogOffset, - const std::string& msgId, - const std::string& transactionId, - const std::string& offsetMsgId); + public: // TransactionMQProducerConfig + TransactionListener* getTransactionListener() const { return m_transactionListener; } + void setTransactionListener(TransactionListener* transactionListener) { m_transactionListener = transactionListener; } - private: - std::shared_ptr m_transactionListener; - int m_thread_num; - boost::thread_group m_threadpool; - boost::asio::io_service m_ioService; - boost::asio::io_service::work m_ioServiceWork; + protected: + TransactionListener* m_transactionListener; }; + +class ROCKETMQCLIENT_API TransactionMQProducer : public DefaultMQProducer, public TransactionMQProducerConfig { + public: + TransactionMQProducer(const std::string& groupname); + TransactionMQProducer(const std::string& groupname, RPCHookPtr rpcHook); + virtual ~TransactionMQProducer(); + + public: // MQProducer + void start() override; + void shutdown() override; + + // Transaction + TransactionSendResult sendMessageInTransaction(MQMessagePtr msg, void* arg) override; +}; + } // namespace rocketmq -#endif +#endif // __TRANSACTION_MQ_PRODUCER_H__ diff --git a/include/TransactionSendResult.h b/include/TransactionSendResult.h index 0bb1e480e..03d626f18 100644 --- a/include/TransactionSendResult.h +++ b/include/TransactionSendResult.h @@ -14,9 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#ifndef __TRANSACTIONSENDRESULT_H__ -#define __TRANSACTIONSENDRESULT_H__ +#ifndef __TRANSACTION_SEND_RESULT_H__ +#define __TRANSACTION_SEND_RESULT_H__ #include "SendResult.h" @@ -26,14 +25,7 @@ enum LocalTransactionState { COMMIT_MESSAGE, ROLLBACK_MESSAGE, UNKNOWN }; class ROCKETMQCLIENT_API TransactionSendResult : public SendResult { public: - TransactionSendResult() {} - - TransactionSendResult(const SendStatus& sendStatus, - const std::string& msgId, - const std::string& offsetMsgId, - const MQMessageQueue& messageQueue, - int64 queueOffset) - : SendResult(sendStatus, msgId, offsetMsgId, messageQueue, queueOffset) {} + TransactionSendResult(const SendResult& sendResult) : SendResult(sendResult), m_localTransactionState(UNKNOWN) {} LocalTransactionState getLocalTransactionState() { return m_localTransactionState; } @@ -44,5 +36,7 @@ class ROCKETMQCLIENT_API TransactionSendResult : public SendResult { private: LocalTransactionState m_localTransactionState; }; + } // namespace rocketmq -#endif \ No newline at end of file + +#endif // __TRANSACTION_SEND_RESULT_H__ diff --git a/include/CBatchMessage.h b/include/c/CBatchMessage.h similarity index 92% rename from include/CBatchMessage.h rename to include/c/CBatchMessage.h index b9a0e9daa..1b4da7e9f 100644 --- a/include/CBatchMessage.h +++ b/include/c/CBatchMessage.h @@ -14,9 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef __C_BATCH_MESSAGE_H__ +#define __C_BATCH_MESSAGE_H__ -#ifndef __C_BATCHMESSAGE_H__ -#define __C_BATCHMESSAGE_H__ #include "CCommon.h" #include "CMessage.h" @@ -33,4 +33,5 @@ ROCKETMQCLIENT_API int DestroyBatchMessage(CBatchMessage* batchMsg); #ifdef __cplusplus } #endif -#endif //__C_BATCHMESSAGE_H__ + +#endif // __C_BATCH_MESSAGE_H__ diff --git a/include/CCommon.h b/include/c/CCommon.h similarity index 94% rename from include/CCommon.h rename to include/c/CCommon.h index 0fbcbdadf..167f645cd 100644 --- a/include/CCommon.h +++ b/include/c/CCommon.h @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef __C_COMMON_H__ #define __C_COMMON_H__ @@ -25,11 +24,11 @@ extern "C" { #define MAX_MESSAGE_ID_LENGTH 256 #define MAX_TOPIC_LENGTH 512 #define MAX_BROKER_NAME_ID_LENGTH 256 + typedef enum _CStatus_ { - // Success - OK = 0, - // Failed, null pointer value - NULL_POINTER = 1, + OK = 0, // Success + + NULL_POINTER = 1, // Failed, null pointer value MALLOC_FAILED = 2, PRODUCER_ERROR_CODE_START = 10, PRODUCER_START_FAILED = 10, @@ -48,7 +47,6 @@ typedef enum _CStatus_ { PULLCONSUMER_FETCH_MQ_FAILED = 31, PULLCONSUMER_FETCH_MESSAGE_FAILED = 32, - Not_Support = 500, NOT_SUPPORT_NOW = -1 } CStatus; @@ -85,4 +83,5 @@ typedef enum _CMessageModel_ { BROADCASTING, CLUSTERING } CMessageModel; #ifdef __cplusplus } #endif -#endif //__C_COMMON_H__ + +#endif // __C_COMMON_H__ diff --git a/include/CErrorMessage.h b/include/c/CErrorMessage.h similarity index 91% rename from include/CErrorMessage.h rename to include/c/CErrorMessage.h index 7d11b5638..928950cf2 100644 --- a/include/CErrorMessage.h +++ b/include/c/CErrorMessage.h @@ -14,9 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#ifndef __CERROR_MESSAGE_H__ -#define __CERROR_MESSAGE_H__ +#ifndef __C_ERROR_MESSAGE_H__ +#define __C_ERROR_MESSAGE_H__ #include "CCommon.h" @@ -29,4 +28,5 @@ ROCKETMQCLIENT_API const char* GetLatestErrorMessage(); // Return the last erro #ifdef __cplusplus } #endif -#endif //__CERROR_MESSAGE_H__ + +#endif // __C_ERROR_MESSAGE_H__ diff --git a/include/CMQException.h b/include/c/CMQException.h similarity index 99% rename from include/CMQException.h rename to include/c/CMQException.h index 4bdf3d149..7e2f498af 100644 --- a/include/CMQException.h +++ b/include/c/CMQException.h @@ -16,6 +16,7 @@ */ #ifndef __C_MQEXCPTION_H__ #define __C_MQEXCPTION_H__ + #include "CCommon.h" #ifdef __cplusplus @@ -25,16 +26,17 @@ extern "C" { #define MAX_EXEPTION_MSG_LENGTH 512 #define MAX_EXEPTION_FILE_LENGTH 256 #define MAX_EXEPTION_TYPE_LENGTH 128 + typedef struct _CMQException_ { int error; int line; char file[MAX_EXEPTION_FILE_LENGTH]; char msg[MAX_EXEPTION_MSG_LENGTH]; char type[MAX_EXEPTION_TYPE_LENGTH]; - } CMQException; #ifdef __cplusplus } #endif + #endif diff --git a/include/CMessage.h b/include/c/CMessage.h similarity index 98% rename from include/CMessage.h rename to include/c/CMessage.h index be46435a2..37feda702 100644 --- a/include/CMessage.h +++ b/include/c/CMessage.h @@ -14,9 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef __C_MESSAGE_H__ #define __C_MESSAGE_H__ + #include "CCommon.h" #ifdef __cplusplus @@ -45,4 +45,5 @@ ROCKETMQCLIENT_API int GetOriginDelayTimeLevel(CMessage* msg); #ifdef __cplusplus } #endif -#endif //__C_MESSAGE_H__ + +#endif // __C_MESSAGE_H__ diff --git a/include/CMessageExt.h b/include/c/CMessageExt.h similarity index 98% rename from include/CMessageExt.h rename to include/c/CMessageExt.h index 42d35deb7..17c0cee6b 100644 --- a/include/CMessageExt.h +++ b/include/c/CMessageExt.h @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef __C_MESSAGE_EXT_H__ #define __C_MESSAGE_EXT_H__ @@ -46,4 +45,5 @@ ROCKETMQCLIENT_API long long GetMessagePreparedTransactionOffset(CMessageExt* ms #ifdef __cplusplus } #endif -#endif //__C_MESSAGE_EXT_H__ + +#endif // __C_MESSAGE_EXT_H__ diff --git a/include/CMessageQueue.h b/include/c/CMessageQueue.h similarity index 97% rename from include/CMessageQueue.h rename to include/c/CMessageQueue.h index 859f71fd2..bd6da3784 100644 --- a/include/CMessageQueue.h +++ b/include/c/CMessageQueue.h @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef __C_MESSAGE_QUEUE_H__ #define __C_MESSAGE_QUEUE_H__ @@ -33,4 +32,5 @@ typedef struct _CMessageQueue_ { #ifdef __cplusplus } #endif -#endif //__C_MESSAGE_H__ + +#endif // __C_MESSAGE_H__ diff --git a/include/CProducer.h b/include/c/CProducer.h similarity index 99% rename from include/CProducer.h rename to include/c/CProducer.h index 09b23bae4..b70e28e65 100644 --- a/include/CProducer.h +++ b/include/c/CProducer.h @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef __C_PRODUCER_H__ #define __C_PRODUCER_H__ @@ -36,6 +35,7 @@ typedef void (*CSendSuccessCallback)(CSendResult result); typedef void (*CSendExceptionCallback)(CMQException e); typedef void (*COnSendSuccessCallback)(CSendResult result, CMessage* msg, void* userData); typedef void (*COnSendExceptionCallback)(CMQException e, CMessage* msg, void* userData); + typedef CTransactionStatus (*CLocalTransactionCheckerCallback)(CProducer* producer, CMessageExt* msg, void* data); typedef CTransactionStatus (*CLocalTransactionExecutorCallback)(CProducer* producer, CMessage* msg, void* data); @@ -101,7 +101,9 @@ ROCKETMQCLIENT_API int SendMessageTransaction(CProducer* producer, CLocalTransactionExecutorCallback callback, void* userData, CSendResult* result); + #ifdef __cplusplus } #endif -#endif //__C_PRODUCER_H__ \ No newline at end of file + +#endif // __C_PRODUCER_H__ diff --git a/include/CPullConsumer.h b/include/c/CPullConsumer.h similarity index 98% rename from include/CPullConsumer.h rename to include/c/CPullConsumer.h index ec960056d..41ebbb9ba 100644 --- a/include/CPullConsumer.h +++ b/include/c/CPullConsumer.h @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef __C_PULL_CONSUMER_H__ #define __C_PULL_CONSUMER_H__ @@ -58,4 +57,5 @@ ROCKETMQCLIENT_API int ReleasePullResult(CPullResult pullResult); #ifdef __cplusplus } #endif -#endif //__C_PUSH_CONSUMER_H__ + +#endif // __C_PUSH_CONSUMER_H__ diff --git a/include/CPullResult.h b/include/c/CPullResult.h similarity index 97% rename from include/CPullResult.h rename to include/c/CPullResult.h index 3c5aaaceb..2f5803081 100644 --- a/include/CPullResult.h +++ b/include/c/CPullResult.h @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef __C_PULL_RESULT_H__ #define __C_PULL_RESULT_H__ @@ -24,6 +23,7 @@ #ifdef __cplusplus extern "C" { #endif + typedef enum E_CPullStatus { E_FOUND, E_NO_NEW_MSG, @@ -45,4 +45,5 @@ typedef struct _CPullResult_ { #ifdef __cplusplus } #endif -#endif //__C_PULL_RESULT_H__ + +#endif // __C_PULL_RESULT_H__ diff --git a/include/CPushConsumer.h b/include/c/CPushConsumer.h similarity index 99% rename from include/CPushConsumer.h rename to include/c/CPushConsumer.h index 4880d0f8a..3754879e4 100644 --- a/include/CPushConsumer.h +++ b/include/c/CPushConsumer.h @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef __C_PUSH_CONSUMER_H__ #define __C_PUSH_CONSUMER_H__ @@ -62,4 +61,5 @@ ROCKETMQCLIENT_API int SetPushConsumerMaxCacheMessageSizeInMb(CPushConsumer* con #ifdef __cplusplus } #endif -#endif //__C_PUSH_CONSUMER_H__ + +#endif // __C_PUSH_CONSUMER_H__ diff --git a/include/CSendResult.h b/include/c/CSendResult.h similarity index 97% rename from include/CSendResult.h rename to include/c/CSendResult.h index 78f21c83a..3ac2fcd74 100644 --- a/include/CSendResult.h +++ b/include/c/CSendResult.h @@ -14,11 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef __C_SEND_RESULT_H__ #define __C_SEND_RESULT_H__ #include "CCommon.h" + #ifdef __cplusplus extern "C" { #endif @@ -39,4 +39,5 @@ typedef struct _SendResult_ { #ifdef __cplusplus } #endif -#endif //__C_PRODUCER_H__ + +#endif // __C_PRODUCER_H__ diff --git a/include/CTransactionStatus.h b/include/c/CTransactionStatus.h similarity index 96% rename from include/CTransactionStatus.h rename to include/c/CTransactionStatus.h index 435b841b8..f0bff3c97 100644 --- a/include/CTransactionStatus.h +++ b/include/c/CTransactionStatus.h @@ -14,13 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef __C_TRANSACTION_STATUS_H__ #define __C_TRANSACTION_STATUS_H__ #ifdef __cplusplus extern "C" { #endif + typedef enum E_CTransactionStatus { E_COMMIT_TRANSACTION = 0, E_ROLLBACK_TRANSACTION = 1, @@ -30,4 +30,5 @@ typedef enum E_CTransactionStatus { #ifdef __cplusplus } #endif -#endif //__C_TRANSACTION_STATUS_H__ \ No newline at end of file + +#endif // __C_TRANSACTION_STATUS_H__ diff --git a/libs/signature/CMakeLists.txt b/libs/signature/CMakeLists.txt index 0348e48e8..6a2aa1f73 100755 --- a/libs/signature/CMakeLists.txt +++ b/libs/signature/CMakeLists.txt @@ -18,12 +18,12 @@ project(signature) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib) -aux_source_directory(src/ DIR_LIB_SRCS) +aux_source_directory(src/ DIR_LIB_SRCS) add_library(Signature STATIC ${DIR_LIB_SRCS}) target_link_libraries(Signature ${deplibs}) set_target_properties(Signature PROPERTIES OUTPUT_NAME "Signature") # install -install(TARGETS Signature DESTINATION lib) +install (TARGETS Signature DESTINATION lib) #install (DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include/rocketmq) diff --git a/libs/signature/include/spas_client.h b/libs/signature/include/spas_client.h index 7bf6aae04..d8262fa12 100644 --- a/libs/signature/include/spas_client.h +++ b/libs/signature/include/spas_client.h @@ -28,14 +28,10 @@ extern "C" { namespace rocketmqSignature { #endif -#define SPAS_MAX_KEY_LEN 128 /* max access_key/secret_key length */ -#define SPAS_MAX_PATH 256 /* max credential file path length */ -#define SPAS_ACCESS_KEY_TAG \ - "accessKey" /* access_key tag in credential file \ - */ -#define SPAS_SECRET_KEY_TAG \ - "secretKey" /* secret_key tag in credential file \ - */ +#define SPAS_MAX_KEY_LEN 128 /* max access_key/secret_key length */ +#define SPAS_MAX_PATH 256 /* max credential file path length */ +#define SPAS_ACCESS_KEY_TAG "accessKey" /* access_key tag in credential file */ +#define SPAS_SECRET_KEY_TAG "secretKey" /* secret_key tag in credential file */ #define SPAS_CREDENTIAL_ENV "SPAS_CREDENTIAL" /* credential file environment variable */ typedef enum { diff --git a/project/CMakeLists.txt b/project/CMakeLists.txt index 60b5d0db2..074d55fde 100755 --- a/project/CMakeLists.txt +++ b/project/CMakeLists.txt @@ -16,24 +16,23 @@ # source files project(rocketmq-client) -file(GLOB_RECURSE SRC_FILES ${CMAKE_SOURCE_DIR}/src/*) -list(REMOVE_ITEM SRC_FILES ${CMAKE_SOURCE_DIR}/src/dllmain.cpp) +file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/../src/*.c*) +list(REMOVE_ITEM SRC_FILES ${PROJECT_SOURCE_DIR}/../src/dllmain.cpp) # subdirs SET(SUB_DIRS) -file(GLOB children ${CMAKE_SOURCE_DIR}/src/*) +file(GLOB children ${PROJECT_SOURCE_DIR}/../src/*) FOREACH (child ${children}) IF (IS_DIRECTORY ${child}) LIST(APPEND SUB_DIRS ${child}) ENDIF () ENDFOREACH () -LIST(APPEND SUB_DIRS ${CMAKE_SOURCE_DIR}/src) +LIST(APPEND SUB_DIRS ${PROJECT_SOURCE_DIR}/../src) -include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${SUB_DIRS}) # libs_directories -file(GLOB LIB_DIRS ${CMAKE_SOURCE_DIR}/libs/*) +file(GLOB LIB_DIRS ${PROJECT_SOURCE_DIR}/../libs/*) foreach (dir ${LIB_DIRS}) if (IS_DIRECTORY ${dir}) set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH};${dir}) @@ -43,32 +42,45 @@ endforeach () # static if (BUILD_ROCKETMQ_STATIC) - add_library(rocketmq_static STATIC ${SRC_FILES}) - set_target_properties(rocketmq_static PROPERTIES OUTPUT_NAME "rocketmq") - add_dependencies(rocketmq_static Signature) - target_link_libraries(rocketmq_static Signature) - target_link_libraries(rocketmq_static ${JSONCPP_LIBRARIES}) - target_link_libraries(rocketmq_static ${LIBEVENT_LIBRARIES}) - target_link_libraries(rocketmq_static ${Boost_LIBRARIES}) - target_link_libraries(rocketmq_static ${deplibs}) + add_library(rocketmq_static STATIC + ${SRC_FILES}) + target_include_directories(rocketmq_static + PUBLIC ${PROJECT_SOURCE_DIR}/../include) + if (spdlog_FOUND) + target_link_libraries(rocketmq_static + PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} ${LIBEVENT_LIBRARIES} spdlog::spdlog) + else (spdlog_FOUND) + target_link_libraries(rocketmq_static + PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} ${LIBEVENT_LIBRARIES}) + endif (spdlog_FOUND) + # set_target_properties(rocketmq_static + # PROPERTIES OUTPUT_NAME "rocketmq") + + include(BundleStaticLibrary) + bundle_static_library(rocketmq_static rocketmq) endif () # shared if (BUILD_ROCKETMQ_SHARED) - set(CMAKE_SHARED_LINKER_FLAGS "-DBOOST_ALL_DYN_LINK -shared ") - add_library(rocketmq_shared SHARED ${SRC_FILES}) - set_target_properties(rocketmq_shared PROPERTIES OUTPUT_NAME "rocketmq") - add_dependencies(rocketmq_shared Signature) - target_link_libraries(rocketmq_shared Signature) - target_link_libraries(rocketmq_shared ${JSONCPP_LIBRARIES}) - target_link_libraries(rocketmq_shared ${LIBEVENT_LIBRARIES}) - target_link_libraries(rocketmq_shared ${Boost_LIBRARIES}) - target_link_libraries(rocketmq_shared ${deplibs}) + add_library(rocketmq_shared SHARED + ${SRC_FILES}) + target_include_directories(rocketmq_shared + PUBLIC ${PROJECT_SOURCE_DIR}/../include) + if (spdlog_FOUND) + target_link_libraries(rocketmq_shared + PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} ${LIBEVENT_LIBRARIES} spdlog::spdlog) + else (spdlog_FOUND) + target_link_libraries(rocketmq_shared + PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} ${LIBEVENT_LIBRARIES}) + endif (spdlog_FOUND) + set_target_properties(rocketmq_shared + PROPERTIES OUTPUT_NAME "rocketmq") endif () # install if (BUILD_ROCKETMQ_STATIC) install(TARGETS rocketmq_static DESTINATION lib) + install(FILES ${LIBRARY_OUTPUT_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}rocketmq${CMAKE_STATIC_LIBRARY_SUFFIX} DESTINATION lib) endif () if (BUILD_ROCKETMQ_SHARED) install(TARGETS rocketmq_shared DESTINATION lib) diff --git a/src/ClientRemotingProcessor.cpp b/src/ClientRemotingProcessor.cpp new file mode 100644 index 000000000..a9989479b --- /dev/null +++ b/src/ClientRemotingProcessor.cpp @@ -0,0 +1,158 @@ +/* + * 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 "ClientRemotingProcessor.h" + +#include "CommandHeader.h" +#include "ConsumerRunningInfo.h" +#include "MQDecoder.h" +#include "MQProtos.h" + +namespace rocketmq { + +ClientRemotingProcessor::ClientRemotingProcessor(MQClientInstance* mqClientFactory) + : m_mqClientFactory(mqClientFactory) {} + +ClientRemotingProcessor::~ClientRemotingProcessor() = default; + +RemotingCommand* ClientRemotingProcessor::processRequest(const std::string& addr, RemotingCommand* request) { + LOG_DEBUG("request Command received:processRequest, addr:%s, code:%d", addr.data(), request->getCode()); + switch (request->getCode()) { + case CHECK_TRANSACTION_STATE: + return checkTransactionState(addr, request); + break; + case NOTIFY_CONSUMER_IDS_CHANGED: + return notifyConsumerIdsChanged(request); + break; + case RESET_CONSUMER_CLIENT_OFFSET: // oneWayRPC + return resetOffset(request); + case GET_CONSUMER_STATUS_FROM_CLIENT: + // return getConsumeStatus( request); + break; + case GET_CONSUMER_RUNNING_INFO: + return getConsumerRunningInfo(addr, request); + break; + case CONSUME_MESSAGE_DIRECTLY: + // return consumeMessageDirectly( request); + break; + default: + break; + } + return nullptr; +} + +RemotingCommand* ClientRemotingProcessor::resetOffset(RemotingCommand* request) { + auto* responseHeader = request->decodeCommandCustomHeader(); + auto requestBody = request->getBody(); + if (requestBody != nullptr && requestBody->getSize() > 0) { + std::unique_ptr body(ResetOffsetBody::Decode(*requestBody)); + if (body != nullptr) { + m_mqClientFactory->resetOffset(responseHeader->getGroup(), responseHeader->getTopic(), body->getOffsetTable()); + } else { + LOG_ERROR("resetOffset failed as received data could not be unserialized"); + } + } + return nullptr; // as resetOffset is oneWayRPC, do not need return any response +} + +ResetOffsetBody* ResetOffsetBody::Decode(MemoryBlock& mem) { + Json::Value root = RemotingSerializable::fromJson(mem); + Json::Value qds = root["offsetTable"]; + std::unique_ptr body(new ResetOffsetBody()); + for (unsigned int i = 0; i < qds.size(); i++) { + Json::Value qd = qds[i]; + MQMessageQueue mq(qd["brokerName"].asString(), qd["topic"].asString(), qd["queueId"].asInt()); + int64_t offset = qd["offset"].asInt64(); + body->setOffsetTable(mq, offset); + } + return body.release(); +} + +std::map ResetOffsetBody::getOffsetTable() { + return m_offsetTable; +} + +void ResetOffsetBody::setOffsetTable(const MQMessageQueue& mq, int64_t offset) { + m_offsetTable[mq] = offset; +} + +RemotingCommand* ClientRemotingProcessor::getConsumerRunningInfo(const std::string& addr, RemotingCommand* request) { + auto* requestHeader = request->decodeCommandCustomHeader(); + LOG_INFO("getConsumerRunningInfo:%s", requestHeader->getConsumerGroup().c_str()); + + RemotingCommand* response = + new RemotingCommand(request->getCode(), "CPP", request->getVersion(), request->getOpaque(), request->getFlag(), + request->getRemark(), nullptr); + + std::unique_ptr runningInfo( + m_mqClientFactory->consumerRunningInfo(requestHeader->getConsumerGroup())); + if (runningInfo != nullptr) { + if (requestHeader->isJstackEnable()) { + /*string jstack = UtilAll::jstack(); + consumerRunningInfo->setJstack(jstack);*/ + } + response->setCode(SUCCESS_VALUE); + std::string body = runningInfo->encode(); + response->setBody(body); + } else { + response->setCode(SYSTEM_ERROR); + response->setRemark("The Consumer Group not exist in this consumer"); + } + + return response; +} + +RemotingCommand* ClientRemotingProcessor::notifyConsumerIdsChanged(RemotingCommand* request) { + auto* requestHeader = request->decodeCommandCustomHeader(); + LOG_INFO("notifyConsumerIdsChanged:%s", requestHeader->getConsumerGroup().c_str()); + m_mqClientFactory->rebalanceImmediately(); + return nullptr; +} + +RemotingCommand* ClientRemotingProcessor::checkTransactionState(const std::string& addr, RemotingCommand* request) { + auto* requestHeader = request->decodeCommandCustomHeader(); + assert(requestHeader != nullptr); + + auto requestBody = request->getBody(); + if (requestBody != nullptr && requestBody->getSize() > 0) { + MQMessageExtPtr2 messageExt = MQDecoder::decode(*requestBody); + if (messageExt != nullptr) { + const auto& transactionId = messageExt->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX); + if (!transactionId.empty()) { + messageExt->setTransactionId(transactionId); + } + const auto& group = messageExt->getProperty(MQMessageConst::PROPERTY_PRODUCER_GROUP); + if (!group.empty()) { + auto* producer = m_mqClientFactory->selectProducer(group); + if (producer != nullptr) { + producer->checkTransactionState(addr, messageExt, requestHeader); + } else { + LOG_DEBUG_NEW("checkTransactionState, pick producer by group[{}] failed", group); + } + } else { + LOG_WARN_NEW("checkTransactionState, pick producer group failed"); + } + } else { + LOG_WARN_NEW("checkTransactionState, decode message failed"); + } + } else { + LOG_ERROR_NEW("checkTransactionState, request body is empty, request header: {}", requestHeader->toString()); + } + + return nullptr; +} + +} // namespace rocketmq diff --git a/src/ClientRemotingProcessor.h b/src/ClientRemotingProcessor.h new file mode 100644 index 000000000..efcb5fc95 --- /dev/null +++ b/src/ClientRemotingProcessor.h @@ -0,0 +1,55 @@ +/* + * 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 __CLIENT_REMOTING_PROCESSOR_H__ +#define __CLIENT_REMOTING_PROCESSOR_H__ + +#include "MQClientInstance.h" +#include "MQMessageQueue.h" +#include "RequestProcessor.h" + +namespace rocketmq { + +class ClientRemotingProcessor : public RequestProcessor { + public: + ClientRemotingProcessor(MQClientInstance* mqClientFactory); + virtual ~ClientRemotingProcessor(); + + RemotingCommand* processRequest(const std::string& addr, RemotingCommand* request) override; + + RemotingCommand* resetOffset(RemotingCommand* request); + RemotingCommand* getConsumerRunningInfo(const std::string& addr, RemotingCommand* request); + RemotingCommand* notifyConsumerIdsChanged(RemotingCommand* request); + RemotingCommand* checkTransactionState(const std::string& addr, RemotingCommand* request); + + private: + MQClientInstance* m_mqClientFactory; +}; + +class ResetOffsetBody { + public: + static ResetOffsetBody* Decode(MemoryBlock& mem); + + std::map getOffsetTable(); + void setOffsetTable(const MQMessageQueue& mq, int64_t offset); + + private: + std::map m_offsetTable; +}; + +} // namespace rocketmq + +#endif // __CLIENT_REMOTING_PROCESSOR_H__ diff --git a/src/MQAdminImpl.cpp b/src/MQAdminImpl.cpp new file mode 100644 index 000000000..ea0651f43 --- /dev/null +++ b/src/MQAdminImpl.cpp @@ -0,0 +1,136 @@ +/* + * 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 "MQAdminImpl.h" + +#include "MQClientAPIImpl.h" +#include "MQClientInstance.h" +#include "TopicPublishInfo.h" + +namespace rocketmq { + +void MQAdminImpl::createTopic(const std::string& key, const std::string& newTopic, int queueNum) {} + +void MQAdminImpl::fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) { + try { + TopicRouteDataPtr topicRouteData( + m_mqClientFactory->getMQClientAPIImpl()->getTopicRouteInfoFromNameServer(topic, 1000 * 3)); + if (topicRouteData != nullptr) { + mqs = m_mqClientFactory->topicRouteData2TopicSubscribeInfo(topic, topicRouteData); + if (!mqs.empty()) { + return; + } else { + THROW_MQEXCEPTION(MQClientException, + "Can not find Message Queue for this topic, " + topic + " Namesrv return empty", -1); + } + } + } catch (const std::exception& e) { + THROW_MQEXCEPTION(MQClientException, "Can not find Message Queue for this topic, " + topic, -1); + } + + THROW_MQEXCEPTION(MQClientException, "Unknown why, Can not find Message Queue for this topic, " + topic, -1); +} + +int64_t MQAdminImpl::searchOffset(const MQMessageQueue& mq, int64_t timestamp) { + std::string brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName()); + if (brokerAddr.empty()) { + m_mqClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic()); + brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName()); + } + + if (!brokerAddr.empty()) { + try { + return m_mqClientFactory->getMQClientAPIImpl()->searchOffset(brokerAddr, mq.getTopic(), mq.getQueueId(), + timestamp, 1000 * 3); + } catch (MQException& e) { + THROW_MQEXCEPTION(MQClientException, "Invoke Broker exception", -1); + } + } + THROW_MQEXCEPTION(MQClientException, "The broker is not exist", -1); +} + +int64_t MQAdminImpl::maxOffset(const MQMessageQueue& mq) { + std::string brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName()); + if (brokerAddr.empty()) { + m_mqClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic()); + brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName()); + } + + if (!brokerAddr.empty()) { + try { + return m_mqClientFactory->getMQClientAPIImpl()->getMaxOffset(brokerAddr, mq.getTopic(), mq.getQueueId(), + 1000 * 3); + } catch (MQException& e) { + THROW_MQEXCEPTION(MQClientException, "Invoke Broker exception", -1); + } + } + THROW_MQEXCEPTION(MQClientException, "The broker is not exist", -1); +} + +int64_t MQAdminImpl::minOffset(const MQMessageQueue& mq) { + std::string brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName()); + if (brokerAddr.empty()) { + m_mqClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic()); + brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName()); + } + + if (!brokerAddr.empty()) { + try { + return m_mqClientFactory->getMQClientAPIImpl()->getMinOffset(brokerAddr, mq.getTopic(), mq.getQueueId(), + 1000 * 3); + } catch (const std::exception& e) { + THROW_MQEXCEPTION(MQClientException, "Invoke Broker[" + brokerAddr + "] exception", -1); + } + } + + THROW_MQEXCEPTION(MQClientException, "The broker[" + mq.getBrokerName() + "] not exist", -1); +} + +int64_t MQAdminImpl::earliestMsgStoreTime(const MQMessageQueue& mq) { + std::string brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName()); + if (brokerAddr.empty()) { + m_mqClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic()); + brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName()); + } + + if (!brokerAddr.empty()) { + try { + return m_mqClientFactory->getMQClientAPIImpl()->getEarliestMsgStoretime(brokerAddr, mq.getTopic(), + mq.getQueueId(), 1000 * 3); + } catch (MQException& e) { + THROW_MQEXCEPTION(MQClientException, "Invoke Broker exception", -1); + } + } + THROW_MQEXCEPTION(MQClientException, "The broker is not exist", -1); +} + +MQMessageExtPtr MQAdminImpl::viewMessage(const std::string& msgId) { + try { + return nullptr; + } catch (MQException& e) { + THROW_MQEXCEPTION(MQClientException, "message id illegal", -1); + } +} + +QueryResult MQAdminImpl::queryMessage(const std::string& topic, + const std::string& key, + int maxNum, + int64_t begin, + int64_t end) { + THROW_MQEXCEPTION(MQClientException, "queryMessage", -1); +} + +} // namespace rocketmq diff --git a/src/MQAdminImpl.h b/src/MQAdminImpl.h new file mode 100644 index 000000000..244d9a356 --- /dev/null +++ b/src/MQAdminImpl.h @@ -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 __MQ_ADMIN_IMPL_H___ +#define __MQ_ADMIN_IMPL_H___ + +#include +#include + +#include "MQClientInstance.h" +#include "MQMessageExt.h" +#include "MQMessageQueue.h" +#include "QueryResult.h" + +namespace rocketmq { + +class MQAdminImpl { + public: + MQAdminImpl(MQClientInstance* mqClientFactory) : m_mqClientFactory(mqClientFactory) {} + + void createTopic(const std::string& key, const std::string& newTopic, int queueNum); + + void fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs); + + int64_t searchOffset(const MQMessageQueue& mq, int64_t timestamp); + int64_t maxOffset(const MQMessageQueue& mq); + int64_t minOffset(const MQMessageQueue& mq); + int64_t earliestMsgStoreTime(const MQMessageQueue& mqClientFactory); + + MQMessageExtPtr viewMessage(const std::string& msgId); + QueryResult queryMessage(const std::string& topic, const std::string& key, int maxNum, int64_t begin, int64_t end); + + private: + MQClientInstance* m_mqClientFactory; +}; + +} // namespace rocketmq + +#endif // __MQ_ADMIN_IMPL_H___ diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index f2829a9ae..22d937ae9 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -14,537 +14,262 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "MQClientAPIImpl.h" -#include -#include -#include -#include -#include "CommunicationMode.h" -#include "Logging.h" -#include "MQDecoder.h" -#include "PullResultExt.h" -namespace rocketmq { -//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; - } +#include +#include +#include - 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; +#include "ClientRemotingProcessor.h" +#include "MQClientInstance.h" +#include "MessageBatch.h" +#include "MessageClientIDSetter.h" +#include "PullCallbackWrap.h" +#include "PullResultExt.h" +#include "SendCallbackWrap.h" +#include "TcpRemotingClient.h" - if (isSync) { - LOG_INFO("fsync with filename:%s", filename.c_str()); - fflush(pFd); - } - fclose(pFd); +namespace rocketmq { - return true; +MQClientAPIImpl::MQClientAPIImpl(ClientRemotingProcessor* clientRemotingProcessor, + std::shared_ptr rpcHook, + const MQClientConfig* clientConfig) + : m_remotingClient(new TcpRemotingClient(clientConfig->getTcpTransportWorkerThreadNum(), + clientConfig->getTcpTransportConnectTimeout(), + clientConfig->getTcpTransportTryLockTimeout())) { + m_remotingClient->registerRPCHook(rpcHook); + m_remotingClient->registerProcessor(CHECK_TRANSACTION_STATE, clientRemotingProcessor); + m_remotingClient->registerProcessor(RESET_CONSUMER_CLIENT_OFFSET, clientRemotingProcessor); + m_remotingClient->registerProcessor(GET_CONSUMER_STATUS_FROM_CLIENT, clientRemotingProcessor); + m_remotingClient->registerProcessor(GET_CONSUMER_RUNNING_INFO, clientRemotingProcessor); + m_remotingClient->registerProcessor(NOTIFY_CONSUMER_IDS_CHANGED, clientRemotingProcessor); + m_remotingClient->registerProcessor(CONSUME_MESSAGE_DIRECTLY, clientRemotingProcessor); } -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 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 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)); - } - } +MQClientAPIImpl::~MQClientAPIImpl() = default; - 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::start() { + m_remotingClient->start(); } -void MQClientAPIImpl::updateNameServerAddr(const string& addrs) { - if (m_pRemotingClient != NULL) - m_pRemotingClient->updateNameServerAddressList(addrs); +void MQClientAPIImpl::shutdown() { + m_remotingClient->shutdown(); } -void MQClientAPIImpl::callSignatureBeforeRequest(const string& addr, - RemotingCommand& request, - const SessionCredentials& session_credentials) { - ClientRPCHook rpcHook(session_credentials); - rpcHook.doBeforeRequest(addr, request); +void MQClientAPIImpl::updateNameServerAddr(const std::string& addrs) { + if (m_remotingClient != nullptr) { + m_remotingClient->updateNameServerAddressList(addrs); + } } -// 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(); +void MQClientAPIImpl::createTopic(const std::string& addr, const std::string& defaultTopic, TopicConfig topicConfig) { 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()); + requestHeader->topic = topicConfig.getTopicName(); + 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 response(m_pRemotingClient->invokeSync(addr, request)); - - if (response) { - switch (response->getCode()) { - case SUCCESS_VALUE: - return; - default: - break; + std::unique_ptr response(m_remotingClient->invokeSync(addr, request)); + assert(response != nullptr); + switch (response->getCode()) { + case SUCCESS_VALUE: { + return; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + default: + break; } - THROW_MQEXCEPTION(MQBrokerException, "response is null", -1); + + THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); } -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(); +SendResult* MQClientAPIImpl::sendMessage(const std::string& addr, + const std::string& brokerName, + const MQMessagePtr msg, + std::unique_ptr requestHeader, + int timeoutMillis, + CommunicationMode communicationMode, + DefaultMQProducerImplPtr producer) { + return sendMessage(addr, brokerName, msg, std::move(requestHeader), timeoutMillis, communicationMode, nullptr, + nullptr, nullptr, 0, producer); +} + +SendResult* MQClientAPIImpl::sendMessage(const std::string& addr, + const std::string& brokerName, + const MQMessagePtr msg, + std::unique_ptr requestHeader, + int timeoutMillis, + CommunicationMode communicationMode, + SendCallback* sendCallback, + TopicPublishInfoPtr topicPublishInfo, + MQClientInstancePtr instance, + int retryTimesWhenSendFailed, + DefaultMQProducerImplPtr producer) { + int code = SEND_MESSAGE; + std::unique_ptr header; + + if (msg->isBatch()) { + code = SEND_BATCH_MESSAGE; + header.reset(SendMessageRequestHeaderV2::createSendMessageRequestHeaderV2(requestHeader.get())); + } else { + header = std::move(requestHeader); + } + + RemotingCommand request(code, header.release()); + request.setBody(msg->getBody()); switch (communicationMode) { case ComMode_ONEWAY: - m_pRemotingClient->invokeOneway(addr, request); - break; + m_remotingClient->invokeOneway(addr, request); + return nullptr; case ComMode_ASYNC: - sendMessageAsync(addr, brokerName, msg, request, pSendCallback, timeoutMillis, maxRetrySendTimes, 1); - break; + sendMessageAsync(addr, brokerName, msg, std::move(request), sendCallback, topicPublishInfo, instance, + timeoutMillis, retryTimesWhenSendFailed, producer); + return nullptr; case ComMode_SYNC: return sendMessageSync(addr, brokerName, msg, request, timeoutMillis); default: + assert(false); 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()); - } + return nullptr; } -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(); +void MQClientAPIImpl::sendMessageAsync(const std::string& addr, + const std::string& brokerName, + const MQMessagePtr msg, + RemotingCommand&& request, + SendCallback* sendCallback, + TopicPublishInfoPtr topicPublishInfo, + MQClientInstancePtr instance, + int64_t timeoutMillis, + int retryTimesWhenSendFailed, + DefaultMQProducerImplPtr producer) throw(RemotingException) { + // delete in future + auto cbw = new SendCallbackWrap(addr, brokerName, msg, std::forward(request), sendCallback, + topicPublishInfo, instance, retryTimesWhenSendFailed, 0, producer); - unique_ptr 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()); + try { + sendMessageAsyncImpl(cbw, timeoutMillis); + } catch (RemotingException& e) { + deleteAndZero(cbw); + throw e; } } -// 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 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 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; +void MQClientAPIImpl::sendMessageAsyncImpl(SendCallbackWrap* cbw, int64_t timeoutMillis) throw(RemotingException) { + const auto& addr = cbw->getAddr(); + auto& request = cbw->getRemotingCommand(); + m_remotingClient->invokeAsync(addr, request, cbw, timeoutMillis); } -int MQClientAPIImpl::wipeWritePermOfBroker(const string& namesrvAddr, const string& brokerName, int timeoutMillis) { - return 0; +SendResult* MQClientAPIImpl::sendMessageSync(const std::string& addr, + const std::string& brokerName, + const MQMessagePtr msg, + RemotingCommand& request, + int timeoutMillis) { + // block until response + std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + assert(response != nullptr); + return processSendResponse(brokerName, msg, response.get()); } -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 ""; -} +SendResult* MQClientAPIImpl::processSendResponse(const std::string& brokerName, + const MQMessagePtr msg, + RemotingCommand* response) { + SendStatus sendStatus = SEND_OK; + switch (response->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: + THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + return nullptr; + } -KVTable MQClientAPIImpl::getKVListByNamespace(const string& projectNamespace, int timeoutMillis) { - return KVTable(); -} + auto* responseHeader = response->decodeCommandCustomHeader(); + assert(responseHeader != nullptr); -void MQClientAPIImpl::deleteKVConfigByValue(const string& projectNamespace, - const string& projectGroup, - int timeoutMillis) {} + MQMessageQueue messageQueue(msg->getTopic(), brokerName, responseHeader->queueId); -SendResult MQClientAPIImpl::sendMessageSync(const string& addr, - const string& brokerName, - const MQMessage& msg, - RemotingCommand& request, - int timeoutMillis) { - // 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); -} + std::string uniqMsgId = MessageClientIDSetter::getUniqID(*msg); -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(); - //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 + // MessageBatch + if (msg->isBatch()) { + const auto& messages = static_cast(msg)->getMessages(); + uniqMsgId.clear(); + uniqMsgId.reserve(33 * messages.size()); + for (const auto& message : messages) { + if (!uniqMsgId.empty()) { + uniqMsgId.append(","); } + uniqMsgId.append(MessageClientIDSetter::getUniqID(*message)); } + } - 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); + SendResult* sendResult = + new SendResult(sendStatus, uniqMsgId, responseHeader->msgId, messageQueue, responseHeader->queueOffset); + sendResult->setTransactionId(responseHeader->transactionId); - if (cbw) { - cbw->onException(); - deleteAndZero(cbw); - } else { - THROW_MQEXCEPTION(MQClientException, "sendMessageAsync failed", -1); - } - } + return sendResult; } -PullResult* MQClientAPIImpl::pullMessage(const string& addr, - PullMessageRequestHeader* pRequestHeader, +PullResult* MQClientAPIImpl::pullMessage(const std::string& addr, + PullMessageRequestHeader* requestHeader, int timeoutMillis, - int communicationMode, - PullCallback* pullCallback, - void* pArg, - const SessionCredentials& sessionCredentials) { - RemotingCommand request(PULL_MESSAGE, pRequestHeader); - callSignatureBeforeRequest(addr, request, sessionCredentials); - request.Encode(); + CommunicationMode communicationMode, + PullCallback* pullCallback) { + RemotingCommand request(PULL_MESSAGE, requestHeader); switch (communicationMode) { - case ComMode_ONEWAY: - break; case ComMode_ASYNC: - pullMessageAsync(addr, request, timeoutMillis, pullCallback, pArg); - break; + pullMessageAsync(addr, request, timeoutMillis, pullCallback); + return nullptr; case ComMode_SYNC: return pullMessageSync(addr, request, timeoutMillis); default: - break; + assert(false); + return nullptr; } - - return NULL; } -void MQClientAPIImpl::pullMessageAsync(const string& addr, +void MQClientAPIImpl::pullMessageAsync(const std::string& addr, RemotingCommand& request, int timeoutMillis, - PullCallback* pullCallback, - void* pArg) { - //invokeAsync(addr, request, cbw, timeoutMillis) == false) { - LOG_ERROR("pullMessageAsync failed of addr:%s, mq:%s", addr.c_str(), - static_cast(pArg)->mq.toString().data()); - deleteAndZero(cbw); - THROW_MQEXCEPTION(MQClientException, "pullMessageAsync failed", -1); - } -} + PullCallback* pullCallback) { + // delete in future + auto* cbw = new PullCallbackWrap(pullCallback, this); -PullResult* MQClientAPIImpl::pullMessageSync(const string& addr, RemotingCommand& request, int timeoutMillis) { - unique_ptr 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(e.what()); - return NULL; - } - } + try { + m_remotingClient->invokeAsync(addr, request, cbw, timeoutMillis); + } catch (RemotingException& e) { + deleteAndZero(cbw); + throw e; } - 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); - } - LOG_ERROR("processSendResponse error remark:%s, error code:%d", (pResponse->getRemark()).c_str(), - pResponse->getCode()); - THROW_MQEXCEPTION(MQClientException, pResponse->getRemark(), pResponse->getCode()); +PullResult* MQClientAPIImpl::pullMessageSync(const std::string& addr, RemotingCommand& request, int timeoutMillis) { + std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + assert(response != nullptr); + return processPullResponse(response.get()); } -PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* pResponse) { +PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* response) { PullStatus pullStatus = NO_NEW_MSG; - switch (pResponse->getCode()) { + switch (response->getCode()) { case SUCCESS_VALUE: pullStatus = FOUND; break; @@ -558,375 +283,406 @@ PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* pResponse) { pullStatus = OFFSET_ILLEGAL; break; default: - THROW_MQEXCEPTION(MQBrokerException, pResponse->getRemark(), pResponse->getCode()); - break; + THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); } - PullMessageResponseHeader* responseHeader = static_cast(pResponse->getCommandHeader()); + // return of decodeCommandCustomHeader is non-null + auto* responseHeader = response->decodeCommandCustomHeader(); + assert(responseHeader != nullptr); - if (!responseHeader) { - LOG_ERROR("processPullResponse:responseHeader is NULL"); - THROW_MQEXCEPTION(MQClientException, "processPullResponse:responseHeader is NULL", -1); - } - //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); - } + return new PullResultExt(pullStatus, responseHeader->nextBeginOffset, responseHeader->minOffset, + responseHeader->maxOffset, (int)responseHeader->suggestWhichBrokerId, response->getBody()); } -//topic = topic; - pRequestHeader->queueId = queueId; - - RemotingCommand request(GET_MIN_OFFSET, pRequestHeader); - callSignatureBeforeRequest(addr, request, sessionCredentials); - request.Encode(); - - unique_ptr response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis)); +MQMessageExtPtr MQClientAPIImpl::viewMessage(const std::string& addr, int64_t phyoffset, int timeoutMillis) { + ViewMessageRequestHeader* requestHeader = new ViewMessageRequestHeader(); + requestHeader->offset = phyoffset; - if (response) { - switch (response->getCode()) { - case SUCCESS_VALUE: { - GetMinOffsetResponseHeader* responseHeader = (GetMinOffsetResponseHeader*)response->getCommandHeader(); + RemotingCommand request(VIEW_MESSAGE_BY_ID, requestHeader); - int64 offset = responseHeader->offset; - return offset; - } - default: - break; + std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + assert(response != nullptr); + switch (response->getCode()) { + case SUCCESS_VALUE: { + // TODO: ... } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + default: + break; } - THROW_MQEXCEPTION(MQBrokerException, "response is null", -1); + + THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); } -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; +int64_t MQClientAPIImpl::searchOffset(const std::string& addr, + const std::string& topic, + int queueId, + uint64_t timestamp, + int timeoutMillis) { + SearchOffsetRequestHeader* requestHeader = new SearchOffsetRequestHeader(); + requestHeader->topic = topic; + requestHeader->queueId = queueId; + requestHeader->timestamp = timestamp; - RemotingCommand request(GET_MAX_OFFSET, pRequestHeader); - callSignatureBeforeRequest(addr, request, sessionCredentials); - request.Encode(); + RemotingCommand request(SEARCH_OFFSET_BY_TIMESTAMP, requestHeader); - unique_ptr response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis)); + std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + assert(response != nullptr); + switch (response->getCode()) { + case SUCCESS_VALUE: { + auto* responseHeader = response->decodeCommandCustomHeader(); + assert(responseHeader != nullptr); + return responseHeader->offset; + } + default: + break; + } - if (response) { - switch (response->getCode()) { - case SUCCESS_VALUE: { - GetMaxOffsetResponseHeader* responseHeader = (GetMaxOffsetResponseHeader*)response->getCommandHeader(); + THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); +} - int64 offset = responseHeader->offset; - return offset; - } - default: - break; +int64_t MQClientAPIImpl::getMaxOffset(const std::string& addr, + const std::string& topic, + int queueId, + int timeoutMillis) { + GetMaxOffsetRequestHeader* requestHeader = new GetMaxOffsetRequestHeader(); + requestHeader->topic = topic; + requestHeader->queueId = queueId; + + RemotingCommand request(GET_MAX_OFFSET, requestHeader); + + std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + assert(response != nullptr); + switch (response->getCode()) { + case SUCCESS_VALUE: { + auto* responseHeader = response->decodeCommandCustomHeader(GET_MAX_OFFSET); + return responseHeader->offset; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + default: + break; } - THROW_MQEXCEPTION(MQBrokerException, "response is null", -1); + + THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); } -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; +int64_t MQClientAPIImpl::getMinOffset(const std::string& addr, + const std::string& topic, + int queueId, + int timeoutMillis) { + GetMinOffsetRequestHeader* requestHeader = new GetMinOffsetRequestHeader(); + requestHeader->topic = topic; + requestHeader->queueId = queueId; - RemotingCommand request(SEARCH_OFFSET_BY_TIMESTAMP, pRequestHeader); - callSignatureBeforeRequest(addr, request, sessionCredentials); - request.Encode(); + RemotingCommand request(GET_MIN_OFFSET, requestHeader); - unique_ptr response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis)); + std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + assert(response != nullptr); + switch (response->getCode()) { + case SUCCESS_VALUE: { + auto* responseHeader = response->decodeCommandCustomHeader(); + assert(responseHeader != nullptr); + return responseHeader->offset; + } + default: + break; + } - if (response) { - switch (response->getCode()) { - case SUCCESS_VALUE: { - SearchOffsetResponseHeader* responseHeader = (SearchOffsetResponseHeader*)response->getCommandHeader(); + THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); +} - int64 offset = responseHeader->offset; - return offset; - } - default: - break; +int64_t MQClientAPIImpl::getEarliestMsgStoretime(const std::string& addr, + const std::string& topic, + int queueId, + int timeoutMillis) { + GetEarliestMsgStoretimeRequestHeader* requestHeader = new GetEarliestMsgStoretimeRequestHeader(); + requestHeader->topic = topic; + requestHeader->queueId = queueId; + + RemotingCommand request(GET_EARLIEST_MSG_STORETIME, requestHeader); + + std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + assert(response != nullptr); + switch (response->getCode()) { + case SUCCESS_VALUE: { + auto* responseHeader = response->decodeCommandCustomHeader(); + assert(responseHeader != nullptr); + return responseHeader->timestamp; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + default: + break; } - 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; + THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); +} - RemotingCommand request(VIEW_MESSAGE_BY_ID, pRequestHeader); - callSignatureBeforeRequest(addr, request, sessionCredentials); - request.Encode(); +void MQClientAPIImpl::getConsumerIdListByGroup(const std::string& addr, + const std::string& consumerGroup, + std::vector& cids, + int timeoutMillis) { + GetConsumerListByGroupRequestHeader* requestHeader = new GetConsumerListByGroupRequestHeader(); + requestHeader->consumerGroup = consumerGroup; - unique_ptr response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis)); + RemotingCommand request(GET_CONSUMER_LIST_BY_GROUP, requestHeader); - if (response) { - switch (response->getCode()) { - case SUCCESS_VALUE: { + std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + assert(response != nullptr); + switch (response->getCode()) { + case SUCCESS_VALUE: { + auto responseBody = response->getBody(); + if (responseBody != nullptr && responseBody->getSize() > 0) { + std::unique_ptr body( + GetConsumerListByGroupResponseBody::Decode(*responseBody)); + cids = body->consumerIdList; + return; } - default: - break; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + default: + break; } - THROW_MQEXCEPTION(MQBrokerException, "response is null", -1); + + THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); } -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; +int64_t MQClientAPIImpl::queryConsumerOffset(const std::string& addr, + QueryConsumerOffsetRequestHeader* requestHeader, + int timeoutMillis) { + RemotingCommand request(QUERY_CONSUMER_OFFSET, requestHeader); - RemotingCommand request(GET_EARLIEST_MSG_STORETIME, pRequestHeader); - callSignatureBeforeRequest(addr, request, sessionCredentials); - request.Encode(); + std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + assert(response != nullptr); + switch (response->getCode()) { + case SUCCESS_VALUE: { + auto* responseHeader = response->decodeCommandCustomHeader(); + assert(responseHeader != nullptr); + return responseHeader->offset; + } + default: + break; + } - unique_ptr response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis)); + THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); +} - if (response) { - switch (response->getCode()) { - case SUCCESS_VALUE: { - GetEarliestMsgStoretimeResponseHeader* responseHeader = - (GetEarliestMsgStoretimeResponseHeader*)response->getCommandHeader(); +void MQClientAPIImpl::updateConsumerOffset(const std::string& addr, + UpdateConsumerOffsetRequestHeader* requestHeader, + int timeoutMillis) { + RemotingCommand request(UPDATE_CONSUMER_OFFSET, requestHeader); - 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& 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 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()); + std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + assert(response != nullptr); + switch (response->getCode()) { + case SUCCESS_VALUE: { + return; } + default: + break; } - THROW_MQEXCEPTION(MQBrokerException, "response is null", -1); + + THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); } -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(); +void MQClientAPIImpl::updateConsumerOffsetOneway(const std::string& addr, + UpdateConsumerOffsetRequestHeader* requestHeader, + int timeoutMillis) { + RemotingCommand request(UPDATE_CONSUMER_OFFSET, requestHeader); - unique_ptr response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis)); + m_remotingClient->invokeOneway(addr, request); +} - if (response) { - switch (response->getCode()) { - case SUCCESS_VALUE: { - QueryConsumerOffsetResponseHeader* responseHeader = - (QueryConsumerOffsetResponseHeader*)response->getCommandHeader(); - int64 consumerOffset = responseHeader->offset; - return consumerOffset; - } - default: - break; +void MQClientAPIImpl::sendHearbeat(const std::string& addr, HeartbeatData* heartbeatData) { + RemotingCommand request(HEART_BEAT, nullptr); + request.setBody(heartbeatData->encode()); + + std::unique_ptr response(m_remotingClient->invokeSync(addr, request)); + assert(response != nullptr); + switch (response->getCode()) { + case SUCCESS_VALUE: { + LOG_INFO("sendheartbeat to broker:%s success", addr.c_str()); + return; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + default: + break; } - 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(); + THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); +} - unique_ptr response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis)); +void MQClientAPIImpl::unregisterClient(const std::string& addr, + const std::string& clientID, + const std::string& producerGroup, + const std::string& consumerGroup) { + LOG_INFO("unregisterClient to broker:%s", addr.c_str()); + RemotingCommand request(UNREGISTER_CLIENT, new UnregisterClientRequestHeader(clientID, producerGroup, consumerGroup)); - if (response) { - switch (response->getCode()) { - case SUCCESS_VALUE: { - return; - } - default: - break; - } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + std::unique_ptr response(m_remotingClient->invokeSync(addr, request)); + assert(response != nullptr); + switch (response->getCode()) { + case SUCCESS_VALUE: + LOG_INFO("unregisterClient to:%s success", addr.c_str()); + return; + default: + break; } - THROW_MQEXCEPTION(MQBrokerException, "response is null", -1); + + LOG_WARN("unregisterClient fail:%s, %d", response->getRemark().c_str(), response->getCode()); + THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); } -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(); +void MQClientAPIImpl::endTransactionOneway(const std::string& addr, + EndTransactionRequestHeader* requestHeader, + const std::string& remark) { + RemotingCommand request(END_TRANSACTION, requestHeader); + request.setRemark(remark); - m_pRemotingClient->invokeOneway(addr, request); + m_remotingClient->invokeOneway(addr, request); } -void MQClientAPIImpl::consumerSendMessageBack(const string addr, +void MQClientAPIImpl::consumerSendMessageBack(const std::string& addr, MQMessageExt& msg, - const string& consumerGroup, + const std::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 response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis)); - - if (response) { - switch (response->getCode()) { - case SUCCESS_VALUE: { - return; - } - default: - break; + int maxConsumeRetryTimes) { + ConsumerSendMsgBackRequestHeader* requestHeader = new ConsumerSendMsgBackRequestHeader(); + requestHeader->group = consumerGroup; + requestHeader->originTopic = msg.getTopic(); + requestHeader->offset = msg.getCommitLogOffset(); + requestHeader->delayLevel = delayLevel; + requestHeader->originMsgId = msg.getMsgId(); + requestHeader->maxReconsumeTimes = maxConsumeRetryTimes; + + RemotingCommand request(CONSUMER_SEND_MSG_BACK, requestHeader); + + std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + assert(response != nullptr); + switch (response->getCode()) { + case SUCCESS_VALUE: { + return; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + default: + break; } - THROW_MQEXCEPTION(MQBrokerException, "response is null", -1); + + THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); } -void MQClientAPIImpl::lockBatchMQ(const string& addr, +void MQClientAPIImpl::lockBatchMQ(const std::string& addr, LockBatchRequestBody* requestBody, - vector& 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 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; + std::vector& mqs, + int timeoutMillis) { + RemotingCommand request(LOCK_BATCH_MQ, nullptr); + request.setBody(requestBody->encode()); + + std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + assert(response != nullptr); + switch (response->getCode()) { + case SUCCESS_VALUE: { + auto requestBody = response->getBody(); + if (requestBody != nullptr && requestBody->getSize() > 0) { + std::unique_ptr body(LockBatchResponseBody::Decode(*requestBody)); + mqs = body->getLockOKMQSet(); + } else { + mqs.clear(); } - THROW_MQEXCEPTION(MQBrokerException, pResponse->getRemark(), pResponse->getCode()); - } + return; + } break; + default: + break; } - THROW_MQEXCEPTION(MQBrokerException, "response is null", -1); + + THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); } -void MQClientAPIImpl::unlockBatchMQ(const string& addr, +void MQClientAPIImpl::unlockBatchMQ(const std::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 pResponse(m_pRemotingClient->invokeSync(addr, request, timeoutMillis)); - - if (pResponse != NULL) { - switch (pResponse->getCode()) { + bool oneway) { + RemotingCommand request(UNLOCK_BATCH_MQ, nullptr); + request.setBody(requestBody->encode()); + + if (oneway) { + m_remotingClient->invokeOneway(addr, request); + } else { + std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + assert(response != nullptr); + switch (response->getCode()) { case SUCCESS_VALUE: { return; } break; default: break; } - THROW_MQEXCEPTION(MQBrokerException, pResponse->getRemark(), pResponse->getCode()); + + THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); } - THROW_MQEXCEPTION(MQBrokerException, "response is null", -1); } -// response(m_remotingClient->invokeSync(null, request, timeoutMillis)); + assert(response != nullptr); + switch (response->getCode()) { + case TOPIC_NOT_EXIST: { + break; + } + case SUCCESS_VALUE: { + auto responseBody = response->getBody(); + if (responseBody != nullptr && responseBody->getSize() > 0) { + return TopicRouteData::Decode(*responseBody); + } + } + default: + break; + } + + THROW_MQEXCEPTION(MQClientException, response->getRemark(), response->getCode()); +} + +TopicList* MQClientAPIImpl::getTopicListFromNameServer() { + RemotingCommand request(GET_ALL_TOPIC_LIST_FROM_NAMESERVER, nullptr); + + std::unique_ptr response(m_remotingClient->invokeSync(null, request)); + assert(response != nullptr); + switch (response->getCode()) { + case SUCCESS_VALUE: { + auto responseBody = response->getBody(); + if (responseBody != nullptr && responseBody->getSize() > 0) { + return TopicList::Decode(*responseBody); + } + } + default: + break; + } + + THROW_MQEXCEPTION(MQClientException, response->getRemark(), response->getCode()); +} + +int MQClientAPIImpl::wipeWritePermOfBroker(const std::string& namesrvAddr, + const std::string& brokerName, + int timeoutMillis) { + return 0; +} + +void MQClientAPIImpl::deleteTopicInBroker(const std::string& addr, const std::string& topic, int timeoutMillis) {} + +void MQClientAPIImpl::deleteTopicInNameServer(const std::string& addr, const std::string& topic, int timeoutMillis) {} + +void MQClientAPIImpl::deleteSubscriptionGroup(const std::string& addr, + const std::string& groupName, + int timeoutMillis) {} + +std::string MQClientAPIImpl::getKVConfigByValue(const std::string& projectNamespace, + const std::string& projectGroup, + int timeoutMillis) { + return ""; +} + +void MQClientAPIImpl::deleteKVConfigByValue(const std::string& projectNamespace, + const std::string& projectGroup, + int timeoutMillis) {} + +KVTable MQClientAPIImpl::getKVListByNamespace(const std::string& projectNamespace, int timeoutMillis) { + return KVTable(); +} + } // namespace rocketmq diff --git a/src/MQClientAPIImpl.h b/src/MQClientAPIImpl.h index 3fbf566b7..0b3844798 100644 --- a/src/MQClientAPIImpl.h +++ b/src/MQClientAPIImpl.h @@ -14,217 +14,187 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef __MQ_CLIENT_API_IMPL_H__ +#define __MQ_CLIENT_API_IMPL_H__ -#ifndef __MQCLIENTAPIIMPL_H__ -#define __MQCLIENTAPIIMPL_H__ -#include "AsyncCallback.h" -#include "ClientRPCHook.h" -#include "ClientRemotingProcessor.h" #include "CommandHeader.h" +#include "CommunicationMode.h" +#include "DefaultMQProducerImpl.h" #include "HeartbeatData.h" #include "KVTable.h" #include "LockBatchBody.h" #include "MQClientException.h" +#include "MQClientInstance.h" #include "MQMessageExt.h" -#include "MQProtos.h" +#include "PullCallback.h" +#include "SendCallback.h" #include "SendResult.h" -#include "SocketUtil.h" -#include "TcpRemotingClient.h" -#include "TopAddressing.h" #include "TopicConfig.h" #include "TopicList.h" +#include "TopicPublishInfo.h" #include "TopicRouteData.h" -#include "UtilAll.h" -#include "VirtualEnvUtil.h" namespace rocketmq { -// rpcHook, + const MQClientConfig* clientConfig); 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& 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& 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); + + void start(); + void shutdown(); + + void updateNameServerAddr(const std::string& addrs); + + void createTopic(const std::string& addr, const std::string& defaultTopic, TopicConfig topicConfig); + + SendResult* sendMessage(const std::string& addr, + const std::string& brokerName, + const MQMessagePtr msg, + std::unique_ptr requestHeader, + int timeoutMillis, + CommunicationMode communicationMode, + DefaultMQProducerImplPtr producer); + SendResult* sendMessage(const std::string& addr, + const std::string& brokerName, + const MQMessagePtr msg, + std::unique_ptr requestHeader, + int timeoutMillis, + CommunicationMode communicationMode, + SendCallback* sendCallback, + TopicPublishInfoPtr topicPublishInfo, + MQClientInstancePtr instance, + int retryTimesWhenSendFailed, + DefaultMQProducerImplPtr producer); + SendResult* processSendResponse(const std::string& brokerName, const MQMessagePtr msg, RemotingCommand* pResponse); + + PullResult* pullMessage(const std::string& addr, + PullMessageRequestHeader* pRequestHeader, + int timeoutMillis, + CommunicationMode communicationMode, + PullCallback* pullCallback); + PullResult* processPullResponse(RemotingCommand* pResponse); + + MQMessageExtPtr viewMessage(const std::string& addr, int64_t phyoffset, int timeoutMillis); + + int64_t searchOffset(const std::string& addr, + const std::string& topic, + int queueId, + uint64_t timestamp, + int timeoutMillis); + + int64_t getMaxOffset(const std::string& addr, const std::string& topic, int queueId, int timeoutMillis); + int64_t getMinOffset(const std::string& addr, const std::string& topic, int queueId, int timeoutMillis); + + int64_t getEarliestMsgStoretime(const std::string& addr, const std::string& topic, int queueId, int timeoutMillis); + + void getConsumerIdListByGroup(const std::string& addr, + const std::string& consumerGroup, + std::vector& cids, + int timeoutMillis); + + int64_t queryConsumerOffset(const std::string& addr, + QueryConsumerOffsetRequestHeader* pRequestHeader, + int timeoutMillis); + + void updateConsumerOffset(const std::string& addr, + UpdateConsumerOffsetRequestHeader* pRequestHeader, + int timeoutMillis); + void updateConsumerOffsetOneway(const std::string& addr, + UpdateConsumerOffsetRequestHeader* pRequestHeader, + int timeoutMillis); + + void sendHearbeat(const std::string& addr, HeartbeatData* pHeartbeatData); + void unregisterClient(const std::string& addr, + const std::string& clientID, + const std::string& producerGroup, + const std::string& consumerGroup); + + void endTransactionOneway(const std::string& addr, + EndTransactionRequestHeader* requestHeader, + const std::string& remark); + + void consumerSendMessageBack(const std::string& addr, + MQMessageExt& msg, + const std::string& consumerGroup, + int delayLevel, + int timeoutMillis, + int maxConsumeRetryTimes); + + void lockBatchMQ(const std::string& addr, + LockBatchRequestBody* requestBody, + std::vector& mqs, + int timeoutMillis); + void unlockBatchMQ(const std::string& addr, + UnlockBatchRequestBody* requestBody, + int timeoutMillis, + bool oneway = false); + + TopicRouteData* getTopicRouteInfoFromNameServer(const std::string& topic, int timeoutMillis); + + TopicList* getTopicListFromNameServer(); + + int wipeWritePermOfBroker(const std::string& namesrvAddr, const std::string& brokerName, int timeoutMillis); + + void deleteTopicInBroker(const std::string& addr, const std::string& topic, int timeoutMillis); + void deleteTopicInNameServer(const std::string& addr, const std::string& topic, int timeoutMillis); + + void deleteSubscriptionGroup(const std::string& addr, const std::string& groupName, int timeoutMillis); + + std::string getKVConfigByValue(const std::string& projectNamespace, + const std::string& projectGroup, + int timeoutMillis); + void deleteKVConfigByValue(const std::string& projectNamespace, const std::string& projectGroup, int timeoutMillis); + + KVTable getKVListByNamespace(const std::string& projectNamespace, int timeoutMillis); + + public: + TcpRemotingClient* getRemotingClient() { return m_remotingClient.get(); } 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, + friend class SendCallbackWrap; + + SendResult* sendMessageSync(const std::string& addr, + const std::string& brokerName, + const MQMessagePtr msg, + RemotingCommand& request, + int timeoutMillis); + + void sendMessageAsync(const std::string& addr, + const std::string& brokerName, + const MQMessagePtr msg, + RemotingCommand&& request, + SendCallback* sendCallback, + TopicPublishInfoPtr topicPublishInfo, + MQClientInstancePtr instance, + int64_t timeoutMilliseconds, + int retryTimesWhenSendFailed, + DefaultMQProducerImplPtr producer) throw(RemotingException); + + void sendMessageAsyncImpl(SendCallbackWrap* cbw, int64_t timeoutMillis) throw(RemotingException); + + PullResult* pullMessageSync(const std::string& addr, RemotingCommand& request, int timeoutMillis); + + void pullMessageAsync(const std::string& addr, RemotingCommand& request, int timeoutMillis, - PullCallback* pullCallback, - void* pArg); - - protected: - unique_ptr m_pRemotingClient; + PullCallback* pullCallback); private: - unique_ptr m_topAddressing; - string m_nameSrvAddr; - bool m_firstFetchNameSrv; - string m_mqClientId; + std::unique_ptr m_remotingClient; + std::string m_nameSrvAddr; }; + } // namespace rocketmq -// +#include + +#include "NameSpaceUtil.h" +#include "UtilAll.h" + +namespace rocketmq { + +static const std::string DEFAULT_INSTANCE_NAME = "DEFAULT"; + +MQClientConfig::MQClientConfig() + : m_instanceName(DEFAULT_INSTANCE_NAME), + m_tcpWorkerThreadNum(std::min(4, (int)std::thread::hardware_concurrency())), + m_tcpConnectTimeout(3000), + m_tcpTransportTryLockTimeout(3) { + const char* addr = std::getenv(ROCKETMQ_NAMESRV_ADDR_ENV.c_str()); + if (addr != nullptr) { + m_namesrvAddr = addr; + } +} + +std::string MQClientConfig::buildMQClientId() const { + std::string clientId; + clientId.append(UtilAll::getLocalAddress()); // clientIP + clientId.append("@"); + clientId.append(m_instanceName); // processId + if (!m_unitName.empty()) { + clientId.append("@"); + clientId.append(m_unitName); // unitName + } + return clientId; +} + +const std::string& MQClientConfig::getGroupName() const { + return m_groupName; +} + +void MQClientConfig::setGroupName(const std::string& groupname) { + m_groupName = groupname; +} + +const std::string& MQClientConfig::getNamesrvAddr() const { + return m_namesrvAddr; +} + +void MQClientConfig::setNamesrvAddr(const std::string& namesrvAddr) { + m_namesrvAddr = NameSpaceUtil::formatNameServerURL(namesrvAddr); +} + +const std::string& MQClientConfig::getInstanceName() const { + return m_instanceName; +} + +void MQClientConfig::setInstanceName(const std::string& instanceName) { + m_instanceName = instanceName; +} + +void MQClientConfig::changeInstanceNameToPID() { + if (m_instanceName == DEFAULT_INSTANCE_NAME) { + m_instanceName = UtilAll::to_string(UtilAll::getProcessId()); + } +} + +int MQClientConfig::getTcpTransportWorkerThreadNum() const { + return m_tcpWorkerThreadNum; +} + +void MQClientConfig::setTcpTransportWorkerThreadNum(int num) { + if (num > m_tcpWorkerThreadNum) { + m_tcpWorkerThreadNum = num; + } +} + +uint64_t MQClientConfig::getTcpTransportConnectTimeout() const { + return m_tcpConnectTimeout; +} + +void MQClientConfig::setTcpTransportConnectTimeout(uint64_t timeout) { + m_tcpConnectTimeout = timeout; +} + +uint64_t MQClientConfig::getTcpTransportTryLockTimeout() const { + return m_tcpTransportTryLockTimeout; +} + +void MQClientConfig::setTcpTransportTryLockTimeout(uint64_t timeout) { + m_tcpTransportTryLockTimeout = std::max(1000, timeout) / 1000; +} + +const std::string& MQClientConfig::getUnitName() const { + return m_unitName; +} + +void MQClientConfig::setUnitName(std::string unitName) { + m_unitName = unitName; +} + +} // namespace rocketmq diff --git a/src/MQClientFactory.cpp b/src/MQClientFactory.cpp deleted file mode 100644 index 6e1a39224..000000000 --- a/src/MQClientFactory.cpp +++ /dev/null @@ -1,1211 +0,0 @@ -/* - * 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 "MQClientFactory.h" -#include "ConsumerRunningInfo.h" -#include "Logging.h" -#include "MQClientManager.h" -#include "MQVersion.h" -#include "PullRequest.h" -#include "Rebalance.h" -#include "TopicPublishInfo.h" -#include "TransactionMQProducer.h" - -#define MAX_BUFF_SIZE 8192 -#define SAFE_BUFF_SIZE 7936 // 8192 - 256 = 7936 -#define PROCESS_NAME_BUF_SIZE 256 - -namespace rocketmq { -// pDefaultTopicInfo(new TopicPublishInfo()); - m_topicPublishInfoTable[DEFAULT_TOPIC] = pDefaultTopicInfo; - m_pClientRemotingProcessor.reset(new ClientRemotingProcessor(this)); - m_pClientAPIImpl.reset(new MQClientAPIImpl(m_clientId, m_pClientRemotingProcessor.get(), pullThreadNum, - tcpConnectTimeout, tcpTransportTryLockTimeout, unitName)); - m_serviceState = CREATE_JUST; - LOG_DEBUG("MQClientFactory construct"); -} - -MQClientFactory::~MQClientFactory() { - LOG_INFO("MQClientFactory:%s destruct", m_clientId.c_str()); - - for (TRDMAP::iterator itp = m_topicRouteTable.begin(); itp != m_topicRouteTable.end(); ++itp) { - delete itp->second; - } - - m_producerTable.clear(); - m_consumerTable.clear(); - m_topicRouteTable.clear(); - m_brokerAddrTable.clear(); - m_topicPublishInfoTable.clear(); - - m_pClientAPIImpl = NULL; -} - -void MQClientFactory::start() { - switch (m_serviceState) { - case CREATE_JUST: - LOG_INFO("MQClientFactory:%s start", m_clientId.c_str()); - m_serviceState = START_FAILED; - // t) { - if ((getConsumerTableSize() == 0) && (getProducerTableSize() == 0)) { - return; - } - - set topicList; - //::iterator it = topicList.begin(); - for (; it != topicList.end(); ++it) { - updateTopicRouteInfoFromNameServer(*it, session_credentials); - } - } - - boost::system::error_code e; - t->expires_from_now(t->expires_from_now() + boost::posix_time::seconds(30), e); - t->async_wait(boost::bind(&MQClientFactory::updateTopicRouteInfo, this, ec, t)); -} - -TopicRouteData* MQClientFactory::getTopicRouteData(const string& topic) { - boost::lock_guard lock(m_topicRouteTableMutex); - if (m_topicRouteTable.find(topic) != m_topicRouteTable.end()) { - return m_topicRouteTable[topic]; - } - return NULL; -} - -void MQClientFactory::addTopicRouteData(const string& topic, TopicRouteData* pTopicRouteData) { - boost::lock_guard lock(m_topicRouteTableMutex); - if (m_topicRouteTable.find(topic) != m_topicRouteTable.end()) { - delete m_topicRouteTable[topic]; - m_topicRouteTable.erase(topic); - } - m_topicRouteTable[topic] = pTopicRouteData; -} - -boost::shared_ptr MQClientFactory::tryToFindTopicPublishInfo( - const string& topic, - const SessionCredentials& session_credentials) { - boost::lock_guard lock(m_topicPublishInfoLock); // add topicPublishInfoLock to avoid con-current - // excuting updateTopicRouteInfoFromNameServer - // when producer send msg before topicRouteInfo - // was got; - if (!isTopicInfoValidInTable(topic)) { - updateTopicRouteInfoFromNameServer(topic, session_credentials); - } - // pTopicPublishInfo; - return pTopicPublishInfo; - } - - return getTopicPublishInfoFromTable(topic); -} - -bool MQClientFactory::updateTopicRouteInfoFromNameServer(const string& topic, - const SessionCredentials& session_credentials, - bool isDefault /* = false */) { - boost::lock_guard lock(m_factoryLock); - unique_ptr pTopicRouteData; - LOG_DEBUG("updateTopicRouteInfoFromNameServer start. Topic:%s", topic.c_str()); - - if (isDefault) { - pTopicRouteData.reset( - m_pClientAPIImpl->getTopicRouteInfoFromNameServer(DEFAULT_TOPIC, 1000 * 5, session_credentials)); - if (pTopicRouteData != NULL) { - vector& queueDatas = pTopicRouteData->getQueueDatas(); - vector::iterator it = queueDatas.begin(); - for (; it != queueDatas.end(); ++it) { - int queueNums = std::min(4, it->readQueueNums); - it->readQueueNums = queueNums; - it->writeQueueNums = queueNums; - } - } - LOG_DEBUG("getTopicRouteInfoFromNameServer is null for topic :%s", topic.c_str()); - } else { - pTopicRouteData.reset(m_pClientAPIImpl->getTopicRouteInfoFromNameServer(topic, 1000 * 5, session_credentials)); - } - - if (pTopicRouteData != NULL) { - LOG_DEBUG("updateTopicRouteInfoFromNameServer has data"); - TopicRouteData* pTemp = getTopicRouteData(topic); - bool changed = true; - if (pTemp != NULL) { - changed = !(*pTemp == *pTopicRouteData); - } - - if (getConsumerTableSize() > 0) { - vector mqs; - topicRouteData2TopicSubscribeInfo(topic, pTopicRouteData.get(), mqs); - updateConsumerSubscribeTopicInfo(topic, mqs); - } - - if (changed) { - // brokerList = pTopicRouteData->getBrokerDatas(); - vector::iterator it = brokerList.begin(); - for (; it != brokerList.end(); ++it) { - LOG_INFO("updateTopicRouteInfoFromNameServer changed with broker name:%s", (*it).brokerName.c_str()); - addBrokerToAddrMap((*it).brokerName, (*it).brokerAddrs); - } - - // publishInfo(topicRouteData2TopicPublishInfo(topic, pTopicRouteData.get())); - addTopicInfoToTable(topic, publishInfo); // erase first, then add - } - - // MQClientFactory::topicRouteData2TopicPublishInfo(const string& topic, - TopicRouteData* pRoute) { - boost::shared_ptr info(new TopicPublishInfo()); - string OrderTopicConf = pRoute->getOrderTopicConf(); - // brokers; - UtilAll::Split(brokers, OrderTopicConf, ';'); - for (size_t i = 0; i < brokers.size(); i++) { - vector item; - UtilAll::Split(item, brokers[i], ':'); - int nums = atoi(item[1].c_str()); - for (int i = 0; i < nums; i++) { - MQMessageQueue mq(topic, item[0], i); - info->updateMessageQueueList(mq); - } - } - } - //& queueDatas = pRoute->getQueueDatas(); - vector::iterator it = queueDatas.begin(); - for (; it != queueDatas.end(); ++it) { - QueueData& qd = (*it); - if (PermName::isWriteable(qd.perm)) { - string addr = findBrokerAddressInPublish(qd.brokerName); - if (addr.empty()) { - continue; - } - for (int i = 0; i < qd.writeQueueNums; i++) { - MQMessageQueue mq(topic, qd.brokerName, i); - info->updateMessageQueueList(mq); - } - } - } - } - return info; -} - -void MQClientFactory::topicRouteData2TopicSubscribeInfo(const string& topic, - TopicRouteData* pRoute, - vector& mqs) { - mqs.clear(); - vector& queueDatas = pRoute->getQueueDatas(); - vector::iterator it = queueDatas.begin(); - for (; it != queueDatas.end(); ++it) { - QueueData& qd = (*it); - if (PermName::isReadable(qd.perm)) { - for (int i = 0; i < qd.readQueueNums; i++) { - MQMessageQueue mq(topic, qd.brokerName, i); - mqs.push_back(mq); - } - } - } -} - -void MQClientFactory::shutdown() { - if (getConsumerTableSize() != 0) - return; - - if (getProducerTableSize() != 0) - return; - - switch (m_serviceState) { - case RUNNING: { - if (m_consumer_async_service_thread) { - m_consumer_async_ioService.stop(); - m_consumer_async_service_thread->interrupt(); - m_consumer_async_service_thread->join(); - } - m_async_ioService.stop(); - m_async_service_thread->interrupt(); - m_async_service_thread->join(); - m_pClientAPIImpl->stopAllTcpTransportThread(); // Note: stop all - // TcpTransport Threads - // and release all - // responseFuture - // conditions - m_serviceState = SHUTDOWN_ALREADY; - LOG_INFO("MQClientFactory:%s shutdown", m_clientId.c_str()); - break; - } - case SHUTDOWN_ALREADY: - case CREATE_JUST: - break; - default: - break; - } - - MQClientManager::getInstance()->removeClientFactory(m_clientId); -} - -bool MQClientFactory::registerProducer(MQProducer* pProducer) { - string groupName = pProducer->getGroupName(); - string namesrvaddr = pProducer->getNamesrvAddr(); - if (groupName.empty()) { - return false; - } - - if (!addProducerToTable(groupName, pProducer)) { - return false; - } - - LOG_DEBUG("registerProducer success:%s", groupName.c_str()); - //getNamesrvDomain()); - if (!nameSrvDomain.empty()) - m_nameSrvDomain = nameSrvDomain; - pProducer->setNamesrvAddr(m_pClientAPIImpl->fetchNameServerAddr(m_nameSrvDomain)); - } else { - m_bFetchNSService = false; - m_pClientAPIImpl->updateNameServerAddr(namesrvaddr); - LOG_INFO("user specfied name server address: %s", namesrvaddr.c_str()); - } - return true; -} - -void MQClientFactory::unregisterProducer(MQProducer* pProducer) { - string groupName = pProducer->getGroupName(); - unregisterClient(groupName, "", pProducer->getSessionCredentials()); - - eraseProducerFromTable(groupName); -} - -bool MQClientFactory::registerConsumer(MQConsumer* pConsumer) { - string groupName = pConsumer->getGroupName(); - string namesrvaddr = pConsumer->getNamesrvAddr(); - if (groupName.empty()) { - return false; - } - - if (!addConsumerToTable(groupName, pConsumer)) { - return false; - } - LOG_DEBUG("registerConsumer success:%s", groupName.c_str()); - //getNamesrvDomain()); - if (!nameSrvDomain.empty()) - m_nameSrvDomain = nameSrvDomain; - pConsumer->setNamesrvAddr(m_pClientAPIImpl->fetchNameServerAddr(m_nameSrvDomain)); - } else { - m_bFetchNSService = false; - m_pClientAPIImpl->updateNameServerAddr(namesrvaddr); - LOG_INFO("user specfied name server address: %s", namesrvaddr.c_str()); - } - - return true; -} - -void MQClientFactory::unregisterConsumer(MQConsumer* pConsumer) { - string groupName = pConsumer->getGroupName(); - unregisterClient("", groupName, pConsumer->getSessionCredentials()); - - eraseConsumerFromTable(groupName); -} - -MQProducer* MQClientFactory::selectProducer(const string& producerName) { - boost::lock_guard lock(m_producerTableMutex); - if (m_producerTable.find(producerName) != m_producerTable.end()) { - return m_producerTable[producerName]; - } - return NULL; -} - -bool MQClientFactory::getSessionCredentialFromProducerTable(SessionCredentials& sessionCredentials) { - boost::lock_guard lock(m_producerTableMutex); - for (MQPMAP::iterator it = m_producerTable.begin(); it != m_producerTable.end(); ++it) { - if (it->second) - sessionCredentials = it->second->getSessionCredentials(); - } - - if (sessionCredentials.isValid()) - return true; - - return false; -} - -bool MQClientFactory::addProducerToTable(const string& producerName, MQProducer* pMQProducer) { - boost::lock_guard lock(m_producerTableMutex); - if (m_producerTable.find(producerName) != m_producerTable.end()) - return false; - m_producerTable[producerName] = pMQProducer; - return true; -} - -void MQClientFactory::eraseProducerFromTable(const string& producerName) { - boost::lock_guard lock(m_producerTableMutex); - if (m_producerTable.find(producerName) != m_producerTable.end()) - m_producerTable.erase(producerName); -} - -int MQClientFactory::getProducerTableSize() { - boost::lock_guard lock(m_producerTableMutex); - return m_producerTable.size(); -} - -void MQClientFactory::insertProducerInfoToHeartBeatData(HeartbeatData* pHeartbeatData) { - boost::lock_guard lock(m_producerTableMutex); - for (MQPMAP::iterator it = m_producerTable.begin(); it != m_producerTable.end(); ++it) { - ProducerData producerData; - producerData.groupName = it->first; - pHeartbeatData->insertDataToProducerDataSet(producerData); - } -} - -MQConsumer* MQClientFactory::selectConsumer(const string& group) { - boost::lock_guard lock(m_consumerTableMutex); - if (m_consumerTable.find(group) != m_consumerTable.end()) { - return m_consumerTable[group]; - } - return NULL; -} - -bool MQClientFactory::getSessionCredentialFromConsumerTable(SessionCredentials& sessionCredentials) { - boost::lock_guard lock(m_consumerTableMutex); - for (MQCMAP::iterator it = m_consumerTable.begin(); it != m_consumerTable.end(); ++it) { - if (it->second) - sessionCredentials = it->second->getSessionCredentials(); - } - - if (sessionCredentials.isValid()) - return true; - - return false; -} - -bool MQClientFactory::getSessionCredentialFromConsumer(const string& consumerGroup, - SessionCredentials& sessionCredentials) { - boost::lock_guard lock(m_consumerTableMutex); - if (m_consumerTable.find(consumerGroup) != m_consumerTable.end()) { - sessionCredentials = m_consumerTable[consumerGroup]->getSessionCredentials(); - } - - if (sessionCredentials.isValid()) - return true; - - return false; -} - -bool MQClientFactory::addConsumerToTable(const string& consumerName, MQConsumer* pMQConsumer) { - boost::lock_guard lock(m_consumerTableMutex); - if (m_consumerTable.find(consumerName) != m_consumerTable.end()) - return false; - m_consumerTable[consumerName] = pMQConsumer; - return true; -} - -void MQClientFactory::eraseConsumerFromTable(const string& consumerName) { - boost::lock_guard lock(m_consumerTableMutex); - if (m_consumerTable.find(consumerName) != m_consumerTable.end()) - m_consumerTable.erase(consumerName); // do not need freee pConsumer, as it - // was allocated by user - else - LOG_WARN("could not find consumer:%s from table", consumerName.c_str()); -} - -int MQClientFactory::getConsumerTableSize() { - boost::lock_guard lock(m_consumerTableMutex); - return m_consumerTable.size(); -} - -void MQClientFactory::getTopicListFromConsumerSubscription(set& topicList) { - boost::lock_guard lock(m_consumerTableMutex); - for (MQCMAP::iterator it = m_consumerTable.begin(); it != m_consumerTable.end(); ++it) { - vector result; - it->second->getSubscriptions(result); - - vector::iterator iter = result.begin(); - for (; iter != result.end(); ++iter) { - topicList.insert((*iter).getTopic()); - } - } -} - -void MQClientFactory::updateConsumerSubscribeTopicInfo(const string& topic, vector mqs) { - boost::lock_guard lock(m_consumerTableMutex); - for (MQCMAP::iterator it = m_consumerTable.begin(); it != m_consumerTable.end(); ++it) { - it->second->updateTopicSubscribeInfo(topic, mqs); - } -} - -void MQClientFactory::insertConsumerInfoToHeartBeatData(HeartbeatData* pHeartbeatData) { - boost::lock_guard lock(m_consumerTableMutex); - for (MQCMAP::iterator it = m_consumerTable.begin(); it != m_consumerTable.end(); ++it) { - MQConsumer* pConsumer = it->second; - ConsumerData consumerData; - consumerData.groupName = pConsumer->getGroupName(); - consumerData.consumeType = pConsumer->getConsumeType(); - consumerData.messageModel = pConsumer->getMessageModel(); - consumerData.consumeFromWhere = pConsumer->getConsumeFromWhere(); - - // result; - pConsumer->getSubscriptions(result); - consumerData.subscriptionDataSet.swap(result); - - pHeartbeatData->insertDataToConsumerDataSet(consumerData); - } -} - -void MQClientFactory::addTopicInfoToTable(const string& topic, boost::shared_ptr pTopicPublishInfo) { - boost::lock_guard lock(m_topicPublishInfoTableMutex); - if (m_topicPublishInfoTable.find(topic) != m_topicPublishInfoTable.end()) { - m_topicPublishInfoTable.erase(topic); - } - m_topicPublishInfoTable[topic] = pTopicPublishInfo; -} - -void MQClientFactory::eraseTopicInfoFromTable(const string& topic) { - boost::lock_guard lock(m_topicPublishInfoTableMutex); - if (m_topicPublishInfoTable.find(topic) != m_topicPublishInfoTable.end()) { - m_topicPublishInfoTable.erase(topic); - } -} - -bool MQClientFactory::isTopicInfoValidInTable(const string& topic) { - boost::lock_guard lock(m_topicPublishInfoTableMutex); - if (m_topicPublishInfoTable.find(topic) != m_topicPublishInfoTable.end()) { - if (m_topicPublishInfoTable[topic]->ok()) - return true; - } - return false; -} - -boost::shared_ptr MQClientFactory::getTopicPublishInfoFromTable(const string& topic) { - boost::lock_guard lock(m_topicPublishInfoTableMutex); - if (m_topicPublishInfoTable.find(topic) != m_topicPublishInfoTable.end()) { - return m_topicPublishInfoTable[topic]; - } - boost::shared_ptr pTopicPublishInfo; - return pTopicPublishInfo; -} - -void MQClientFactory::getTopicListFromTopicPublishInfo(set& topicList) { - boost::lock_guard lock(m_topicPublishInfoTableMutex); - for (TPMap::iterator itp = m_topicPublishInfoTable.begin(); itp != m_topicPublishInfoTable.end(); ++itp) { - topicList.insert(itp->first); - } -} - -void MQClientFactory::clearBrokerAddrMap() { - boost::lock_guard lock(m_brokerAddrlock); - m_brokerAddrTable.clear(); -} - -bool MQClientFactory::isBrokerAddressInUse(const std::string& address) { - if (m_topicRouteTableMutex.try_lock()) { - boost::lock_guard lk(m_topicRouteTableMutex, boost::adopt_lock_t()); - for (TRDMAP::iterator it = m_topicRouteTable.begin(); it != m_topicRouteTable.end(); it++) { - TopicRouteData* topicRouteData = it->second; - vector& brokerData = topicRouteData->getBrokerDatas(); - for (vector::iterator next = brokerData.begin(); next != brokerData.end(); next++) { - map& brokerAddresses = next->brokerAddrs; - for (map::iterator entry = brokerAddresses.begin(); entry != brokerAddresses.end(); entry++) { - if (address == entry->second) { - return true; - } - } - } - } - return false; - } else { - LOG_WARN("Cannot lock m_topicRouteTableMutex. Assume %s is still in use", address.c_str()); - return true; - } -} -void MQClientFactory::addBrokerToAddrMap(const string& brokerName, map& brokerAddrs) { - boost::lock_guard lock(m_brokerAddrlock); - if (m_brokerAddrTable.find(brokerName) != m_brokerAddrTable.end()) { - m_brokerAddrTable.erase(brokerName); - } - m_brokerAddrTable[brokerName] = brokerAddrs; -} - -MQClientFactory::BrokerAddrMAP MQClientFactory::getBrokerAddrMap() { - boost::lock_guard lock(m_brokerAddrlock); - return m_brokerAddrTable; -} - -string MQClientFactory::findBrokerAddressInPublish(const string& brokerName) { - /*reslove the concurrent access m_brokerAddrTable by - findBrokerAddressInPublish(called by sendKernlImpl) And - sendHeartbeatToAllBroker, which leads hign RT of sendMsg - 1. change m_brokerAddrTable from hashMap to map; - 2. do not add m_factoryLock here, but copy m_brokerAddrTable, - this is used to avoid con-current access m_factoryLock by - findBrokerAddressInPublish(called by sendKernlImpl) And - updateTopicRouteInfoFromNameServer - - Note: after copying m_brokerAddrTable, updateTopicRouteInfoFromNameServer - modify m_brokerAddrTable imediatly, - after 1st send fail, producer will get topicPushlibshInfo again - before next try, so 2nd try will get correct broker to send ms; - */ - BrokerAddrMAP brokerTable(getBrokerAddrMap()); - string brokerAddr; - bool found = false; - - if (brokerTable.find(brokerName) != brokerTable.end()) { - map brokerMap(brokerTable[brokerName]); - map::iterator it1 = brokerMap.find(MASTER_ID); - if (it1 != brokerMap.end()) { - brokerAddr = it1->second; - found = true; - } - } - - brokerTable.clear(); - if (found) - return brokerAddr; - - return ""; -} - -FindBrokerResult* MQClientFactory::findBrokerAddressInSubscribe(const string& brokerName, - int brokerId, - bool onlyThisBroker) { - string brokerAddr; - bool slave = false; - bool found = false; - BrokerAddrMAP brokerTable(getBrokerAddrMap()); - - if (brokerTable.find(brokerName) != brokerTable.end()) { - map brokerMap(brokerTable[brokerName]); - if (!brokerMap.empty()) { - auto iter = brokerMap.find(brokerId); - if (iter != brokerMap.end()) { - brokerAddr = iter->second; - slave = (brokerId != MASTER_ID); - found = true; - } else if (!onlyThisBroker) { // not only from master - iter = brokerMap.begin(); - brokerAddr = iter->second; - slave = iter->first != MASTER_ID; - found = true; - } - } - } - - brokerTable.clear(); - - if (found) { - return new FindBrokerResult(brokerAddr, slave); - } - - return nullptr; -} - -FindBrokerResult* MQClientFactory::findBrokerAddressInAdmin(const string& brokerName) { - BrokerAddrMAP brokerTable(getBrokerAddrMap()); - bool found = false; - bool slave = false; - string brokerAddr; - - if (brokerTable.find(brokerName) != brokerTable.end()) { - map brokerMap(brokerTable[brokerName]); - map::iterator it1 = brokerMap.begin(); - if (it1 != brokerMap.end()) { - slave = (it1->first != MASTER_ID); - found = true; - brokerAddr = it1->second; - } - } - - brokerTable.clear(); - if (found) - return new FindBrokerResult(brokerAddr, slave); - - return NULL; -} - -void MQClientFactory::checkTransactionState(const std::string& addr, - const MQMessageExt& messageExt, - const CheckTransactionStateRequestHeader& checkRequestHeader) { - string group = messageExt.getProperty(MQMessage::PROPERTY_PRODUCER_GROUP); - if (!group.empty()) { - MQProducer* producer = selectProducer(group); - if (producer != nullptr) { - TransactionMQProducer* transProducer = dynamic_cast(producer); - if (transProducer != nullptr) { - transProducer->checkTransactionState(addr, messageExt, checkRequestHeader.m_tranStateTableOffset, - checkRequestHeader.m_commitLogOffset, checkRequestHeader.m_msgId, - checkRequestHeader.m_transactionId, checkRequestHeader.m_offsetMsgId); - } else { - LOG_ERROR("checkTransactionState, producer not TransactionMQProducer failed, msg:%s", - messageExt.toString().data()); - } - } else { - LOG_ERROR("checkTransactionState, pick producer by group[%s] failed, msg:%s", group.data(), - messageExt.toString().data()); - } - } else { - LOG_ERROR("checkTransactionState, pick producer group failed, msg:%s", messageExt.toString().data()); - } -} - -MQClientAPIImpl* MQClientFactory::getMQClientAPIImpl() const { - return m_pClientAPIImpl.get(); -} - -void MQClientFactory::cleanOfflineBrokers() { - LOG_DEBUG("Begin to clean offline brokers"); - boost::lock_guard lock(m_brokerAddrlock); - - for (BrokerAddrMAP::iterator it = m_brokerAddrTable.begin(); it != m_brokerAddrTable.end();) { - std::string brokerName = it->first; - map brokerIdAddressMap = it->second; - - for (map::iterator next = brokerIdAddressMap.begin(); next != brokerIdAddressMap.end();) { - if (!isBrokerAddressInUse(next->second)) { - LOG_INFO("Remove broker address: %s", (next->second).c_str()); - brokerIdAddressMap.erase(next++); - } else { - next++; - } - } - - if (brokerIdAddressMap.empty()) { - m_brokerAddrTable.erase(it++); - LOG_INFO("Broker name: %s is purged from client", brokerName.c_str()); - } else { - LOG_DEBUG("Broker: %s is alive", brokerName.c_str()); - it++; - } - } - - LOG_DEBUG("Exit of cleaning offline brokers"); -} - -void MQClientFactory::sendHeartbeatToAllBroker() { - BrokerAddrMAP brokerTable(getBrokerAddrMap()); - if (brokerTable.size() == 0) { - LOG_WARN("sendheartbeat brokeradd is empty"); - return; - } - - unique_ptr heartbeatData(prepareHeartbeatData()); - bool producerEmpty = heartbeatData->isProducerDataSetEmpty(); - bool consumerEmpty = heartbeatData->isConsumerDataSetEmpty(); - if (producerEmpty && consumerEmpty) { - LOG_WARN("sendheartbeat heartbeatData empty"); - brokerTable.clear(); - return; - } - - SessionCredentials session_credentials; - getSessionCredentialsFromOneOfProducerOrConsumer(session_credentials); - for (BrokerAddrMAP::iterator it = brokerTable.begin(); it != brokerTable.end(); ++it) { - map brokerMap(it->second); - map::iterator it1 = brokerMap.begin(); - for (; it1 != brokerMap.end(); ++it1) { - string& addr = it1->second; - if (consumerEmpty && it1->first != MASTER_ID) - continue; - - try { - m_pClientAPIImpl->sendHeartbeat(addr, heartbeatData.get(), session_credentials); - } catch (MQException& e) { - LOG_ERROR(e.what()); - } - } - } - brokerTable.clear(); -} - -void MQClientFactory::persistAllConsumerOffset(boost::system::error_code& ec, - boost::shared_ptr t) { - { - boost::lock_guard lock(m_consumerTableMutex); - if (m_consumerTable.size() > 0) { - for (MQCMAP::iterator it = m_consumerTable.begin(); it != m_consumerTable.end(); ++it) { - LOG_DEBUG("Client factory start persistAllConsumerOffset"); - it->second->persistConsumerOffset(); - } - } - } - - boost::system::error_code e; - t->expires_from_now(t->expires_from_now() + boost::posix_time::seconds(5), e); - t->async_wait(boost::bind(&MQClientFactory::persistAllConsumerOffset, this, ec, t)); -} - -HeartbeatData* MQClientFactory::prepareHeartbeatData() { - HeartbeatData* pHeartbeatData = new HeartbeatData(); - // clientID - pHeartbeatData->setClientID(m_clientId); - - // Consumer - insertConsumerInfoToHeartBeatData(pHeartbeatData); - - // Producer - insertProducerInfoToHeartBeatData(pHeartbeatData); - - return pHeartbeatData; -} - -void MQClientFactory::timerCB_sendHeartbeatToAllBroker(boost::system::error_code& ec, - boost::shared_ptr t) { - sendHeartbeatToAllBroker(); - - boost::system::error_code e; - t->expires_from_now(t->expires_from_now() + boost::posix_time::seconds(30), e); - t->async_wait(boost::bind(&MQClientFactory::timerCB_sendHeartbeatToAllBroker, this, ec, t)); -} - -void MQClientFactory::timerCB_cleanOfflineBrokers(boost::system::error_code& ec, - boost::shared_ptr t) { - cleanOfflineBrokers(); - - boost::system::error_code e; - t->expires_from_now(t->expires_from_now() + boost::posix_time::seconds(30), e); - t->async_wait(boost::bind(&MQClientFactory::timerCB_cleanOfflineBrokers, this, ec, t)); -} - -void MQClientFactory::fetchNameServerAddr(boost::system::error_code& ec, - boost::shared_ptr t) { - m_pClientAPIImpl->fetchNameServerAddr(m_nameSrvDomain); - - boost::system::error_code e; - t->expires_from_now(t->expires_from_now() + boost::posix_time::seconds(60 * 2), e); - t->async_wait(boost::bind(&MQClientFactory::fetchNameServerAddr, this, ec, t)); -} - -void MQClientFactory::startScheduledTask(bool startFetchNSService) { - boost::asio::io_service::work work(m_async_ioService); // avoid async io - // service stops after - // first timer timeout - // callback - - boost::system::error_code ec1; - boost::shared_ptr t1 = - boost::make_shared(m_async_ioService, boost::posix_time::seconds(3)); - t1->async_wait(boost::bind(&MQClientFactory::updateTopicRouteInfo, this, ec1, t1)); - - boost::system::error_code ec2; - boost::shared_ptr t2 = - boost::make_shared(m_async_ioService, boost::posix_time::milliseconds(10)); - t2->async_wait(boost::bind(&MQClientFactory::timerCB_sendHeartbeatToAllBroker, this, ec2, t2)); - - boost::system::error_code ec3; - boost::shared_ptr t3 = - boost::make_shared(m_async_ioService, boost::posix_time::seconds(3)); - t3->async_wait(boost::bind(&MQClientFactory::timerCB_cleanOfflineBrokers, this, ec3, t3)); - - if (startFetchNSService) { - boost::system::error_code ec5; - boost::shared_ptr t5 = - boost::make_shared(m_async_ioService, boost::posix_time::seconds(60 * 2)); - t5->async_wait(boost::bind(&MQClientFactory::fetchNameServerAddr, this, ec5, t5)); - } - - LOG_INFO("start scheduled task:%s", m_clientId.c_str()); - boost::system::error_code ec; - m_async_ioService.run(ec); -} - -void MQClientFactory::rebalanceImmediately() { - // m_consumer_async_service_thread will be only started once for all consumer - if (m_consumer_async_service_thread == NULL) { - doRebalance(); - m_consumer_async_service_thread.reset( - new boost::thread(boost::bind(&MQClientFactory::consumer_timerOperation, this))); - } -} - -void MQClientFactory::consumer_timerOperation() { - LOG_INFO("clientFactory:%s start consumer_timerOperation", m_clientId.c_str()); - boost::asio::io_service::work work(m_consumer_async_ioService); // avoid async io - // service stops after - // first timer timeout - // callback - - boost::system::error_code ec1; - boost::shared_ptr t1 = - boost::make_shared(m_consumer_async_ioService, boost::posix_time::seconds(10)); - t1->async_wait(boost::bind(&MQClientFactory::timerCB_doRebalance, this, ec1, t1)); - - boost::system::error_code ec2; - boost::shared_ptr t2 = - boost::make_shared(m_consumer_async_ioService, boost::posix_time::seconds(5)); - t2->async_wait(boost::bind(&MQClientFactory::persistAllConsumerOffset, this, ec2, t2)); - - boost::system::error_code ec; - m_consumer_async_ioService.run(ec); - LOG_INFO("clientFactory:%s stop consumer_timerOperation", m_clientId.c_str()); -} - -void MQClientFactory::timerCB_doRebalance(boost::system::error_code& ec, - boost::shared_ptr t) { - doRebalance(); - - boost::system::error_code e; - t->expires_from_now(t->expires_from_now() + boost::posix_time::seconds(10), e); - t->async_wait(boost::bind(&MQClientFactory::timerCB_doRebalance, this, ec, t)); -} - -void MQClientFactory::doRebalance() { - LOG_DEBUG("Client factory:%s start doRebalance", m_clientId.c_str()); - if (getConsumerTableSize() > 0) { - boost::lock_guard lock(m_consumerTableMutex); - for (MQCMAP::iterator it = m_consumerTable.begin(); it != m_consumerTable.end(); ++it) { - it->second->doRebalance(); - } - } - LOG_DEBUG("Client factory:%s finish doRebalance", m_clientId.c_str()); -} - -void MQClientFactory::doRebalanceByConsumerGroup(const string& consumerGroup) { - boost::lock_guard lock(m_consumerTableMutex); - if (m_consumerTable.find(consumerGroup) != m_consumerTable.end()) { - LOG_INFO("Client factory:%s start dorebalance for consumer:%s", m_clientId.c_str(), consumerGroup.c_str()); - MQConsumer* pMQConsumer = m_consumerTable[consumerGroup]; - pMQConsumer->doRebalance(); - } -} - -void MQClientFactory::endTransactionOneway(const MQMessageQueue& mq, - EndTransactionRequestHeader* requestHeader, - const SessionCredentials& sessionCredentials) { - string brokerAddr = findBrokerAddressInPublish(mq.getBrokerName()); - string remark = ""; - if (!brokerAddr.empty()) { - try { - getMQClientAPIImpl()->endTransactionOneway(brokerAddr, requestHeader, remark, sessionCredentials); - } catch (MQException& e) { - LOG_ERROR("endTransactionOneway exception:%s", e.what()); - throw e; - } - } else { - THROW_MQEXCEPTION(MQClientException, "The broker[" + mq.getBrokerName() + "] not exist", -1); - } -} - -void MQClientFactory::unregisterClient(const string& producerGroup, - const string& consumerGroup, - const SessionCredentials& sessionCredentials) { - BrokerAddrMAP brokerTable(getBrokerAddrMap()); - for (BrokerAddrMAP::iterator it = brokerTable.begin(); it != brokerTable.end(); ++it) { - map brokerMap(it->second); - map::iterator it1 = brokerMap.begin(); - for (; it1 != brokerMap.end(); ++it1) { - string& addr = it1->second; - m_pClientAPIImpl->unregisterClient(addr, m_clientId, producerGroup, consumerGroup, sessionCredentials); - } - } -} - -//& mqs, - const SessionCredentials& sessionCredentials) { - TopicRouteData* pTopicRouteData = getTopicRouteData(topic); - if (pTopicRouteData == NULL) { - updateTopicRouteInfoFromNameServer(topic, sessionCredentials); - pTopicRouteData = getTopicRouteData(topic); - } - if (pTopicRouteData != NULL) { - topicRouteData2TopicSubscribeInfo(topic, pTopicRouteData, mqs); - if (mqs.empty()) { - THROW_MQEXCEPTION(MQClientException, "Can not find Message Queue", -1); - } - return; - } - THROW_MQEXCEPTION(MQClientException, "Can not find Message Queue", -1); -} - -//getMinOffset(brokerAddr, mq.getTopic(), mq.getQueueId(), 1000 * 3, sessionCredentials); - } catch (MQException& e) { - LOG_ERROR(e.what()); - } - } - THROW_MQEXCEPTION(MQClientException, "The broker is not exist", -1); -} - -int64 MQClientFactory::maxOffset(const MQMessageQueue& mq, const SessionCredentials& sessionCredentials) { - string brokerAddr = findBrokerAddressInPublish(mq.getBrokerName()); - if (brokerAddr.empty()) { - updateTopicRouteInfoFromNameServer(mq.getTopic(), sessionCredentials); - brokerAddr = findBrokerAddressInPublish(mq.getBrokerName()); - } - - if (!brokerAddr.empty()) { - try { - return m_pClientAPIImpl->getMaxOffset(brokerAddr, mq.getTopic(), mq.getQueueId(), 1000 * 3, sessionCredentials); - } catch (MQException& e) { - THROW_MQEXCEPTION(MQClientException, "Invoke Broker exception", -1); - } - } - THROW_MQEXCEPTION(MQClientException, "The broker is not exist", -1); -} - -int64 MQClientFactory::searchOffset(const MQMessageQueue& mq, - int64 timestamp, - const SessionCredentials& sessionCredentials) { - string brokerAddr = findBrokerAddressInPublish(mq.getBrokerName()); - if (brokerAddr.empty()) { - updateTopicRouteInfoFromNameServer(mq.getTopic(), sessionCredentials); - brokerAddr = findBrokerAddressInPublish(mq.getBrokerName()); - } - - if (!brokerAddr.empty()) { - try { - return m_pClientAPIImpl->searchOffset(brokerAddr, mq.getTopic(), mq.getQueueId(), timestamp, 1000 * 3, - sessionCredentials); - } catch (MQException& e) { - THROW_MQEXCEPTION(MQClientException, "Invoke Broker exception", -1); - } - } - THROW_MQEXCEPTION(MQClientException, "The broker is not exist", -1); -} - -MQMessageExt* MQClientFactory::viewMessage(const string& msgId, const SessionCredentials& sessionCredentials) { - try { - return NULL; - } catch (MQException& e) { - THROW_MQEXCEPTION(MQClientException, "message id illegal", -1); - } -} - -int64 MQClientFactory::earliestMsgStoreTime(const MQMessageQueue& mq, const SessionCredentials& sessionCredentials) { - string brokerAddr = findBrokerAddressInPublish(mq.getBrokerName()); - if (brokerAddr.empty()) { - updateTopicRouteInfoFromNameServer(mq.getTopic(), sessionCredentials); - brokerAddr = findBrokerAddressInPublish(mq.getBrokerName()); - } - - if (!brokerAddr.empty()) { - try { - return m_pClientAPIImpl->getEarliestMsgStoretime(brokerAddr, mq.getTopic(), mq.getQueueId(), 1000 * 3, - sessionCredentials); - } catch (MQException& e) { - THROW_MQEXCEPTION(MQClientException, "Invoke Broker exception", -1); - } - } - THROW_MQEXCEPTION(MQClientException, "The broker is not exist", -1); -} - -QueryResult MQClientFactory::queryMessage(const string& topic, - const string& key, - int maxNum, - int64 begin, - int64 end, - const SessionCredentials& sessionCredentials) { - THROW_MQEXCEPTION(MQClientException, "queryMessage", -1); -} - -void MQClientFactory::findConsumerIds(const string& topic, - const string& group, - vector& cids, - const SessionCredentials& sessionCredentials) { - string brokerAddr; - TopicRouteData* pTopicRouteData = getTopicRouteData(topic); - if (pTopicRouteData == NULL) { - updateTopicRouteInfoFromNameServer(topic, sessionCredentials); - pTopicRouteData = getTopicRouteData(topic); - } - if (pTopicRouteData != NULL) { - brokerAddr = pTopicRouteData->selectBrokerAddr(); - } - - if (!brokerAddr.empty()) { - try { - LOG_INFO("getConsumerIdList from broker:%s", brokerAddr.c_str()); - return m_pClientAPIImpl->getConsumerIdListByGroup(brokerAddr, group, cids, 5000, sessionCredentials); - } catch (MQException& e) { - LOG_ERROR(e.what()); - } - } -} - -void MQClientFactory::resetOffset(const string& group, - const string& topic, - const map& offsetTable) { - MQConsumer* pConsumer = selectConsumer(group); - if (pConsumer) { - map::const_iterator it = offsetTable.begin(); - - for (; it != offsetTable.end(); ++it) { - MQMessageQueue mq = it->first; - boost::weak_ptr pullRequest = pConsumer->getRebalance()->getPullRequest(mq); - boost::shared_ptr pullreq = pullRequest.lock(); - // PullRequest* pullreq = pConsumer->getRebalance()->getPullRequest(mq); - if (pullreq) { - pullreq->setDropped(true); - LOG_INFO("resetOffset setDropped for mq:%s", mq.toString().data()); - pullreq->clearAllMsgs(); - pullreq->updateQueueMaxOffset(it->second); - } else { - LOG_ERROR("no corresponding pullRequest found for topic:%s", topic.c_str()); - } - } - - for (it = offsetTable.begin(); it != offsetTable.end(); ++it) { - MQMessageQueue mq = it->first; - if (topic == mq.getTopic()) { - LOG_INFO("offset sets to:%lld", it->second); - pConsumer->updateConsumeOffset(mq, it->second); - } - } - pConsumer->persistConsumerOffsetByResetOffset(); - - boost::this_thread::sleep_for(boost::chrono::milliseconds(10)); - - for (it = offsetTable.begin(); it != offsetTable.end(); ++it) { - MQMessageQueue mq = it->first; - if (topic == mq.getTopic()) { - LOG_DEBUG("resetOffset sets to:%lld for mq:%s", it->second, mq.toString().c_str()); - pConsumer->updateConsumeOffset(mq, it->second); - } - } - pConsumer->persistConsumerOffsetByResetOffset(); - - for (it = offsetTable.begin(); it != offsetTable.end(); ++it) { - MQMessageQueue mq = it->first; - if (topic == mq.getTopic()) { - pConsumer->removeConsumeOffset(mq); - } - } - - // do call pConsumer->doRebalance directly here, as it is conflict with - // timerCB_doRebalance; - doRebalanceByConsumerGroup(pConsumer->getGroupName()); - } else { - LOG_ERROR("no corresponding consumer found for group:%s", group.c_str()); - } -} - -ConsumerRunningInfo* MQClientFactory::consumerRunningInfo(const string& consumerGroup) { - MQConsumer* pConsumer = selectConsumer(consumerGroup); - if (pConsumer) { - ConsumerRunningInfo* runningInfo = pConsumer->getConsumerRunningInfo(); - if (runningInfo) { - runningInfo->setProperty(ConsumerRunningInfo::PROP_NAMESERVER_ADDR, pConsumer->getNamesrvAddr()); - if (pConsumer->getConsumeType() == CONSUME_PASSIVELY) { - runningInfo->setProperty(ConsumerRunningInfo::PROP_CONSUME_TYPE, "CONSUME_PASSIVELY"); - } else { - runningInfo->setProperty(ConsumerRunningInfo::PROP_CONSUME_TYPE, "CONSUME_ACTIVELY"); - } - runningInfo->setProperty( - ConsumerRunningInfo::PROP_CLIENT_VERSION, - MQVersion::GetVersionDesc(MQVersion::s_CurrentVersion)); // MQVersion::s_CurrentVersion )); - - return runningInfo; - } - } - - LOG_ERROR("no corresponding consumer found for group:%s", consumerGroup.c_str()); - return NULL; -} - -void MQClientFactory::getSessionCredentialsFromOneOfProducerOrConsumer(SessionCredentials& session_credentials) { - // Note: on the same MQClientFactory, all producers and consumers used the - // same - // sessionCredentials, - // So only need get sessionCredentials from the first one producer or consumer - // now. - // this function was only used by updateTopicRouteInfo() and - // sendHeartbeatToAllBrokers() now. - // if this strategy was changed in future, need get sessionCredentials for - // each - // producer and consumer. - getSessionCredentialFromProducerTable(session_credentials); - if (!session_credentials.isValid()) - getSessionCredentialFromConsumerTable(session_credentials); - - if (!session_credentials.isValid()) { - LOG_INFO( - "updateTopicRouteInfo: didn't get the session_credentials from any " - "producers and consumers, please re-intialize it if application needs authentication"); - } -} - -// -#include -#include -#include -#include -#include -#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 { -// topicRouteData2TopicPublishInfo(const string& topic, TopicRouteData* pRoute); - - void topicRouteData2TopicSubscribeInfo(const string& topic, TopicRouteData* pRoute, vector& mqs); - - FindBrokerResult* findBrokerAddressInSubscribe(const string& brokerName, int brokerId, bool onlyThisBroker); - - FindBrokerResult* findBrokerAddressInAdmin(const string& brokerName); - - string findBrokerAddressInPublish(const string& brokerName); - - boost::shared_ptr tryToFindTopicPublishInfo(const string& topic, - const SessionCredentials& session_credentials); - - void fetchSubscribeMessageQueues(const string& topic, - vector& mqs, - const SessionCredentials& session_credentials); - - bool updateTopicRouteInfoFromNameServer(const string& topic, - const SessionCredentials& session_credentials, - bool isDefault = false); - void rebalanceImmediately(); - void doRebalanceByConsumerGroup(const string& consumerGroup); - void sendHeartbeatToAllBroker(); - - void cleanOfflineBrokers(); - - void findConsumerIds(const string& topic, - const string& group, - vector& cids, - const SessionCredentials& session_credentials); - void resetOffset(const string& group, const string& topic, const map& offsetTable); - ConsumerRunningInfo* consumerRunningInfo(const string& consumerGroup); - bool getSessionCredentialFromConsumer(const string& consumerGroup, SessionCredentials& sessionCredentials); - void addBrokerToAddrMap(const string& brokerName, map& brokerAddrs); - map> 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); - // t); - void updateTopicRouteInfo(boost::system::error_code& ec, boost::shared_ptr t); - void timerCB_sendHeartbeatToAllBroker(boost::system::error_code& ec, - boost::shared_ptr t); - - void timerCB_cleanOfflineBrokers(boost::system::error_code& ec, boost::shared_ptr t); - - // consumer related operation - void consumer_timerOperation(); - void persistAllConsumerOffset(boost::system::error_code& ec, boost::shared_ptr t); - void doRebalance(); - void timerCB_doRebalance(boost::system::error_code& ec, boost::shared_ptr t); - bool getSessionCredentialFromConsumerTable(SessionCredentials& sessionCredentials); - bool addConsumerToTable(const string& consumerName, MQConsumer* pMQConsumer); - void eraseConsumerFromTable(const string& consumerName); - int getConsumerTableSize(); - void getTopicListFromConsumerSubscription(set& topicList); - void updateConsumerSubscribeTopicInfo(const string& topic, vector mqs); - void insertConsumerInfoToHeartBeatData(HeartbeatData* pHeartbeatData); - - // producer related operation - bool getSessionCredentialFromProducerTable(SessionCredentials& sessionCredentials); - bool addProducerToTable(const string& producerName, MQProducer* pMQProducer); - void eraseProducerFromTable(const string& producerName); - int getProducerTableSize(); - void insertProducerInfoToHeartBeatData(HeartbeatData* pHeartbeatData); - - // topicPublishInfo related operation - void addTopicInfoToTable(const string& topic, boost::shared_ptr pTopicPublishInfo); - void eraseTopicInfoFromTable(const string& topic); - bool isTopicInfoValidInTable(const string& topic); - boost::shared_ptr getTopicPublishInfoFromTable(const string& topic); - void getTopicListFromTopicPublishInfo(set& topicList); - - void getSessionCredentialsFromOneOfProducerOrConsumer(SessionCredentials& session_credentials); - - protected: - string m_clientId; - unique_ptr m_pClientAPIImpl; - unique_ptr m_pClientRemotingProcessor; - - private: - string m_nameSrvDomain; // per clientId - ServiceState m_serviceState; - bool m_bFetchNSService; - - // MQProducer; - typedef map MQPMAP; - boost::mutex m_producerTableMutex; - MQPMAP m_producerTable; - - // MQConsumer; - typedef map MQCMAP; - // Changed to recursive mutex due to avoid deadlock issue: - boost::recursive_mutex m_consumerTableMutex; - MQCMAP m_consumerTable; - - // TopicRouteData - typedef map TRDMAP; - boost::mutex m_topicRouteTableMutex; - TRDMAP m_topicRouteTable; - - //TopicPublishInfo> ; - typedef map> 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 m_async_service_thread; - - boost::asio::io_service m_consumer_async_ioService; - unique_ptr m_consumer_async_service_thread; -}; - -} // namespace rocketmq - -#endif diff --git a/src/MQClientImpl.cpp b/src/MQClientImpl.cpp new file mode 100644 index 000000000..fac8659a3 --- /dev/null +++ b/src/MQClientImpl.cpp @@ -0,0 +1,90 @@ +/* + * 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 "MQClientImpl.h" + +#include "Logging.h" +#include "MQAdminImpl.h" +#include "MQClientManager.h" +#include "TopicPublishInfo.h" +#include "UtilAll.h" + +namespace rocketmq { + +#define ROCKETMQCPP_VERSION "1.0.1" +#define BUILD_DATE "03-14-2018" + +// display version: strings bin/librocketmq.so |grep VERSION +const char* rocketmq_build_time = "VERSION: " ROCKETMQCPP_VERSION ", BUILD DATE: " BUILD_DATE; + +void MQClientImpl::start() { + if (m_clientInstance == nullptr) { + m_clientInstance = MQClientManager::getInstance()->getOrCreateMQClientInstance(m_clientConfig, m_rpcHook); + } + LOG_INFO_NEW("MQClientImpl start, nameserveraddr:{}, instanceName:{}, groupName:{}, clientId:{}", + m_clientConfig->getNamesrvAddr(), m_clientConfig->getInstanceName(), m_clientConfig->getGroupName(), + m_clientInstance->getClientId()); +} + +void MQClientImpl::shutdown() { + m_clientInstance = nullptr; +} + +void MQClientImpl::createTopic(const std::string& key, const std::string& newTopic, int queueNum) { + try { + m_clientInstance->getMQAdminImpl()->createTopic(key, newTopic, queueNum); + } catch (MQException& e) { + LOG_ERROR(e.what()); + } +} + +int64_t MQClientImpl::searchOffset(const MQMessageQueue& mq, uint64_t timestamp) { + return m_clientInstance->getMQAdminImpl()->searchOffset(mq, timestamp); +} + +int64_t MQClientImpl::maxOffset(const MQMessageQueue& mq) { + return m_clientInstance->getMQAdminImpl()->maxOffset(mq); +} + +int64_t MQClientImpl::minOffset(const MQMessageQueue& mq) { + return m_clientInstance->getMQAdminImpl()->minOffset(mq); +} + +int64_t MQClientImpl::earliestMsgStoreTime(const MQMessageQueue& mq) { + return m_clientInstance->getMQAdminImpl()->earliestMsgStoreTime(mq); +} + +MQMessageExtPtr MQClientImpl::viewMessage(const std::string& msgId) { + return m_clientInstance->getMQAdminImpl()->viewMessage(msgId); +} + +QueryResult MQClientImpl::queryMessage(const std::string& topic, + const std::string& key, + int maxNum, + int64_t begin, + int64_t end) { + return m_clientInstance->getMQAdminImpl()->queryMessage(topic, key, maxNum, begin, end); +} + +MQClientInstancePtr MQClientImpl::getFactory() const { + return m_clientInstance; +} + +bool MQClientImpl::isServiceStateOk() { + return m_serviceState == RUNNING; +} + +} // namespace rocketmq diff --git a/src/MQClientImpl.h b/src/MQClientImpl.h new file mode 100644 index 000000000..f116407c8 --- /dev/null +++ b/src/MQClientImpl.h @@ -0,0 +1,64 @@ +/* + * 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_IMPL_H__ +#define __MQ_CLIENT_IMPL_H__ + +#include "MQAdmin.h" +#include "MQClientConfig.h" +#include "MQClientInstance.h" +#include "ServiceState.h" + +namespace rocketmq { + +class MQClientImpl : virtual public MQAdmin { + public: + MQClientImpl(MQClientConfig* config, std::shared_ptr rpcHook) + : m_clientConfig(config), m_rpcHook(rpcHook), m_serviceState(CREATE_JUST), m_clientInstance(nullptr) {} + + public: // MQAdmin + void createTopic(const std::string& key, const std::string& newTopic, int queueNum) override; + int64_t searchOffset(const MQMessageQueue& mq, uint64_t timestamp) override; + int64_t maxOffset(const MQMessageQueue& mq) override; + int64_t minOffset(const MQMessageQueue& mq) override; + int64_t earliestMsgStoreTime(const MQMessageQueue& mq) override; + MQMessageExtPtr viewMessage(const std::string& offsetMsgId) override; + QueryResult queryMessage(const std::string& topic, + const std::string& key, + int maxNum, + int64_t begin, + int64_t end) override; + + public: + virtual void start(); + virtual void shutdown(); + + MQClientInstancePtr getFactory() const; + virtual bool isServiceStateOk(); + + std::shared_ptr getRPCHook() { return m_rpcHook; } + void setRPCHook(std::shared_ptr rpcHook) { m_rpcHook = rpcHook; } + + protected: + MQClientConfig* m_clientConfig; + std::shared_ptr m_rpcHook; + ServiceState m_serviceState; + MQClientInstancePtr m_clientInstance; +}; + +} // namespace rocketmq + +#endif // __MQ_CLIENT_IMPL_H__ diff --git a/src/MQClientInstance.cpp b/src/MQClientInstance.cpp new file mode 100644 index 000000000..fff4d6045 --- /dev/null +++ b/src/MQClientInstance.cpp @@ -0,0 +1,962 @@ +/* + * 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 "MQClientInstance.h" + +#include + +#include "ClientRemotingProcessor.h" +#include "ConsumerRunningInfo.h" +#include "Logging.h" +#include "MQAdminImpl.h" +#include "MQClientAPIImpl.h" +#include "MQClientManager.h" +#include "MQVersion.h" +#include "PermName.h" +#include "PullMessageService.h" +#include "PullRequest.h" +#include "RebalanceImpl.h" +#include "RebalanceService.h" +#include "TcpRemotingClient.h" +#include "TopicPublishInfo.h" +#include "UtilAll.h" + +#define MAX_BUFF_SIZE 8192 +#define PROCESS_NAME_BUF_SIZE 256 +#define SAFE_BUFF_SIZE (MAX_BUFF_SIZE - PROCESS_NAME_BUF_SIZE) // 8192 - 256 = 7936 + +namespace rocketmq { + +static const long LOCK_TIMEOUT_MILLIS = 3000L; + +MQClientInstance::MQClientInstance(MQClientConfig clientConfig, const std::string& clientId) + : MQClientInstance(clientConfig, clientId, nullptr) {} + +MQClientInstance::MQClientInstance(MQClientConfig clientConfig, + const std::string& clientId, + std::shared_ptr rpcHook) + : m_clientConfig(clientConfig), + m_clientId(clientId), + m_rebalanceService(new RebalanceService(this)), + m_pullMessageService(new PullMessageService(this)), + m_scheduledExecutorService("MQClient", false) { + // default Topic register + TopicPublishInfoPtr defaultTopicInfo(new TopicPublishInfo()); + m_topicPublishInfoTable[AUTO_CREATE_TOPIC_KEY_TOPIC] = defaultTopicInfo; + + m_clientRemotingProcessor.reset(new ClientRemotingProcessor(this)); + m_mqClientAPIImpl.reset(new MQClientAPIImpl(m_clientRemotingProcessor.get(), rpcHook, &m_clientConfig)); + + std::string namesrvAddr = m_clientConfig.getNamesrvAddr(); + if (!namesrvAddr.empty()) { + m_mqClientAPIImpl->updateNameServerAddr(namesrvAddr); + LOG_INFO_NEW("user specified name server address: {}", namesrvAddr); + } + + m_mqAdminImpl.reset(new MQAdminImpl(this)); + + m_serviceState = CREATE_JUST; + LOG_DEBUG_NEW("MQClientInstance construct"); +} + +MQClientInstance::~MQClientInstance() { + LOG_INFO_NEW("MQClientInstance:{} destruct", m_clientId); + + // UNNECESSARY: + m_producerTable.clear(); + m_consumerTable.clear(); + m_topicPublishInfoTable.clear(); + m_topicRouteTable.clear(); + m_brokerAddrTable.clear(); + + m_mqClientAPIImpl = nullptr; +} + +TopicPublishInfoPtr MQClientInstance::topicRouteData2TopicPublishInfo(const std::string& topic, + TopicRouteDataPtr route) { + TopicPublishInfoPtr info(new TopicPublishInfo()); + info->setTopicRouteData(route); + + std::string orderTopicConf = route->getOrderTopicConf(); + if (!orderTopicConf.empty()) { // order msg + // "broker-a:8";"broker-b:8" + std::vector brokers; + UtilAll::Split(brokers, orderTopicConf, ';'); + for (const auto& broker : brokers) { + std::vector item; + UtilAll::Split(item, broker, ':'); + int nums = atoi(item[1].c_str()); + for (int i = 0; i < nums; i++) { + info->getMessageQueueList().emplace_back(topic, item[0], i); + } + } + info->setOrderTopic(true); + } else { // no order msg + const auto& qds = route->getQueueDatas(); + for (const auto& qd : qds) { + if (PermName::isWriteable(qd.perm)) { + const BrokerData* brokerData = nullptr; + for (const auto& bd : route->getBrokerDatas()) { + if (bd.brokerName == qd.brokerName) { + brokerData = &bd; + break; + } + } + + if (nullptr == brokerData) { + LOG_WARN_NEW("MQClientInstance: broker:{} of topic:{} have not data", qd.brokerName, topic); + continue; + } + + if (brokerData->brokerAddrs.find(MASTER_ID) == brokerData->brokerAddrs.end()) { + LOG_WARN_NEW("MQClientInstance: broker:{} of topic:{} have not master node", qd.brokerName, topic); + continue; + } + + for (int i = 0; i < qd.writeQueueNums; i++) { + info->getMessageQueueList().emplace_back(topic, qd.brokerName, i); + } + } + } + + // sort, make brokerName is staggered. + std::sort(info->getMessageQueueList().begin(), info->getMessageQueueList().end(), + [](const MQMessageQueue& a, const MQMessageQueue& b) { + auto result = a.getQueueId() - b.getQueueId(); + if (result == 0) { + result = a.getBrokerName().compare(b.getBrokerName()); + } + return result < 0; + }); + + info->setOrderTopic(false); + } + + return info; +} + +std::vector MQClientInstance::topicRouteData2TopicSubscribeInfo(const std::string& topic, + TopicRouteDataPtr route) { + std::vector mqList; + const auto& queueDatas = route->getQueueDatas(); + for (const auto& qd : queueDatas) { + if (PermName::isReadable(qd.perm)) { + for (int i = 0; i < qd.readQueueNums; i++) { + MQMessageQueue mq(topic, qd.brokerName, i); + mqList.push_back(mq); + } + } + } + return mqList; +} + +void MQClientInstance::start() { + switch (m_serviceState) { + case CREATE_JUST: + LOG_INFO_NEW("MQClientInstance:{} start", m_clientId); + m_serviceState = START_FAILED; + + m_mqClientAPIImpl->start(); + + // start various schedule tasks + startScheduledTask(); + + // start pull service + m_pullMessageService->start(); + + // start rebalance service + m_rebalanceService->start(); + + LOG_INFO_NEW("the client factory [{}] start OK", m_clientId); + m_serviceState = RUNNING; + break; + case RUNNING: + case SHUTDOWN_ALREADY: + case START_FAILED: + LOG_INFO_NEW("The Factory object:{} start failed with fault state:{}", m_clientId, m_serviceState); + break; + default: + break; + } +} + +void MQClientInstance::shutdown() { + if (getConsumerTableSize() != 0) + return; + + if (getProducerTableSize() != 0) + return; + + switch (m_serviceState) { + case CREATE_JUST: + break; + case RUNNING: { + m_serviceState = SHUTDOWN_ALREADY; + m_pullMessageService->shutdown(); + m_scheduledExecutorService.shutdown(); + m_mqClientAPIImpl->shutdown(); + m_rebalanceService->shutdown(); + + MQClientManager::getInstance()->removeMQClientInstance(m_clientId); + LOG_INFO_NEW("the client factory [{}] shutdown OK", m_clientId); + } break; + case SHUTDOWN_ALREADY: + break; + default: + break; + } +} + +bool MQClientInstance::isRunning() { + return m_serviceState == RUNNING; +} + +void MQClientInstance::startScheduledTask() { + LOG_INFO_NEW("start scheduled task:{}", m_clientId); + m_scheduledExecutorService.startup(); + + // updateTopicRouteInfoFromNameServer + m_scheduledExecutorService.schedule(std::bind(&MQClientInstance::updateTopicRouteInfoPeriodically, this), 10, + time_unit::milliseconds); + + // sendHeartbeatToAllBroker + m_scheduledExecutorService.schedule(std::bind(&MQClientInstance::sendHeartbeatToAllBrokerPeriodically, this), 1000, + time_unit::milliseconds); + + // persistAllConsumerOffset + m_scheduledExecutorService.schedule(std::bind(&MQClientInstance::persistAllConsumerOffsetPeriodically, this), + 1000 * 10, time_unit::milliseconds); +} + +void MQClientInstance::updateTopicRouteInfoPeriodically() { + updateTopicRouteInfoFromNameServer(); + + // next round + m_scheduledExecutorService.schedule(std::bind(&MQClientInstance::updateTopicRouteInfoPeriodically, this), 1000 * 30, + time_unit::milliseconds); +} + +void MQClientInstance::sendHeartbeatToAllBrokerPeriodically() { + cleanOfflineBroker(); + sendHeartbeatToAllBrokerWithLock(); + + // next round + m_scheduledExecutorService.schedule(std::bind(&MQClientInstance::sendHeartbeatToAllBrokerPeriodically, this), + 1000 * 30, time_unit::milliseconds); +} + +void MQClientInstance::persistAllConsumerOffsetPeriodically() { + persistAllConsumerOffset(); + + // next round + m_scheduledExecutorService.schedule(std::bind(&MQClientInstance::persistAllConsumerOffsetPeriodically, this), + 1000 * 5, time_unit::milliseconds); +} + +std::string MQClientInstance::getClientId() { + return m_clientId; +} + +void MQClientInstance::updateTopicRouteInfoFromNameServer() { + std::set topicList; + + // Consumer + getTopicListFromConsumerSubscription(topicList); + + // Producer + getTopicListFromTopicPublishInfo(topicList); + + // update + if (!topicList.empty()) { + for (const auto& topic : topicList) { + updateTopicRouteInfoFromNameServer(topic); + } + } +} + +void MQClientInstance::cleanOfflineBroker() { + if (UtilAll::try_lock_for(m_lockNamesrv, LOCK_TIMEOUT_MILLIS)) { + std::lock_guard lock(m_lockNamesrv, std::adopt_lock); + + BrokerAddrMAP updatedTable(getBrokerAddrTable()); + for (auto itBrokerTable = updatedTable.begin(); itBrokerTable != updatedTable.end();) { + const auto& brokerName = itBrokerTable->first; + auto& cloneAddrTable = itBrokerTable->second; + + for (auto it = cloneAddrTable.begin(); it != cloneAddrTable.end();) { + const auto& addr = it->second; + if (!isBrokerAddrExistInTopicRouteTable(addr)) { + it = cloneAddrTable.erase(it); + LOG_INFO_NEW("the broker addr[{} {}] is offline, remove it", brokerName, addr); + } else { + it++; + } + } + + if (cloneAddrTable.empty()) { + itBrokerTable = updatedTable.erase(itBrokerTable); + LOG_INFO_NEW("the broker[{}] name's host is offline, remove it", brokerName); + } else { + itBrokerTable++; + } + } + + resetBrokerAddrTable(std::move(updatedTable)); + } else { + LOG_WARN_NEW("lock namesrv, but failed."); + } +} + +bool MQClientInstance::isBrokerAddrExistInTopicRouteTable(const std::string& addr) { + std::lock_guard lock(m_topicRouteTableMutex); + for (const auto& it : m_topicRouteTable) { + const auto topicRouteData = it.second; + const auto& bds = topicRouteData->getBrokerDatas(); + for (const auto& bd : bds) { + for (const auto& itAddr : bd.brokerAddrs) { + if (itAddr.second == addr) { + return true; + } + } + } + } + return false; +} + +void MQClientInstance::sendHeartbeatToAllBrokerWithLock() { + if (m_lockHeartbeat.try_lock()) { + std::lock_guard lock(m_lockHeartbeat, std::adopt_lock); + sendHeartbeatToAllBroker(); + } else { + LOG_WARN_NEW("lock heartBeat, but failed."); + } +} + +void MQClientInstance::persistAllConsumerOffset() { + std::lock_guard lock(m_consumerTableMutex); + for (const auto& it : m_consumerTable) { + LOG_DEBUG_NEW("Client factory start persistAllConsumerOffset"); + it.second->persistConsumerOffset(); + } +} + +void MQClientInstance::sendHeartbeatToAllBroker() { + std::unique_ptr heartbeatData(prepareHeartbeatData()); + bool producerEmpty = heartbeatData->isProducerDataSetEmpty(); + bool consumerEmpty = heartbeatData->isConsumerDataSetEmpty(); + if (producerEmpty && consumerEmpty) { + LOG_WARN_NEW("sending heartbeat, but no consumer and no producer"); + return; + } + + BrokerAddrMAP brokerAddrTable(getBrokerAddrTable()); + if (!brokerAddrTable.empty()) { + for (const auto& it : brokerAddrTable) { + // const auto& brokerName = it.first; + const auto& oneTable = it.second; + for (const auto& it2 : oneTable) { + const auto id = it2.first; + const auto& addr = it2.second; + if (consumerEmpty && id != MASTER_ID) { + continue; + } + + try { + m_mqClientAPIImpl->sendHearbeat(addr, heartbeatData.get()); + } catch (MQException& e) { + LOG_ERROR_NEW("{}", e.what()); + } + } + } + brokerAddrTable.clear(); + } else { + LOG_WARN_NEW("sendheartbeat brokerAddrTable is empty"); + } +} + +bool MQClientInstance::updateTopicRouteInfoFromNameServer(const std::string& topic, bool isDefault) { + if (UtilAll::try_lock_for(m_lockNamesrv, LOCK_TIMEOUT_MILLIS)) { + std::lock_guard lock(m_lockNamesrv, std::adopt_lock); + LOG_DEBUG_NEW("updateTopicRouteInfoFromNameServer start:{}", topic); + + try { + TopicRouteDataPtr topicRouteData; + if (isDefault) { + topicRouteData.reset(m_mqClientAPIImpl->getTopicRouteInfoFromNameServer(AUTO_CREATE_TOPIC_KEY_TOPIC, 1000 * 3)); + if (topicRouteData != nullptr) { + auto& queueDatas = topicRouteData->getQueueDatas(); + for (auto& qd : queueDatas) { + int queueNums = std::min(4, qd.readQueueNums); + qd.readQueueNums = queueNums; + qd.writeQueueNums = queueNums; + } + } + LOG_DEBUG_NEW("getTopicRouteInfoFromNameServer is null for topic: {}", topic); + } else { + topicRouteData.reset(m_mqClientAPIImpl->getTopicRouteInfoFromNameServer(topic, 1000 * 3)); + } + if (topicRouteData != nullptr) { + LOG_INFO_NEW("updateTopicRouteInfoFromNameServer has data"); + auto old = getTopicRouteData(topic); + bool changed = topicRouteDataIsChange(old.get(), topicRouteData.get()); + + if (changed) { + LOG_INFO_NEW("updateTopicRouteInfoFromNameServer changed:{}", topic); + + // update broker addr + const auto& brokerDatas = topicRouteData->getBrokerDatas(); + for (const auto& bd : brokerDatas) { + LOG_INFO_NEW("updateTopicRouteInfoFromNameServer changed with broker name:{}", bd.brokerName); + addBrokerToAddrTable(bd.brokerName, bd.brokerAddrs); + } + + // update publish info + { + TopicPublishInfoPtr publishInfo(topicRouteData2TopicPublishInfo(topic, topicRouteData)); + publishInfo->setHaveTopicRouterInfo(true); + updateProducerTopicPublishInfo(topic, publishInfo); + } + + // update subscribe info + if (getConsumerTableSize() > 0) { + std::vector subscribeInfo = topicRouteData2TopicSubscribeInfo(topic, topicRouteData); + updateConsumerTopicSubscribeInfo(topic, subscribeInfo); + } + + addTopicRouteData(topic, topicRouteData); + } + + LOG_DEBUG_NEW("updateTopicRouteInfoFromNameServer end:{}", topic); + return true; + } else { + LOG_WARN_NEW("updateTopicRouteInfoFromNameServer, getTopicRouteInfoFromNameServer return null, Topic: {}", + topic); + } + } catch (const std::exception& e) { + if (!UtilAll::isRetryTopic(topic) && topic != AUTO_CREATE_TOPIC_KEY_TOPIC) { + LOG_WARN_NEW("updateTopicRouteInfoFromNameServer Exception, {}", e.what()); + } + } + } else { + LOG_WARN_NEW("updateTopicRouteInfoFromNameServer tryLock timeout {}ms", LOCK_TIMEOUT_MILLIS); + } + + return false; +} + +HeartbeatData* MQClientInstance::prepareHeartbeatData() { + HeartbeatData* pHeartbeatData = new HeartbeatData(); + + // clientID + pHeartbeatData->setClientID(m_clientId); + + // Consumer + insertConsumerInfoToHeartBeatData(pHeartbeatData); + + // Producer + insertProducerInfoToHeartBeatData(pHeartbeatData); + + return pHeartbeatData; +} + +void MQClientInstance::insertConsumerInfoToHeartBeatData(HeartbeatData* pHeartbeatData) { + std::lock_guard lock(m_consumerTableMutex); + for (const auto& it : m_consumerTable) { + const auto* consumer = it.second; + ConsumerData consumerData; + consumerData.groupName = consumer->groupName(); + consumerData.consumeType = consumer->consumeType(); + consumerData.messageModel = consumer->messageModel(); + consumerData.consumeFromWhere = consumer->consumeFromWhere(); + std::vector result = consumer->subscriptions(); + consumerData.subscriptionDataSet.swap(result); + // TODO: unitMode + + pHeartbeatData->insertDataToConsumerDataSet(consumerData); + } +} + +void MQClientInstance::insertProducerInfoToHeartBeatData(HeartbeatData* pHeartbeatData) { + std::lock_guard lock(m_producerTableMutex); + for (const auto& it : m_producerTable) { + ProducerData producerData; + producerData.groupName = it.first; + pHeartbeatData->insertDataToProducerDataSet(producerData); + } +} + +bool MQClientInstance::topicRouteDataIsChange(TopicRouteData* olddata, TopicRouteData* nowdata) { + if (olddata == nullptr || nowdata == nullptr) { + return true; + } + return !(*olddata == *nowdata); +} + +TopicRouteDataPtr MQClientInstance::getTopicRouteData(const std::string& topic) { + std::lock_guard lock(m_topicRouteTableMutex); + auto iter = m_topicRouteTable.find(topic); + if (iter != m_topicRouteTable.end()) { + return iter->second; + } + return TopicRouteDataPtr(); +} + +void MQClientInstance::addTopicRouteData(const std::string& topic, TopicRouteDataPtr topicRouteData) { + std::lock_guard lock(m_topicRouteTableMutex); + m_topicRouteTable[topic] = topicRouteData; +} + +bool MQClientInstance::registerConsumer(const std::string& group, MQConsumerInner* consumer) { + if (group.empty()) { + return false; + } + + if (!addConsumerToTable(group, consumer)) { + LOG_WARN_NEW("the consumer group[{}] exist already.", group); + return false; + } + + LOG_DEBUG_NEW("registerConsumer success:{}", group); + return true; +} + +void MQClientInstance::unregisterConsumer(const std::string& group) { + eraseConsumerFromTable(group); + unregisterClientWithLock(null, group); +} + +void MQClientInstance::unregisterClientWithLock(const std::string& producerGroup, const std::string& consumerGroup) { + if (UtilAll::try_lock_for(m_lockHeartbeat, LOCK_TIMEOUT_MILLIS)) { + std::lock_guard lock(m_lockHeartbeat, std::adopt_lock); + + try { + unregisterClient(producerGroup, consumerGroup); + } catch (const std::exception& e) { + LOG_ERROR_NEW("unregisterClient exception: {}", e.what()); + } + } else { + LOG_WARN_NEW("lock heartBeat, but failed."); + } +} + +void MQClientInstance::unregisterClient(const std::string& producerGroup, const std::string& consumerGroup) { + BrokerAddrMAP brokerAddrTable(getBrokerAddrTable()); + for (const auto& it : brokerAddrTable) { + const auto& brokerName = it.first; + const auto& oneTable = it.second; + for (const auto& it2 : oneTable) { + const auto& index = it2.first; + const auto& addr = it2.second; + try { + m_mqClientAPIImpl->unregisterClient(addr, m_clientId, producerGroup, consumerGroup); + LOG_INFO_NEW("unregister client[Producer: {} Consumer: {}] from broker[{} {} {}] success", producerGroup, + consumerGroup, brokerName, index, addr); + } catch (const std::exception& e) { + LOG_ERROR_NEW("unregister client exception from broker: {}. EXCEPTION: {}", addr, e.what()); + } + } + } +} + +bool MQClientInstance::registerProducer(const std::string& group, MQProducerInner* producer) { + if (group.empty()) { + return false; + } + + if (!addProducerToTable(group, producer)) { + LOG_WARN_NEW("the consumer group[{}] exist already.", group); + return false; + } + + LOG_DEBUG_NEW("registerProducer success:{}", group); + return true; +} + +void MQClientInstance::unregisterProducer(const std::string& group) { + eraseProducerFromTable(group); + unregisterClientWithLock(group, null); +} + +void MQClientInstance::rebalanceImmediately() { + m_rebalanceService->wakeup(); +} + +void MQClientInstance::doRebalance() { + LOG_INFO_NEW("Client factory:{} start dorebalance", m_clientId); + if (getConsumerTableSize() > 0) { + std::lock_guard lock(m_consumerTableMutex); + for (auto& it : m_consumerTable) { + it.second->doRebalance(); + } + } + LOG_INFO_NEW("Client factory:{} finish dorebalance", m_clientId); +} + +void MQClientInstance::doRebalanceByConsumerGroup(const std::string& consumerGroup) { + std::lock_guard lock(m_consumerTableMutex); + if (m_consumerTable.find(consumerGroup) != m_consumerTable.end()) { + try { + LOG_INFO_NEW("Client factory:{} start dorebalance for consumer:{}", m_clientId, consumerGroup); + auto* consumer = m_consumerTable[consumerGroup]; + consumer->doRebalance(); + } catch (const std::exception& e) { + LOG_ERROR_NEW("{}", e.what()); + } + } +} + +MQProducerInner* MQClientInstance::selectProducer(const std::string& producerName) { + std::lock_guard lock(m_producerTableMutex); + if (m_producerTable.find(producerName) != m_producerTable.end()) { + return m_producerTable[producerName]; + } + return nullptr; +} + +bool MQClientInstance::addProducerToTable(const std::string& producerName, MQProducerInner* producer) { + std::lock_guard lock(m_producerTableMutex); + if (m_producerTable.find(producerName) != m_producerTable.end()) + return false; + m_producerTable[producerName] = producer; + return true; +} + +void MQClientInstance::eraseProducerFromTable(const std::string& producerName) { + std::lock_guard lock(m_producerTableMutex); + if (m_producerTable.find(producerName) != m_producerTable.end()) { + m_producerTable.erase(producerName); + } +} + +int MQClientInstance::getProducerTableSize() { + std::lock_guard lock(m_producerTableMutex); + return m_producerTable.size(); +} + +void MQClientInstance::getTopicListFromTopicPublishInfo(std::set& topicList) { + std::lock_guard lock(m_topicPublishInfoTableMutex); + for (const auto& it : m_topicPublishInfoTable) { + topicList.insert(it.first); + } +} + +void MQClientInstance::updateProducerTopicPublishInfo(const std::string& topic, TopicPublishInfoPtr publishInfo) { + addTopicInfoToTable(topic, publishInfo); +} + +MQConsumerInner* MQClientInstance::selectConsumer(const std::string& group) { + std::lock_guard lock(m_consumerTableMutex); + if (m_consumerTable.find(group) != m_consumerTable.end()) { + return m_consumerTable[group]; + } + return nullptr; +} + +bool MQClientInstance::addConsumerToTable(const std::string& consumerName, MQConsumerInner* consumer) { + std::lock_guard lock(m_consumerTableMutex); + if (m_consumerTable.find(consumerName) != m_consumerTable.end()) { + return false; + } else { + m_consumerTable[consumerName] = consumer; + return true; + } +} + +void MQClientInstance::eraseConsumerFromTable(const std::string& consumerName) { + std::lock_guard lock(m_consumerTableMutex); + if (m_consumerTable.find(consumerName) != m_consumerTable.end()) { + m_consumerTable.erase(consumerName); // do not need free consumer, as it was allocated by user + } else { + LOG_WARN_NEW("could not find consumer:{} from table", consumerName); + } +} + +int MQClientInstance::getConsumerTableSize() { + std::lock_guard lock(m_consumerTableMutex); + return m_consumerTable.size(); +} + +void MQClientInstance::getTopicListFromConsumerSubscription(std::set& topicList) { + std::lock_guard lock(m_consumerTableMutex); + for (const auto& it : m_consumerTable) { + std::vector result = it.second->subscriptions(); + for (const auto& sd : result) { + topicList.insert(sd.getTopic()); + } + } +} + +void MQClientInstance::updateConsumerTopicSubscribeInfo(const std::string& topic, + std::vector subscribeInfo) { + std::lock_guard lock(m_consumerTableMutex); + for (auto& it : m_consumerTable) { + it.second->updateTopicSubscribeInfo(topic, subscribeInfo); + } +} + +void MQClientInstance::addTopicInfoToTable(const std::string& topic, TopicPublishInfoPtr topicPublishInfo) { + std::lock_guard lock(m_topicPublishInfoTableMutex); + m_topicPublishInfoTable[topic] = topicPublishInfo; +} + +void MQClientInstance::eraseTopicInfoFromTable(const std::string& topic) { + std::lock_guard lock(m_topicPublishInfoTableMutex); + if (m_topicPublishInfoTable.find(topic) != m_topicPublishInfoTable.end()) { + m_topicPublishInfoTable.erase(topic); + } +} + +TopicPublishInfoPtr MQClientInstance::getTopicPublishInfoFromTable(const std::string& topic) { + std::lock_guard lock(m_topicPublishInfoTableMutex); + if (m_topicPublishInfoTable.find(topic) != m_topicPublishInfoTable.end()) { + return m_topicPublishInfoTable[topic]; + } + return TopicPublishInfoPtr(); +} + +bool MQClientInstance::isTopicInfoValidInTable(const std::string& topic) { + std::lock_guard lock(m_topicPublishInfoTableMutex); + auto iter = m_topicPublishInfoTable.find(topic); + if (iter != m_topicPublishInfoTable.end()) { + return iter->second->ok(); + } + return false; +} + +TopicPublishInfoPtr MQClientInstance::tryToFindTopicPublishInfo(const std::string& topic) { + auto topicPublishInfo = getTopicPublishInfoFromTable(topic); + if (nullptr == topicPublishInfo || !topicPublishInfo->ok()) { + updateTopicRouteInfoFromNameServer(topic); + topicPublishInfo = getTopicPublishInfoFromTable(topic); + } + + if (nullptr != topicPublishInfo && (topicPublishInfo->isHaveTopicRouterInfo() || topicPublishInfo->ok())) { + return topicPublishInfo; + } else { + LOG_INFO_NEW("updateTopicRouteInfoFromNameServer with default"); + updateTopicRouteInfoFromNameServer(topic, true); + return getTopicPublishInfoFromTable(topic); + } +} + +FindBrokerResult* MQClientInstance::findBrokerAddressInAdmin(const std::string& brokerName) { + BrokerAddrMAP brokerTable(getBrokerAddrTable()); + bool found = false; + bool slave = false; + std::string brokerAddr; + + if (brokerTable.find(brokerName) != brokerTable.end()) { + std::map brokerMap(brokerTable[brokerName]); + std::map::iterator it1 = brokerMap.begin(); + if (it1 != brokerMap.end()) { + slave = (it1->first != MASTER_ID); + found = true; + brokerAddr = it1->second; + } + } + + brokerTable.clear(); + if (found) { + return new FindBrokerResult(brokerAddr, slave); + } + + return nullptr; +} + +std::string MQClientInstance::findBrokerAddressInPublish(const std::string& brokerName) { + BrokerAddrMAP brokerTable(getBrokerAddrTable()); + std::string brokerAddr; + bool found = false; + + if (brokerTable.find(brokerName) != brokerTable.end()) { + const auto& brokerMap = brokerTable[brokerName]; + auto it = brokerMap.find(MASTER_ID); + if (it != brokerMap.end()) { + brokerAddr = it->second; + found = true; + } + } + + brokerTable.clear(); + if (found) { + return brokerAddr; + } + + return null; +} + +FindBrokerResult* MQClientInstance::findBrokerAddressInSubscribe(const std::string& brokerName, + int brokerId, + bool onlyThisBroker) { + std::string brokerAddr; + bool slave = false; + bool found = false; + BrokerAddrMAP brokerTable(getBrokerAddrTable()); + + if (brokerTable.find(brokerName) != brokerTable.end()) { + std::map brokerMap(brokerTable[brokerName]); + if (!brokerMap.empty()) { + auto iter = brokerMap.find(brokerId); + if (iter != brokerMap.end()) { + brokerAddr = iter->second; + slave = (brokerId != MASTER_ID); + found = true; + } else if (!onlyThisBroker) { // not only from master + iter = brokerMap.begin(); + brokerAddr = iter->second; + slave = iter->first != MASTER_ID; + found = true; + } + } + } + + brokerTable.clear(); + + if (found) { + return new FindBrokerResult(brokerAddr, slave); + } + + return nullptr; +} + +void MQClientInstance::findConsumerIds(const std::string& topic, + const std::string& group, + std::vector& cids) { + std::string brokerAddr = findBrokerAddrByTopic(topic); + if (brokerAddr.empty()) { + updateTopicRouteInfoFromNameServer(topic); + brokerAddr = findBrokerAddrByTopic(topic); + } + + if (!brokerAddr.empty()) { + try { + LOG_INFO_NEW("getConsumerIdList from broker:{}", brokerAddr); + return m_mqClientAPIImpl->getConsumerIdListByGroup(brokerAddr, group, cids, 5000); + } catch (MQException& e) { + LOG_ERROR_NEW("{}", e.what()); + } + } +} + +std::string MQClientInstance::findBrokerAddrByTopic(const std::string& topic) { + auto topicRouteData = getTopicRouteData(topic); + if (topicRouteData != nullptr) { + return topicRouteData->selectBrokerAddr(); + } + return ""; +} + +void MQClientInstance::resetOffset(const std::string& group, + const std::string& topic, + const std::map& offsetTable) { + DefaultMQPushConsumerImpl* consumer = nullptr; + try { + auto* impl = selectConsumer(group); + if (impl != nullptr && std::type_index(typeid(*impl)) == std::type_index(typeid(DefaultMQPushConsumerImpl))) { + consumer = static_cast(impl); + } else { + LOG_INFO_NEW("[reset-offset] consumer dose not exist. group={}", group); + return; + } + consumer->suspend(); + + auto processQueueTable = consumer->getRebalanceImpl()->getProcessQueueTable(); + for (const auto& it : processQueueTable) { + const auto& mq = it.first; + if (topic == mq.getTopic() && offsetTable.find(mq) != offsetTable.end()) { + auto pq = it.second; + pq->setDropped(true); + pq->clearAllMsgs(); + } + } + + std::this_thread::sleep_for(std::chrono::seconds(10)); + + for (const auto& it : processQueueTable) { + const auto& mq = it.first; + auto it2 = offsetTable.find(mq); + if (it2 != offsetTable.end()) { + auto offset = it2->second; + consumer->updateConsumeOffset(mq, offset); + consumer->getRebalanceImpl()->removeUnnecessaryMessageQueue(mq, it.second); + consumer->getRebalanceImpl()->removeProcessQueueDirectly(mq); + } + } + } catch (...) { + if (consumer != nullptr) { + consumer->resume(); + } + throw; + } + if (consumer != nullptr) { + consumer->resume(); + } +} + +ConsumerRunningInfo* MQClientInstance::consumerRunningInfo(const std::string& consumerGroup) { + auto* consumer = selectConsumer(consumerGroup); + if (consumer != nullptr) { + std::unique_ptr runningInfo(consumer->consumerRunningInfo()); + if (runningInfo != nullptr) { + auto nsList = m_mqClientAPIImpl->getRemotingClient()->getNameServerAddressList(); + + std::string nsAddr; + for (const auto& addr : nsList) { + nsAddr.append(addr); + } + + runningInfo->setProperty(ConsumerRunningInfo::PROP_NAMESERVER_ADDR, nsAddr); + if (consumer->consumeType() == CONSUME_PASSIVELY) { + runningInfo->setProperty(ConsumerRunningInfo::PROP_CONSUME_TYPE, "CONSUME_PASSIVELY"); + } else { + runningInfo->setProperty(ConsumerRunningInfo::PROP_CONSUME_TYPE, "CONSUME_ACTIVELY"); + } + runningInfo->setProperty(ConsumerRunningInfo::PROP_CLIENT_VERSION, + MQVersion::GetVersionDesc(MQVersion::s_CurrentVersion)); + + return runningInfo.release(); + } + } + + LOG_ERROR_NEW("no corresponding consumer found for group:{}", consumerGroup); + return nullptr; +} + +void MQClientInstance::addBrokerToAddrTable(const std::string& brokerName, + const std::map& brokerAddrs) { + std::lock_guard lock(m_brokerAddrTableMutex); + if (m_brokerAddrTable.find(brokerName) != m_brokerAddrTable.end()) { + m_brokerAddrTable.erase(brokerName); + } + m_brokerAddrTable.emplace(brokerName, brokerAddrs); +} + +void MQClientInstance::resetBrokerAddrTable(BrokerAddrMAP&& table) { + std::lock_guard lock(m_brokerAddrTableMutex); + m_brokerAddrTable = std::forward(table); +} + +void MQClientInstance::clearBrokerAddrTable() { + std::lock_guard lock(m_brokerAddrTableMutex); + m_brokerAddrTable.clear(); +} + +MQClientInstance::BrokerAddrMAP MQClientInstance::getBrokerAddrTable() { + std::lock_guard lock(m_brokerAddrTableMutex); + return m_brokerAddrTable; +} + +} // namespace rocketmq diff --git a/src/MQClientInstance.h b/src/MQClientInstance.h new file mode 100644 index 000000000..be6993f97 --- /dev/null +++ b/src/MQClientInstance.h @@ -0,0 +1,204 @@ +/* + * 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_INSTANCE_H__ +#define __MQ_CLIENT_INSTANCE_H__ + +#include +#include +#include + +#include "ConsumerRunningInfo.h" +#include "FindBrokerResult.h" +#include "HeartbeatData.h" +#include "MQClientConfig.h" +#include "MQClientException.h" +#include "MQConsumerInner.h" +#include "MQMessageQueue.h" +#include "MQProducerInner.h" +#include "ServiceState.h" +#include "TopicPublishInfo.h" +#include "TopicRouteData.h" +#include "concurrent/executor.hpp" + +namespace rocketmq { + +class RPCHook; +class MQClientAPIImpl; +class MQAdminImpl; +class ClientRemotingProcessor; +class RebalanceService; +class PullMessageService; + +class MQClientInstance; +typedef std::shared_ptr MQClientInstancePtr; + +class MQClientInstance { + public: + MQClientInstance(MQClientConfig clientConfig, const std::string& clientId); + MQClientInstance(MQClientConfig clientConfig, const std::string& clientId, std::shared_ptr rpcHook); + virtual ~MQClientInstance(); + + static TopicPublishInfoPtr topicRouteData2TopicPublishInfo(const std::string& topic, TopicRouteDataPtr route); + static std::vector topicRouteData2TopicSubscribeInfo(const std::string& topic, + TopicRouteDataPtr route); + + std::string getClientId(); + + void start(); + void shutdown(); + bool isRunning(); + + bool registerProducer(const std::string& group, MQProducerInner* producer); + void unregisterProducer(const std::string& group); + + bool registerConsumer(const std::string& group, MQConsumerInner* consumer); + void unregisterConsumer(const std::string& group); + + void updateTopicRouteInfoFromNameServer(); + bool updateTopicRouteInfoFromNameServer(const std::string& topic, bool isDefault = false); + + void sendHeartbeatToAllBrokerWithLock(); + + void rebalanceImmediately(); + void doRebalance(); + + MQProducerInner* selectProducer(const std::string& group); + MQConsumerInner* selectConsumer(const std::string& group); + + FindBrokerResult* findBrokerAddressInAdmin(const std::string& brokerName); + std::string findBrokerAddressInPublish(const std::string& brokerName); + FindBrokerResult* findBrokerAddressInSubscribe(const std::string& brokerName, int brokerId, bool onlyThisBroker); + + void findConsumerIds(const std::string& topic, const std::string& group, std::vector& cids); + + std::string findBrokerAddrByTopic(const std::string& topic); + + void resetOffset(const std::string& group, + const std::string& topic, + const std::map& offsetTable); + + ConsumerRunningInfo* consumerRunningInfo(const std::string& consumerGroup); + + public: + TopicPublishInfoPtr tryToFindTopicPublishInfo(const std::string& topic); + + public: + MQClientAPIImpl* getMQClientAPIImpl() const { return m_mqClientAPIImpl.get(); } + MQAdminImpl* getMQAdminImpl() const { return m_mqAdminImpl.get(); } + PullMessageService* getPullMessageService() const { return m_pullMessageService.get(); } + + private: + typedef std::map> BrokerAddrMAP; + + void unregisterClientWithLock(const std::string& producerGroup, const std::string& consumerGroup); + void unregisterClient(const std::string& producerGroup, const std::string& consumerGroup); + + void addBrokerToAddrTable(const std::string& brokerName, const std::map& brokerAddrs); + void resetBrokerAddrTable(BrokerAddrMAP&& table); + void clearBrokerAddrTable(); + BrokerAddrMAP getBrokerAddrTable(); + + void cleanOfflineBroker(); + bool isBrokerAddrExistInTopicRouteTable(const std::string& addr); + + // scheduled task + void startScheduledTask(); + void updateTopicRouteInfoPeriodically(); + void sendHeartbeatToAllBrokerPeriodically(); + void persistAllConsumerOffsetPeriodically(); + + // topic route + bool topicRouteDataIsChange(TopicRouteData* old, TopicRouteData* now); + TopicRouteDataPtr getTopicRouteData(const std::string& topic); + void addTopicRouteData(const std::string& topic, TopicRouteDataPtr topicRouteData); + + // heartbeat + void sendHeartbeatToAllBroker(); + HeartbeatData* prepareHeartbeatData(); + void insertConsumerInfoToHeartBeatData(HeartbeatData* pHeartbeatData); + void insertProducerInfoToHeartBeatData(HeartbeatData* pHeartbeatData); + + // offset + void persistAllConsumerOffset(); + + // rebalance + void doRebalanceByConsumerGroup(const std::string& consumerGroup); + + // consumer related operation + bool addConsumerToTable(const std::string& consumerName, MQConsumerInner* consumer); + void eraseConsumerFromTable(const std::string& consumerName); + int getConsumerTableSize(); + void getTopicListFromConsumerSubscription(std::set& topicList); + void updateConsumerTopicSubscribeInfo(const std::string& topic, std::vector subscribeInfo); + + // producer related operation + bool addProducerToTable(const std::string& producerName, MQProducerInner* producer); + void eraseProducerFromTable(const std::string& producerName); + int getProducerTableSize(); + void getTopicListFromTopicPublishInfo(std::set& topicList); + void updateProducerTopicPublishInfo(const std::string& topic, TopicPublishInfoPtr publishInfo); + + // topicPublishInfo related operation + void addTopicInfoToTable(const std::string& topic, TopicPublishInfoPtr pTopicPublishInfo); + void eraseTopicInfoFromTable(const std::string& topic); + TopicPublishInfoPtr getTopicPublishInfoFromTable(const std::string& topic); + bool isTopicInfoValidInTable(const std::string& topic); + + private: + MQClientConfig m_clientConfig; + std::string m_clientId; + ServiceState m_serviceState; + + // group -> MQProducer + typedef std::map MQPMAP; + MQPMAP m_producerTable; + std::mutex m_producerTableMutex; + + // group -> MQConsumer + typedef std::map MQCMAP; + MQCMAP m_consumerTable; + std::mutex m_consumerTableMutex; + + // Topic -> TopicRouteData + typedef std::map TRDMAP; + TRDMAP m_topicRouteTable; + std::mutex m_topicRouteTableMutex; + + // brokerName -> [ brokerid : addr ] + BrokerAddrMAP m_brokerAddrTable; + std::mutex m_brokerAddrTableMutex; + + // topic -> TopicPublishInfo + typedef std::map TPMAP; + TPMAP m_topicPublishInfoTable; + std::mutex m_topicPublishInfoTableMutex; + + std::timed_mutex m_lockNamesrv; + std::timed_mutex m_lockHeartbeat; + + std::unique_ptr m_mqClientAPIImpl; + std::unique_ptr m_mqAdminImpl; + std::unique_ptr m_clientRemotingProcessor; + + std::unique_ptr m_rebalanceService; + std::unique_ptr m_pullMessageService; + scheduled_thread_pool_executor m_scheduledExecutorService; +}; + +} // namespace rocketmq + +#endif // __MQ_CLIENT_INSTANCE_H__ diff --git a/src/MQClientManager.cpp b/src/MQClientManager.cpp index de35ddd7d..d768e8e61 100644 --- a/src/MQClientManager.cpp +++ b/src/MQClientManager.cpp @@ -15,43 +15,45 @@ * limitations under the License. */ #include "MQClientManager.h" + #include "Logging.h" namespace rocketmq { -// rpcHook) { + std::string clientId = clientConfig->buildMQClientId(); + std::lock_guard lock(m_mutex); + auto it = m_instanceTable.find(clientId); + if (it != m_instanceTable.end()) { return it->second; } else { - MQClientFactory* factory = - new MQClientFactory(clientId, pullThreadNum, tcpConnectTimeout, tcpTransportTryLockTimeout, unitName); - m_factoryTable[clientId] = factory; - return factory; + // clone clientConfig + auto instance = std::make_shared(*clientConfig, clientId, rpcHook); + m_instanceTable[clientId] = instance; + LOG_INFO_NEW("Created new MQClientInstance for clientId:[{}]", clientId); + return instance; } } -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); +void MQClientManager::removeMQClientInstance(const std::string& clientId) { + std::lock_guard lock(m_mutex); + auto it = m_instanceTable.find(clientId); + if (it != m_instanceTable.end()) { + m_instanceTable.erase(it); } } -// +#include #include -#include "Logging.h" -#include "MQClientFactory.h" + +#include "MQClientInstance.h" namespace rocketmq { -// rpcHook); + + void removeMQClientInstance(const std::string& clientId); private: MQClientManager(); private: - typedef map FTMAP; - FTMAP m_factoryTable; + std::map m_instanceTable; + std::mutex m_mutex; }; -//(m_pAsyncCallBack); - if (pCallback) { - unique_ptr 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 pResponse(pResponseFuture->getCommand()); - - if (m_pAsyncCallBack == NULL) { - return; - } - int opaque = pResponseFuture->getOpaque(); - SendCallback* pCallback = static_cast(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); - } -} - -//(pArg); -} - -PullCallbackWarp::~PullCallbackWarp() {} - -void PullCallbackWarp::onException() { - if (m_pAsyncCallBack == NULL) - return; - - PullCallback* pCallback = static_cast(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 PullCallbackWarp::operationComplete(ResponseFuture* pResponseFuture, bool bProducePullRequest) { - unique_ptr pResponse(pResponseFuture->getCommand()); - if (m_pAsyncCallBack == NULL) { - LOG_ERROR("m_pAsyncCallBack is NULL, AsyncPull could not continue"); - return; - } - PullCallback* pCallback = static_cast(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(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(e.what()); - MQException exception("pullResult error", -1, __FILE__, __LINE__); - if (pCallback && bProducePullRequest) - pCallback->onException(exception); - } - } -} - -// -#include -#include -#include -#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((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(bytes); -} -inline uint64 ByteOrder::littleEndianInt64(const void* const bytes) { - return *static_cast(bytes); -} -inline uint16 ByteOrder::littleEndianShort(const void* const bytes) { - return *static_cast(bytes); -} -inline uint32 ByteOrder::bigEndianInt(const void* const bytes) { - return swap(*static_cast(bytes)); -} -inline uint64 ByteOrder::bigEndianInt64(const void* const bytes) { - return swap(*static_cast(bytes)); -} -inline uint16 ByteOrder::bigEndianShort(const void* const bytes) { - return swap(*static_cast(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(bytes)); -} -inline uint64 ByteOrder::littleEndianInt64(const void* const bytes) { - return swap(*static_cast(bytes)); -} -inline uint16 ByteOrder::littleEndianShort(const void* const bytes) { - return swap(*static_cast(bytes)); -} -inline uint32 ByteOrder::bigEndianInt(const void* const bytes) { - return *static_cast(bytes); -} -inline uint64 ByteOrder::bigEndianInt64(const void* const bytes) { - return *static_cast(bytes); -} -inline uint16 ByteOrder::bigEndianShort(const void* const bytes) { - return *static_cast(bytes); -} -inline bool ByteOrder::isBigEndian() { - return true; -} -#endif - -inline int ByteOrder::littleEndian24Bit(const void* const bytes) { - return (((int)static_cast(bytes)[2]) << 16) | (((int)static_cast(bytes)[1]) << 8) | - ((int)static_cast(bytes)[0]); -} -inline int ByteOrder::bigEndian24Bit(const void* const bytes) { - return (((int)static_cast(bytes)[0]) << 16) | (((int)static_cast(bytes)[1]) << 8) | - ((int)static_cast(bytes)[2]); -} -inline void ByteOrder::littleEndian24BitToChars(const int value, void* const destBytes) { - static_cast(destBytes)[0] = (uint8)value; - static_cast(destBytes)[1] = (uint8)(value >> 8); - static_cast(destBytes)[2] = (uint8)(value >> 16); -} -inline void ByteOrder::bigEndian24BitToChars(const int value, void* const destBytes) { - static_cast(destBytes)[0] = (uint8)(value >> 16); - static_cast(destBytes)[1] = (uint8)(value >> 8); - static_cast(destBytes)[2] = (uint8)value; -} -} -#endif // BYTEORDER_H_INCLUDED +/* + * 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 __BYTE_ORDER_H__ +#define __BYTE_ORDER_H__ + +#include + +namespace rocketmq { + +/** + * Contains static methods for converting the byte order between different endiannesses. + */ +class ROCKETMQCLIENT_API ByteOrder { + public: + //============================================================================== + /** Swaps the upper and lower bytes of a 16-bit integer. */ + static uint16_t swap(uint16_t value); + + /** Reverses the order of the 4 bytes in a 32-bit integer. */ + static uint32_t swap(uint32_t value); + + /** Reverses the order of the 8 bytes in a 64-bit integer. */ + static uint64_t swap(uint64_t value); + + //============================================================================== + /** Swaps the byte order of a 16-bit int if the CPU is big-endian */ + static uint16_t swapIfBigEndian(uint16_t value); + + /** Swaps the byte order of a 32-bit int if the CPU is big-endian */ + static uint32_t swapIfBigEndian(uint32_t value); + + /** Swaps the byte order of a 64-bit int if the CPU is big-endian */ + static uint64_t swapIfBigEndian(uint64_t value); + + /** Swaps the byte order of a 16-bit int if the CPU is little-endian */ + static uint16_t swapIfLittleEndian(uint16_t value); + + /** Swaps the byte order of a 32-bit int if the CPU is little-endian */ + static uint32_t swapIfLittleEndian(uint32_t value); + + /** Swaps the byte order of a 64-bit int if the CPU is little-endian */ + static uint64_t swapIfLittleEndian(uint64_t value); + + //============================================================================== + /** Turns 4 bytes into a little-endian integer. */ + static uint32_t littleEndianInt(const void* bytes); + + /** Turns 8 bytes into a little-endian integer. */ + static uint64_t littleEndianInt64(const void* bytes); + + /** Turns 2 bytes into a little-endian integer. */ + static uint16_t littleEndianShort(const void* bytes); + + /** Turns 4 bytes into a big-endian integer. */ + static uint32_t bigEndianInt(const void* bytes); + + /** Turns 8 bytes into a big-endian integer. */ + static uint64_t bigEndianInt64(const void* bytes); + + /** Turns 2 bytes into a big-endian integer. */ + static uint16_t 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_t ByteOrder::swap(uint16_t n) { + return static_cast((n << 8) | (n >> 8)); +} + +inline uint32_t ByteOrder::swap(uint32_t n) { + return (n << 24) | (n >> 24) | ((n & 0xff00) << 8) | ((n & 0xff0000) >> 8); +} + +inline uint64_t ByteOrder::swap(uint64_t value) { + return (((uint64_t)swap((uint32_t)value)) << 32) | swap((uint32_t)(value >> 32)); +} + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ //__BYTE_ORDER__ is defined by GCC +inline uint16_t ByteOrder::swapIfBigEndian(const uint16_t v) { + return v; +} + +inline uint32_t ByteOrder::swapIfBigEndian(const uint32_t v) { + return v; +} + +inline uint64_t ByteOrder::swapIfBigEndian(const uint64_t v) { + return v; +} + +inline uint16_t ByteOrder::swapIfLittleEndian(const uint16_t v) { + return swap(v); +} + +inline uint32_t ByteOrder::swapIfLittleEndian(const uint32_t v) { + return swap(v); +} + +inline uint64_t ByteOrder::swapIfLittleEndian(const uint64_t v) { + return swap(v); +} + +inline uint32_t ByteOrder::littleEndianInt(const void* const bytes) { + return *static_cast(bytes); +} + +inline uint64_t ByteOrder::littleEndianInt64(const void* const bytes) { + return *static_cast(bytes); +} + +inline uint16_t ByteOrder::littleEndianShort(const void* const bytes) { + return *static_cast(bytes); +} + +inline uint32_t ByteOrder::bigEndianInt(const void* const bytes) { + return swap(*static_cast(bytes)); +} + +inline uint64_t ByteOrder::bigEndianInt64(const void* const bytes) { + return swap(*static_cast(bytes)); +} + +inline uint16_t ByteOrder::bigEndianShort(const void* const bytes) { + return swap(*static_cast(bytes)); +} + +inline bool ByteOrder::isBigEndian() { + return false; +} +#else +inline uint16_t ByteOrder::swapIfBigEndian(const uint16_t v) { + return swap(v); +} + +inline uint32_t ByteOrder::swapIfBigEndian(const uint32_t v) { + return swap(v); +} + +inline uint64_t ByteOrder::swapIfBigEndian(const uint64_t v) { + return swap(v); +} + +inline uint16_t ByteOrder::swapIfLittleEndian(const uint16_t v) { + return v; +} + +inline uint32_t ByteOrder::swapIfLittleEndian(const uint32_t v) { + return v; +} + +inline uint64_t ByteOrder::swapIfLittleEndian(const uint64_t v) { + return v; +} + +inline uint32_t ByteOrder::littleEndianInt(const void* const bytes) { + return swap(*static_cast(bytes)); +} + +inline uint64_t ByteOrder::littleEndianInt64(const void* const bytes) { + return swap(*static_cast(bytes)); +} + +inline uint16_t ByteOrder::littleEndianShort(const void* const bytes) { + return swap(*static_cast(bytes)); +} + +inline uint32_t ByteOrder::bigEndianInt(const void* const bytes) { + return *static_cast(bytes); +} + +inline uint64_t ByteOrder::bigEndianInt64(const void* const bytes) { + return *static_cast(bytes); +} + +inline uint16_t ByteOrder::bigEndianShort(const void* const bytes) { + return *static_cast(bytes); +} + +inline bool ByteOrder::isBigEndian() { + return true; +} +#endif + +inline int ByteOrder::littleEndian24Bit(const void* const bytes) { + return (((int)static_cast(bytes)[2]) << 16) | (((int)static_cast(bytes)[1]) << 8) | + ((int)static_cast(bytes)[0]); +} + +inline int ByteOrder::bigEndian24Bit(const void* const bytes) { + return (((int)static_cast(bytes)[0]) << 16) | (((int)static_cast(bytes)[1]) << 8) | + ((int)static_cast(bytes)[2]); +} + +inline void ByteOrder::littleEndian24BitToChars(const int value, void* const destBytes) { + static_cast(destBytes)[0] = (uint8_t)value; + static_cast(destBytes)[1] = (uint8_t)(value >> 8); + static_cast(destBytes)[2] = (uint8_t)(value >> 16); +} + +inline void ByteOrder::bigEndian24BitToChars(const int value, void* const destBytes) { + static_cast(destBytes)[0] = (uint8_t)(value >> 16); + static_cast(destBytes)[1] = (uint8_t)(value >> 8); + static_cast(destBytes)[2] = (uint8_t)value; +} + +} // namespace rocketmq + +#endif // __BYTE_ORDER_H__ diff --git a/src/common/ClientRPCHook.cpp b/src/common/ClientRPCHook.cpp index cd216d10b..0f7c101df 100644 --- a/src/common/ClientRPCHook.cpp +++ b/src/common/ClientRPCHook.cpp @@ -14,62 +14,76 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "ClientRPCHook.h" + +#include + #include "CommandHeader.h" +#include "DataBlock.h" #include "Logging.h" -extern "C" { +#include "RemotingCommand.h" + #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"; +const std::string SessionCredentials::AccessKey = "AccessKey"; +const std::string SessionCredentials::SecretKey = "SecretKey"; +const std::string SessionCredentials::Signature = "Signature"; +const std::string SessionCredentials::SignatureMethod = "SignatureMethod"; +const std::string SessionCredentials::ONSChannelKey = "OnsChannel"; -void ClientRPCHook::doBeforeRequest(const string& remoteAddr, RemotingCommand& request) { - CommandHeader* header = request.getCommandHeader(); +void ClientRPCHook::doBeforeRequest(const std::string& remoteAddr, RemotingCommand& request, bool toSent) { + if (toSent) { + // sign request + signCommand(request); + } +} - map requestMap; - string totalMsg; +void ClientRPCHook::doAfterResponse(const std::string& remoteAddr, + RemotingCommand& request, + RemotingCommand* response, + bool toSent) { + if (toSent && response != nullptr) { + // sign response + signCommand(*response); + } +} - requestMap.insert(pair(SessionCredentials::AccessKey, sessionCredentials.getAccessKey())); - requestMap.insert(pair(SessionCredentials::ONSChannelKey, sessionCredentials.getAuthChannel())); +void ClientRPCHook::signCommand(RemotingCommand& command) { + std::map headerMap; + headerMap.insert(std::make_pair(SessionCredentials::AccessKey, sessionCredentials_.getAccessKey())); + headerMap.insert(std::make_pair(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("before insert declared filed, MAP SIZE is:" SIZET_FMT "", headerMap.size()); + auto* header = command.readCustomHeader(); + if (header != nullptr) { + header->SetDeclaredFieldOfCommandHeader(headerMap); } - LOG_DEBUG("after insert declared filed, MAP SIZE is:" SIZET_FMT "", requestMap.size()); + LOG_DEBUG("after insert declared filed, MAP SIZE is:" SIZET_FMT "", headerMap.size()); - map::iterator it = requestMap.begin(); - for (; it != requestMap.end(); ++it) { - totalMsg.append(it->second); + std::string totalMsg; + for (const auto& it : headerMap) { + 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()); + auto body = command.getBody(); + if (body != nullptr && body->getSize() > 0) { + LOG_DEBUG_NEW("request have msgBody, length is:{}", body->getSize()); + totalMsg.append(body->getData(), body->getSize()); } 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(pSignature)); - request.addExtField(SessionCredentials::Signature, signature); - request.addExtField(SessionCredentials::AccessKey, sessionCredentials.getAccessKey()); - request.addExtField(SessionCredentials::ONSChannelKey, sessionCredentials.getAuthChannel()); + char* pSignature = + rocketmqSignature::spas_sign(totalMsg.c_str(), totalMsg.size(), sessionCredentials_.getSecretKey().c_str()); + if (pSignature != nullptr) { + std::string signature(static_cast(pSignature)); + command.addExtField(SessionCredentials::Signature, signature); + command.addExtField(SessionCredentials::AccessKey, sessionCredentials_.getAccessKey()); + command.addExtField(SessionCredentials::ONSChannelKey, sessionCredentials_.getAuthChannel()); rocketmqSignature::spas_mem_free(pSignature); } else { LOG_ERROR("signature for request failed"); } } -} + +} // namespace rocketmq diff --git a/src/common/CommunicationMode.h b/src/common/CommunicationMode.h index 6ba947ab6..bf8c0fe36 100644 --- a/src/common/CommunicationMode.h +++ b/src/common/CommunicationMode.h @@ -14,14 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#ifndef __COMMUNICATIONMODE_H__ -#define __COMMUNICATIONMODE_H__ +#ifndef __COMMUNICATION_MODE_H__ +#define __COMMUNICATION_MODE_H__ namespace rocketmq { -// +#include +#include + +namespace rocketmq { + +//###################################### +// MemoryBlock +//###################################### + +void MemoryBlock::copyTo(void* dst, ssize_t offset, size_t num) const { + char* d = static_cast(dst); + + if (offset < 0) { + memset(d, 0, -offset); + d += (-offset); + num -= (-offset); + offset = 0; + } + + if (offset + num > size_) { + size_t newNum = size_ - offset; + memset(d + newNum, 0, num - newNum); + num = newNum; + } + + if (num > 0) { + memcpy(d, data_ + offset, num); + } +} + +//###################################### +// MemoryPool +//###################################### + +MemoryPool::MemoryPool() : MemoryBlock() {} + +MemoryPool::MemoryPool(size_t initialSize, bool initialiseToZero) : MemoryBlock(nullptr, initialSize) { + if (size_ > 0) { + data_ = static_cast(initialiseToZero ? std::calloc(initialSize, sizeof(char)) + : std::malloc(initialSize * sizeof(char))); + } +} + +MemoryPool::MemoryPool(const void* const dataToInitialiseFrom, size_t sizeInBytes) : MemoryBlock(nullptr, sizeInBytes) { + if (size_ > 0) { + data_ = static_cast(std::malloc(size_ * sizeof(char))); + + if (dataToInitialiseFrom != nullptr) { + memcpy(data_, dataToInitialiseFrom, size_); + } + } +} + +MemoryPool::MemoryPool(const MemoryPool& other) : MemoryBlock(nullptr, other.size_) { + if (size_ > 0) { + data_ = static_cast(std::malloc(size_ * sizeof(char))); + memcpy(data_, other.data_, size_); + } +} + +MemoryPool::MemoryPool(MemoryPool&& other) : MemoryBlock(other.data_, other.size_) { + other.size_ = 0; + other.data_ = nullptr; +} + +MemoryPool::~MemoryPool() { + std::free(data_); +} + +MemoryPool& MemoryPool::operator=(const MemoryPool& other) { + if (this != &other) { + setSize(other.size_, false); + memcpy(data_, other.data_, size_); + } + return *this; +} + +MemoryPool& MemoryPool::operator=(MemoryPool&& other) { + if (this != &other) { + std::free(data_); + + size_ = other.size_; + data_ = other.data_; + + other.size_ = 0; + other.data_ = nullptr; + } + return *this; +} + +//============================================================================== +bool MemoryPool::matches(const void* dataToCompare, size_t dataSize) const { + return size_ == dataSize && memcmp(data_, dataToCompare, size_) == 0; +} + +bool MemoryPool::operator==(const MemoryPool& other) const { + return matches(other.data_, other.size_); +} + +bool MemoryPool::operator!=(const MemoryPool& other) const { + return !operator==(other); +} + +//============================================================================== +void MemoryPool::reset() { + reset(nullptr, 0); +} + +void MemoryPool::reset(char* data, size_t size) { + if (size != 0) { + throw std::runtime_error("MemoryBlock can't set external pointer as data."); + } + + std::free(data_); + data_ = nullptr; + size_ = 0; +} + +// this will resize the block to this size_ +void MemoryPool::setSize(size_t newSize, bool initialiseToZero) { + if (size_ != newSize) { + if (newSize <= 0) { + reset(); + } else { + if (data_ != nullptr) { + data_ = static_cast(std::realloc(data_, newSize * sizeof(char))); + + if (initialiseToZero && (newSize > size_)) { + memset(data_ + size_, 0, newSize - size_); + } + } else { + data_ = static_cast(initialiseToZero ? std::calloc(newSize, sizeof(char)) + : std::malloc(newSize * sizeof(char))); + } + + size_ = newSize; + } + } +} + +void MemoryPool::ensureSize(size_t minimumSize, bool initialiseToZero) { + if (size_ < minimumSize) { + setSize(minimumSize, initialiseToZero); + } +} + +//============================================================================== +void MemoryPool::fillWith(int value) { + memset(data_, value, size_); +} + +void MemoryPool::append(const void* const srcData, size_t numBytes) { + if (numBytes > 0) { + size_t oldSize = size_; + setSize(size_ + numBytes); + memcpy(data_ + oldSize, srcData, numBytes); + } +} + +void MemoryPool::replaceWith(const void* const srcData, size_t numBytes) { + if (numBytes > 0) { + setSize(numBytes); + memcpy(data_, srcData, numBytes); + } +} + +void MemoryPool::insert(const void* const srcData, size_t numBytes, size_t insertPosition) { + if (numBytes > 0) { + insertPosition = std::min(insertPosition, size_); + size_t trailingDataSize = size_ - insertPosition; + setSize(size_ + numBytes, false); + + if (trailingDataSize > 0) { + memmove(data_ + insertPosition + numBytes, data_ + insertPosition, trailingDataSize); + } + + memcpy(data_ + insertPosition, srcData, numBytes); + } +} + +void MemoryPool::removeSection(size_t startByte, size_t numBytesToRemove) { + if (startByte + numBytesToRemove >= size_) { + setSize(startByte); + } else if (numBytesToRemove > 0) { + memmove(data_ + startByte, data_ + startByte + numBytesToRemove, size_ - (startByte + numBytesToRemove)); + setSize(size_ - numBytesToRemove); + } +} + +void MemoryPool::copyFrom(const void* src, ssize_t offset, size_t num) { + const char* d = static_cast(src); + + if (offset < 0) { + d += (-offset); + num -= (-offset); + offset = 0; + } + + if (offset + num > size_) { + num = size_ - offset; + } + + if (num > 0) { + memcpy(data_ + offset, d, num); + } +} + +//###################################### +// MemoryView +//###################################### + +void MemoryView::reset() { + reset(nullptr, 0); +} + +void MemoryView::reset(char* data, size_t size) { + throw std::runtime_error("MemoryView can't reset()."); +} + +} // namespace rocketmq diff --git a/src/common/DataBlock.h b/src/common/DataBlock.h new file mode 100644 index 000000000..08a64046c --- /dev/null +++ b/src/common/DataBlock.h @@ -0,0 +1,211 @@ +/* + * 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 __DATA_BLOCK_H__ +#define __DATA_BLOCK_H__ + +#include + +#include "RocketMQClient.h" + +namespace rocketmq { + +class MemoryBlock; +typedef MemoryBlock* MemoryBlockPtr; +typedef std::shared_ptr MemoryBlockPtr2; +typedef std::unique_ptr MemoryBlockPtr3; + +class ROCKETMQCLIENT_API MemoryBlock { + public: + MemoryBlock() : MemoryBlock(nullptr, 0) {} + MemoryBlock(char* data, size_t size) : data_(data), size_(size) {} + virtual ~MemoryBlock() = default; + + /** Returns a void pointer to the data. + * + * Note that the pointer returned will probably become invalid when the block is resized. + */ + char* getData() { return data_; } + + const char* getData() const { return data_; } + + /** Returns the block's current allocated size, in bytes. */ + size_t getSize() const { return size_; } + + /** Returns a byte from the memory block. + * This returns a reference, so you can also use it to set a byte. + */ + template + char& operator[](const Type offset) { + return data_[offset]; + } + + template + const char& operator[](const Type offset) const { + return data_[offset]; + } + + /** Frees all the blocks data, setting its size to 0. */ + virtual void reset() { reset(nullptr, 0); } + + virtual void reset(char* data, size_t size) { + data_ = data; + size_ = size; + } + + /** 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, ssize_t sourceOffset, size_t numBytes) const; + + protected: + char* data_; + size_t size_; +}; + +class ROCKETMQCLIENT_API MemoryPool : public MemoryBlock { + public: + /** Create an uninitialised block with 0 size. */ + MemoryPool(); + + /** 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 + */ + MemoryPool(size_t 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 + */ + MemoryPool(const void* dataToInitialiseFrom, size_t sizeInBytes); + + /** Creates a copy of another memory block. */ + MemoryPool(const MemoryPool&); + + MemoryPool(MemoryPool&&); + + /** Destructor. */ + ~MemoryPool(); + + /** Copies another memory block onto this one. + * This block will be resized and copied to exactly match the other one. + */ + MemoryPool& operator=(const MemoryPool&); + + MemoryPool& operator=(MemoryPool&&); + + /** Returns true if the data in this MemoryBlock matches the raw bytes passed-in. */ + bool matches(const void* data, size_t dataSize) const; + + /** Compares two memory blocks. + * @returns true only if the two blocks are the same size and have identical contents. + */ + bool operator==(const MemoryPool& other) const; + + /** Compares two memory blocks. + * @returns true if the two blocks are different sizes or have different contents. + */ + bool operator!=(const MemoryPool& other) const; + + void reset() override; + void reset(char* data, size_t size) override; + + /** 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(size_t 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(size_t minimumSize, bool initialiseNewSpaceToZero = false); + + /** 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 increasedaccordingly. + */ + void append(const void* data, size_t 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, size_t 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, size_t numBytesToInsert, size_t 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(size_t startByte, size_t 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, ssize_t destinationOffset, size_t numBytes); +}; + +class ROCKETMQCLIENT_API MemoryView : public MemoryBlock { + public: + MemoryView(MemoryBlockPtr2 origin, size_t offset) : MemoryView(origin, offset, origin->getSize() - offset) {} + MemoryView(MemoryBlockPtr2 origin, size_t offset, size_t size) + : MemoryBlock(origin->getData() + offset, size), origin_(origin) {} + + void reset() override; + void reset(char* data, size_t size) override; + + private: + MemoryBlockPtr2 origin_; +}; + +} // namespace rocketmq + +#endif // __DATA_BLOCK_H__ diff --git a/src/common/FilterAPI.h b/src/common/FilterAPI.h index d632bc232..86e89a8ef 100644 --- a/src/common/FilterAPI.h +++ b/src/common/FilterAPI.h @@ -14,48 +14,48 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#ifndef __FILTERAPI_H__ -#define __FILTERAPI_H__ +#ifndef __FILTER_API_H__ +#define __FILTER_API_H__ #include + #include "MQClientException.h" #include "SubscriptionData.h" #include "UtilAll.h" + namespace rocketmq { -// subscriptionData(new SubscriptionData(topic, subString)); if (subString.empty() || !subString.compare(SUB_ALL)) { subscriptionData->setSubString(SUB_ALL); } else { - vector out; - UtilAll::Split(out, subString, "||"); + std::vector tags; + UtilAll::Split(tags, 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 (!tags.empty()) { + for (auto tag : tags) { if (!tag.empty()) { - subscriptionData->putTagsSet(tag); - subscriptionData->putCodeSet(tag); + UtilAll::Trim(tag); + if (!tag.empty()) { + subscriptionData->putTagsSet(tag); + subscriptionData->putCodeSet(UtilAll::HashCode(tag)); + } } } + } else { + THROW_MQEXCEPTION(MQClientException, "FilterAPI subString split error", -1); } } - return subscriptionData; + return subscriptionData.release(); } }; -// -#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(std::malloc(skipBufferSize * sizeof(char))); - - while (numBytesToSkip > 0 && !isExhausted()) - numBytesToSkip -= read(temp, (int)std::min(numBytesToSkip, (int64)skipBufferSize)); - - std::free(temp); - } -} -} +/* + * 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 + +#include "MemoryOutputStream.h" +#include "big_endian.h" + +namespace rocketmq { + +int64_t InputStream::getNumBytesRemaining() { + int64_t 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_t InputStream::readInt64BigEndian() { + char asBytes[8]; + uint64_t 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_t asInt; + double asDouble; + } n; + n.asInt = readInt64BigEndian(); + return n.asDouble; +} + +size_t InputStream::readIntoMemoryBlock(MemoryPool& block, size_t numBytes) { + MemoryOutputStream mo(block, true); + return (size_t)mo.writeFromInputStream(*this, numBytes); +} + +//============================================================================== +void InputStream::skipNextBytes(int64_t numBytesToSkip) { + if (numBytesToSkip > 0) { + const int skipBufferSize = (int)std::min(numBytesToSkip, (int64_t)16384); + char* temp = static_cast(std::malloc(skipBufferSize * sizeof(char))); + + while (numBytesToSkip > 0 && !isExhausted()) + numBytesToSkip -= read(temp, (int)std::min(numBytesToSkip, (int64_t)skipBufferSize)); + + std::free(temp); + } +} +} // namespace rocketmq diff --git a/src/common/InputStream.h b/src/common/InputStream.h index 8c6ddb51a..12a07fb01 100644 --- a/src/common/InputStream.h +++ b/src/common/InputStream.h @@ -1,194 +1,193 @@ -/* -* 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() {} -}; -} -#endif // INPUTSTREAM_H_INCLUDED +/* + * 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_t getTotalLength() = 0; + + /** Returns the number of bytes available for reading, or a negative value if + the remaining length is not known. + @see getTotalLength + */ + int64_t 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_t 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_t. + 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(MemoryPool& destBlock, size_t maxNumBytesToRead = -1); + + //============================================================================== + /** Returns the offset of the next byte that will be read from the stream. + @see setPosition + */ + virtual int64_t 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_t 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_t numBytesToSkip); + + protected: + //============================================================================== + InputStream() {} +}; +} // namespace rocketmq +#endif // INPUTSTREAM_H_INCLUDED diff --git a/include/BatchMessage.h b/src/common/InvokeCallback.h similarity index 76% rename from include/BatchMessage.h rename to src/common/InvokeCallback.h index bca467a00..676222710 100644 --- a/include/BatchMessage.h +++ b/src/common/InvokeCallback.h @@ -14,16 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef __INVOKE_CALLBACK_H__ +#define __INVOKE_CALLBACK_H__ -#ifndef __BATCHMESSAGE_H__ -#define __BATCHMESSAGE_H__ -#include -#include "MQMessage.h" namespace rocketmq { -class BatchMessage : public MQMessage { + +class ResponseFuture; + +class InvokeCallback { public: - static std::string encode(std::vector& msgs); - static std::string encode(MQMessage& message); + virtual ~InvokeCallback() = default; + virtual void operationComplete(ResponseFuture* responseFuture) noexcept = 0; }; + } // namespace rocketmq -#endif \ No newline at end of file + +#endif // __INVOKE_CALLBACK_H__ diff --git a/src/common/MQClient.cpp b/src/common/MQClient.cpp deleted file mode 100644 index f638f6f44..000000000 --- a/src/common/MQClient.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* - * 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 "MQClient.h" -#include "Logging.h" -#include "MQClientFactory.h" -#include "MQClientManager.h" -#include "NameSpaceUtil.h" -#include "TopicPublishInfo.h" -#include "UtilAll.h" - -namespace rocketmq { - -#define ROCKETMQCPP_VERSION "1.2.4" -#define BUILD_DATE "11-11-2019" -// display version: strings bin/librocketmq.so |grep VERSION -const char* rocketmq_build_time = "VERSION: " ROCKETMQCPP_VERSION ", BUILD DATE: " BUILD_DATE " "; - -//createTopic(key, newTopic, queueNum, m_SessionCredentials); - } catch (MQException& e) { - LOG_ERROR(e.what()); - } -} - -int64 MQClient::earliestMsgStoreTime(const MQMessageQueue& mq) { - return getFactory()->earliestMsgStoreTime(mq, m_SessionCredentials); -} - -QueryResult MQClient::queryMessage(const string& topic, const string& key, int maxNum, int64 begin, int64 end) { - return getFactory()->queryMessage(topic, key, maxNum, begin, end, m_SessionCredentials); -} - -int64 MQClient::minOffset(const MQMessageQueue& mq) { - return getFactory()->minOffset(mq, m_SessionCredentials); -} - -int64 MQClient::maxOffset(const MQMessageQueue& mq) { - return getFactory()->maxOffset(mq, m_SessionCredentials); -} - -int64 MQClient::searchOffset(const MQMessageQueue& mq, uint64_t timestamp) { - return getFactory()->searchOffset(mq, timestamp, m_SessionCredentials); -} - -MQMessageExt* MQClient::viewMessage(const string& msgId) { - return getFactory()->viewMessage(msgId, m_SessionCredentials); -} - -vector MQClient::getTopicMessageQueueInfo(const string& topic) { - boost::weak_ptr weak_topicPublishInfo( - getFactory()->tryToFindTopicPublishInfo(topic, m_SessionCredentials)); - boost::shared_ptr topicPublishInfo(weak_topicPublishInfo.lock()); - if (topicPublishInfo) { - return topicPublishInfo->getMessageQueueList(); - } - THROW_MQEXCEPTION(MQClientException, "could not find MessageQueue Info of topic: [" + topic + "].", -1); -} - -void MQClient::start() { - if (getFactory() == NULL) { - m_clientFactory = MQClientManager::getInstance()->getMQClientFactory( - getMQClientId(), m_pullThreadNum, m_tcpConnectTimeout, m_tcpTransportTryLockTimeout, m_unitName); - } - 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 MQClient::shutdown() { - m_clientFactory->shutdown(); - m_clientFactory = NULL; -} - -MQClientFactory* MQClient::getFactory() const { - return m_clientFactory; -} - -bool MQClient::isServiceStateOk() { - return m_serviceState == RUNNING; -} - -void MQClient::setLogLevel(elogLevel inputLevel) { - ALOG_ADAPTER->setLogLevel(inputLevel); -} - -elogLevel MQClient::getLogLevel() { - return ALOG_ADAPTER->getLogLevel(); -} - -void MQClient::setLogFileSizeAndNum(int fileNum, long perFileSize) { - ALOG_ADAPTER->setLogFileNumAndSize(fileNum, perFileSize); -} - -void MQClient::setTcpTransportPullThreadNum(int num) { - if (num > m_pullThreadNum) { - m_pullThreadNum = num; - } -} - -const int MQClient::getTcpTransportPullThreadNum() const { - return m_pullThreadNum; -} - -void MQClient::setTcpTransportConnectTimeout(uint64_t timeout) { - m_tcpConnectTimeout = timeout; -} -const uint64_t MQClient::getTcpTransportConnectTimeout() const { - return m_tcpConnectTimeout; -} - -void MQClient::setTcpTransportTryLockTimeout(uint64_t timeout) { - if (timeout < 1000) { - timeout = 1000; - } - m_tcpTransportTryLockTimeout = timeout / 1000; -} -const uint64_t MQClient::getTcpTransportTryLockTimeout() const { - return m_tcpTransportTryLockTimeout; -} - -void MQClient::setUnitName(string unitName) { - m_unitName = unitName; -} -const string& MQClient::getUnitName() { - return m_unitName; -} - -void MQClient::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& MQClient::getSessionCredentials() const { - return m_SessionCredentials; -} - -// namespace rocketmq { -//(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; -} -} +/* + * 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" + +#include +#include + +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(nullptr) { + if (keepInternalCopy) { + createInternalCopy(); + } +} + +void MemoryInputStream::createInternalCopy() { + std::free(internalCopy); + internalCopy = static_cast(std::malloc(dataSize)); + memcpy(internalCopy, data, dataSize); + data = internalCopy; +} + +MemoryInputStream::~MemoryInputStream() { + std::free(internalCopy); +} + +int64_t MemoryInputStream::getTotalLength() { + return (int64_t)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_t pos) { + if (pos < 0) + position = 0; + else + position = (int64_t)dataSize < pos ? (int64_t)dataSize : pos; + + return true; +} + +int64_t MemoryInputStream::getPosition() { + return (int64_t)position; +} + +} // namespace rocketmq diff --git a/src/common/MemoryInputStream.h b/src/common/MemoryInputStream.h index 53584b9a3..c6f94e4ef 100644 --- a/src/common/MemoryInputStream.h +++ b/src/common/MemoryInputStream.h @@ -1,96 +1,95 @@ -/* -* 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(); -}; -} -#endif +/* + * 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_t getPosition(); + bool setPosition(int64_t pos); + int64_t getTotalLength(); + bool isExhausted(); + int read(void* destBuffer, int maxBytesToRead); + + private: + //============================================================================== + const void* data; + size_t dataSize, position; + char* internalCopy; + + void createInternalCopy(); +}; +} // namespace rocketmq +#endif diff --git a/src/common/MemoryOutputStream.cpp b/src/common/MemoryOutputStream.cpp index 9578c8a35..f51444dc3 100644 --- a/src/common/MemoryOutputStream.cpp +++ b/src/common/MemoryOutputStream.cpp @@ -1,156 +1,173 @@ -/* -* 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(blockToUse->getData()); - } else { - if (storageNeeded > availableSize) - return NULL; - - data = static_cast(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(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; -} -} +/* + * 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" + +#include +#include + +namespace rocketmq { + +MemoryOutputStream::MemoryOutputStream(const size_t initialSize) + : poolToUse(&internalPool), externalData(nullptr), position(0), size(0), availableSize(0) { + internalPool.setSize(initialSize, false); +} + +MemoryOutputStream::MemoryOutputStream(MemoryPool& memoryBlockToWriteTo, const bool appendToExistingBlockContent) + : poolToUse(&memoryBlockToWriteTo), externalData(NULL), position(0), size(0), availableSize(0) { + if (appendToExistingBlockContent) { + position = size = memoryBlockToWriteTo.getSize(); + } +} + +MemoryOutputStream::MemoryOutputStream(void* destBuffer, size_t destBufferSize) + : poolToUse(NULL), externalData(destBuffer), position(0), size(0), availableSize(destBufferSize) {} + +MemoryOutputStream::~MemoryOutputStream() { + trimExternalBlockSize(); +} + +void MemoryOutputStream::flush() { + trimExternalBlockSize(); +} + +void MemoryOutputStream::trimExternalBlockSize() { + if (poolToUse != &internalPool && poolToUse != NULL) { + poolToUse->setSize(size, false); + } +} + +void MemoryOutputStream::preallocate(const size_t bytesToPreallocate) { + if (poolToUse != NULL) { + poolToUse->ensureSize(bytesToPreallocate + 1); + } +} + +void MemoryOutputStream::reset() { + position = 0; + size = 0; +} + +char* MemoryOutputStream::prepareToWrite(size_t numBytes) { + size_t storageNeeded = position + numBytes; + + char* data; + + if (poolToUse != NULL) { + if (storageNeeded >= (unsigned int)(poolToUse->getSize())) { + poolToUse->ensureSize((storageNeeded + std::min(storageNeeded / 2, (size_t)(1024 * 1024)) + 32) & ~31u); + } + + data = static_cast(poolToUse->getData()); + } else { + if (storageNeeded > availableSize) { + return NULL; + } + + data = static_cast(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; +} + +MemoryPool MemoryOutputStream::getMemoryBlock() const { + return MemoryPool(getData(), getDataSize()); +} + +const void* MemoryOutputStream::getData() const { + if (poolToUse == NULL) { + return externalData; + } + + if ((unsigned int)poolToUse->getSize() > size) { + static_cast(poolToUse->getData())[size] = 0; + } + + return poolToUse->getData(); +} + +bool MemoryOutputStream::setPosition(int64_t newPosition) { + if (newPosition <= (int64_t)size) { + // ok to seek backwards + if (newPosition < 0) { + position = 0; + } else { + position = (int64_t)size < newPosition ? size : newPosition; + } + return true; + } + + // can't move beyond the end of the stream.. + return false; +} + +int64_t MemoryOutputStream::writeFromInputStream(InputStream& source, int64_t maxNumBytesToWrite) { + // before writing from an input, see if we can preallocate to make it more efficient.. + int64_t availableData = source.getTotalLength() - source.getPosition(); + + if (availableData > 0) { + if (maxNumBytesToWrite > availableData || maxNumBytesToWrite < 0) { + maxNumBytesToWrite = availableData; + } + + if (poolToUse != NULL) { + preallocate(poolToUse->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 diff --git a/src/common/MemoryOutputStream.h b/src/common/MemoryOutputStream.h index 4b39879b9..6b24e3063 100644 --- a/src/common/MemoryOutputStream.h +++ b/src/common/MemoryOutputStream.h @@ -1,130 +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. -*/ - -#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); -} -#endif // MEMORYOUTPUTSTREAM_H_INCLUDED +/* + * 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(MemoryPool& 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. */ + MemoryPool 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_t getPosition() { return (int64_t)position; } + bool setPosition(int64_t); + int64_t writeFromInputStream(InputStream&, int64_t maxNumBytesToWrite); + bool writeRepeatedByte(uint8 byte, size_t numTimesToRepeat); + + private: + //============================================================================== + MemoryPool* const poolToUse; + MemoryPool internalPool; + 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 diff --git a/src/common/MessageAccessor.cpp b/src/common/MessageAccessor.cpp deleted file mode 100644 index 6fcfac173..000000000 --- a/src/common/MessageAccessor.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 -#include -#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& 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); - } - } -} -//= ENDPOINT_PREFIX_LENGTH && nameServerAddr.find(ENDPOINT_PREFIX) != string::npos) { +bool NameSpaceUtil::isEndPointURL(std::string nameServerAddr) { + if (nameServerAddr.length() >= ENDPOINT_PREFIX_LENGTH && nameServerAddr.find(ENDPOINT_PREFIX) != std::string::npos) { return true; } return false; } -string NameSpaceUtil::formatNameServerURL(string nameServerAddr) { +std::string NameSpaceUtil::formatNameServerURL(std::string nameServerAddr) { auto index = nameServerAddr.find(ENDPOINT_PREFIX); - if (index != string::npos) { + if (index != std::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); @@ -37,55 +37,4 @@ string NameSpaceUtil::formatNameServerURL(string nameServerAddr) { 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 = nameServerAddr.find(NAMESPACE_PREFIX); - if (index != string::npos) { - auto indexDot = nameServerAddr.find('.'); - if (indexDot != string::npos) { - nameSpace = nameServerAddr.substr(index, indexDot); - 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::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.length() >= ns.length() && source.find(ns) != string::npos) { - return true; - } - return false; -} } // namespace rocketmq diff --git a/src/common/NameSpaceUtil.h b/src/common/NameSpaceUtil.h index a63d6475f..29dfbb64d 100644 --- a/src/common/NameSpaceUtil.h +++ b/src/common/NameSpaceUtil.h @@ -14,37 +14,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#ifndef __NAMESPACEUTIL_H__ -#define __NAMESPACEUTIL_H__ +#ifndef __NAMESPACE_UTIL_H__ +#define __NAMESPACE_UTIL_H__ #include -using namespace std; +namespace rocketmq { -static const string ENDPOINT_PREFIX = "http://"; +static const std::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 isEndPointURL(std::string nameServerAddr); - static bool checkNameSpaceExistInNsURL(string nameServerAddr); - - static bool checkNameSpaceExistInNameServer(string nameServerAddr); - - static string withNameSpace(string source, string ns); - - static bool hasNameSpace(string source, string ns); + static std::string formatNameServerURL(std::string nameServerAddr); }; } // namespace rocketmq -#endif //__NAMESPACEUTIL_H__ + +#endif // __NAMESPACE_UTIL_H__ diff --git a/src/common/NamesrvConfig.h b/src/common/NamesrvConfig.h index 30bbb0e49..0276f5391 100644 --- a/src/common/NamesrvConfig.h +++ b/src/common/NamesrvConfig.h @@ -14,25 +14,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __NAMESRVCONFIG_H__ -#define __NAMESRVCONFIG_H__ +#ifndef __NAMESRV_CONFIG_H__ +#define __NAMESRV_CONFIG_H__ #include #include #include "UtilAll.h" namespace rocketmq { -// -#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::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; -} -} +/* + * 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 +#include + +#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_t value) { + uint64_t v; + char pUint64[sizeof(v)]; + WriteBigEndian(pUint64, (uint64_t)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_t asInt; + double asDouble; + } n; + n.asDouble = value; + return writeInt64BigEndian(n.asInt); +} + +int64_t OutputStream::writeFromInputStream(InputStream& source, int64_t numBytesToWrite) { + if (numBytesToWrite < 0) + numBytesToWrite = std::numeric_limits::max(); + + int64_t numWritten = 0; + + while (numBytesToWrite > 0) { + char buffer[8192]; + const int num = source.read(buffer, (int)std::min(numBytesToWrite, (int64_t)sizeof(buffer))); + + if (num <= 0) + break; + + write(buffer, (size_t)num); + + numBytesToWrite -= num; + numWritten += num; + } + + return numWritten; +} +} // namespace rocketmq diff --git a/src/common/OutputStream.h b/src/common/OutputStream.h index 3792169d9..a6b2c26ba 100644 --- a/src/common/OutputStream.h +++ b/src/common/OutputStream.h @@ -1,148 +1,147 @@ -/* -* 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); -}; -} - -#endif // OUTPUTSTREAM_H_INCLUDED +/* + * 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_t newPosition) = 0; + + /** Returns the stream's current position. + + @see setPosition + */ + virtual int64_t 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_t 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_t writeFromInputStream(InputStream& source, int64_t maxNumBytesToWrite); +}; +} // namespace rocketmq + +#endif // OUTPUTSTREAM_H_INCLUDED diff --git a/src/common/PermName.cpp b/src/common/PermName.cpp index bd36bfc05..76fb19580 100644 --- a/src/common/PermName.cpp +++ b/src/common/PermName.cpp @@ -18,7 +18,7 @@ #include "UtilAll.h" namespace rocketmq { -// namespace rocketmq { -// response(responseFuture->getResponseCommand()); // avoid RemotingCommand leak + + if (m_pullCallback == nullptr) { + LOG_ERROR("m_pullCallback is NULL, AsyncPull could not continue"); + return; + } + + if (response != nullptr) { + try { + std::unique_ptr pullResult(m_pClientAPI->processPullResponse(response.get())); + assert(pullResult != nullptr); + m_pullCallback->onSuccess(*pullResult); + } catch (MQException& e) { + m_pullCallback->onException(e); + } + } else { + std::string err; + if (!responseFuture->isSendRequestOK()) { + err = "send request failed"; + } else if (responseFuture->isTimeout()) { + err = "wait response timeout"; + } else { + err = "unknown reason"; + } + MQException exception(err, -1, __FILE__, __LINE__); + m_pullCallback->onException(exception); + } + + // auto delete callback + if (m_pullCallback->getPullCallbackType() == PULL_CALLBACK_TYPE_AUTO_DELETE) { + deleteAndZero(m_pullCallback); + } +} + +} // namespace rocketmq diff --git a/src/common/url.h b/src/common/PullCallbackWrap.h old mode 100644 new mode 100755 similarity index 62% rename from src/common/url.h rename to src/common/PullCallbackWrap.h index 0fbcb85fe..b4343d570 --- a/src/common/url.h +++ b/src/common/PullCallbackWrap.h @@ -14,25 +14,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef ROCKETMQ_CLIENT4CPP_URL_HH_ -#define ROCKETMQ_CLIENT4CPP_URL_HH_ +#ifndef __PULL_CALLBACK_WRAP_H__ +#define __PULL_CALLBACK_WRAP_H__ -#include +#include "InvokeCallback.h" +#include "MQClientAPIImpl.h" +#include "PullCallback.h" +#include "ResponseFuture.h" namespace rocketmq { -class Url { + +class PullCallbackWrap : public InvokeCallback { public: - Url(const std::string& url_s); // omitted copy, ==, accessors, ... + PullCallbackWrap(PullCallback* pullCallback, MQClientAPIImpl* pClientAPI); - private: - void parse(const std::string& url_s); + void operationComplete(ResponseFuture* responseFuture) noexcept override; - public: - std::string protocol_; - std::string host_; - std::string port_; - std::string path_; - std::string query_; + private: + PullCallback* m_pullCallback; + MQClientAPIImpl* m_pClientAPI; }; -} -#endif // ROCKETMQ_CLIENT4CPP_URL_HH_ + +} // namespace rocketmq + +#endif // __PULL_CALLBACK_WRAP_H__ diff --git a/src/common/PullSysFlag.cpp b/src/common/PullSysFlag.cpp index a4af97aed..da6287fbc 100644 --- a/src/common/PullSysFlag.cpp +++ b/src/common/PullSysFlag.cpp @@ -17,7 +17,7 @@ #include "PullSysFlag.h" namespace rocketmq { -// + +#include "CommandHeader.h" +#include "DefaultMQProducer.h" +#include "Logging.h" +#include "MQClientAPIImpl.h" +#include "MQClientInstance.h" +#include "MQDecoder.h" +#include "MQMessageQueue.h" +#include "MQProtos.h" +#include "PullAPIWrapper.h" +#include "PullResultExt.h" +#include "TopicPublishInfo.h" + +namespace rocketmq { + +SendCallbackWrap::SendCallbackWrap(const std::string& addr, + const std::string& brokerName, + const MQMessagePtr msg, + RemotingCommand&& request, + SendCallback* sendCallback, + TopicPublishInfoPtr topicPublishInfo, + MQClientInstancePtr instance, + int retryTimesWhenSendFailed, + int times, + DefaultMQProducerImplPtr producer) + : m_addr(addr), + m_brokerName(brokerName), + m_msg(msg), + m_request(std::forward(request)), + m_sendCallback(sendCallback), + m_topicPublishInfo(topicPublishInfo), + m_instance(instance), + m_timesTotal(retryTimesWhenSendFailed), + m_times(times), + m_producer(producer) {} + +void SendCallbackWrap::operationComplete(ResponseFuture* responseFuture) noexcept { + auto producer = m_producer.lock(); + if (nullptr == producer) { + MQException exception("DefaultMQProducer is released.", -1, __FILE__, __LINE__); + m_sendCallback->onException(exception); + + // auto delete callback + if (m_sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_ATUO_DELETE) { + deleteAndZero(m_sendCallback); + } + return; + } + + std::unique_ptr response(responseFuture->getResponseCommand()); // avoid RemotingCommand leak + if (nullptr == m_sendCallback && response != nullptr) { + // TODO: executeSendMessageHookAfter + // try { + // std::unique_ptr sendResult(m_pClientAPI->processSendResponse(m_brokerName, m_msg, response.get())); + // if (context != null && sendResult != nullptr) { + // context.setSendResult(sendResult); + // context.getProducer().executeSendMessageHookAfter(context); + // } + // } catch (...) { + // } + + producer->updateFaultItem(m_brokerName, UtilAll::currentTimeMillis() - responseFuture->getBeginTimestamp(), false); + return; + } + + if (response != nullptr) { + int opaque = responseFuture->getOpaque(); + try { + std::unique_ptr sendResult( + m_instance->getMQClientAPIImpl()->processSendResponse(m_brokerName, m_msg, response.get())); + assert(sendResult != nullptr); + + LOG_DEBUG("operationComplete: processSendResponse success, opaque:%d, maxRetryTime:%d, retrySendTimes:%d", opaque, + m_timesTotal, m_times); + + // TODO: executeSendMessageHookAfter + // if (context != null) { + // context.setSendResult(sendResult); + // context.getProducer().executeSendMessageHookAfter(context); + // } + + try { + m_sendCallback->onSuccess(*sendResult); + } catch (...) { + } + + producer->updateFaultItem(m_brokerName, UtilAll::currentTimeMillis() - responseFuture->getBeginTimestamp(), + false); + + // auto delete callback + if (m_sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_ATUO_DELETE) { + deleteAndZero(m_sendCallback); + } + } catch (MQException& e) { + producer->updateFaultItem(m_brokerName, UtilAll::currentTimeMillis() - responseFuture->getBeginTimestamp(), true); + LOG_ERROR("operationComplete: processSendResponse exception: %s", e.what()); + return onExceptionImpl(responseFuture, responseFuture->leftTime(), e, false); + } + } else { + producer->updateFaultItem(m_brokerName, UtilAll::currentTimeMillis() - responseFuture->getBeginTimestamp(), true); + std::string err; + if (!responseFuture->isSendRequestOK()) { + err = "send request failed"; + } else if (responseFuture->isTimeout()) { + err = "wait response timeout"; + } else { + err = "unknown reason"; + } + MQException exception(err, -1, __FILE__, __LINE__); + return onExceptionImpl(responseFuture, responseFuture->leftTime(), exception, true); + } +} + +void SendCallbackWrap::onExceptionImpl(ResponseFuture* responseFuture, + long timeoutMillis, + MQException& e, + bool needRetry) { + auto producer = m_producer.lock(); + if (nullptr == producer) { + MQException exception("DefaultMQProducer is released.", -1, __FILE__, __LINE__); + m_sendCallback->onException(exception); + + // auto delete callback + if (m_sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_ATUO_DELETE) { + deleteAndZero(m_sendCallback); + } + return; + } + + m_times++; + if (needRetry && m_times <= m_timesTotal) { + std::string retryBrokerName = m_brokerName; // by default, it will send to the same broker + if (m_topicPublishInfo != nullptr) { + // select one message queue accordingly, in order to determine which broker to send + const auto& mqChosen = producer->selectOneMessageQueue(m_topicPublishInfo.get(), m_brokerName); + retryBrokerName = mqChosen.getBrokerName(); + + // set queueId to requestHeader + auto* requestHeader = m_request.readCustomHeader(); + if (std::type_index(typeid(*requestHeader)) == std::type_index(typeid(SendMessageRequestHeaderV2))) { + static_cast(requestHeader)->e = mqChosen.getQueueId(); + } else { + static_cast(requestHeader)->queueId = mqChosen.getQueueId(); + } + } + std::string addr = m_instance->findBrokerAddressInPublish(retryBrokerName); + LOG_INFO_NEW("async send msg by retry {} times. topic={}, brokerAddr={}, brokerName={}", m_times, m_msg->getTopic(), + addr, retryBrokerName); + try { + // new request + m_request.setOpaque(RemotingCommand::createNewRequestId()); + + // resend + m_addr = std::move(addr); + m_brokerName = std::move(retryBrokerName); + m_instance->getMQClientAPIImpl()->sendMessageAsyncImpl(this, timeoutMillis); + + responseFuture->releaseInvokeCallback(); // for avoid delete this SendCallbackWrap + return; + } catch (MQException& e1) { + producer->updateFaultItem(m_brokerName, 3000, true); + return onExceptionImpl(responseFuture, responseFuture->leftTime(), e1, true); + } + } else { + m_sendCallback->onException(e); + + // auto delete callback + if (m_sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_ATUO_DELETE) { + deleteAndZero(m_sendCallback); + } + } +} + +} // namespace rocketmq diff --git a/src/common/SendCallbackWrap.h b/src/common/SendCallbackWrap.h new file mode 100755 index 000000000..a969f7527 --- /dev/null +++ b/src/common/SendCallbackWrap.h @@ -0,0 +1,72 @@ +/* + * 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 __SEND_CALLBACK_WRAP_H__ +#define __SEND_CALLBACK_WRAP_H__ + +#include + +#include "DefaultMQProducerImpl.h" +#include "InvokeCallback.h" +#include "MQClientInstance.h" +#include "MQMessage.h" +#include "RemotingCommand.h" +#include "ResponseFuture.h" +#include "SendCallback.h" +#include "TopicPublishInfo.h" + +namespace rocketmq { + +class SendCallbackWrap : public InvokeCallback { + public: + SendCallbackWrap(const std::string& addr, + const std::string& brokerName, + const MQMessagePtr msg, + RemotingCommand&& request, + SendCallback* sendCallback, + TopicPublishInfoPtr topicPublishInfo, + MQClientInstancePtr instance, + int retryTimesWhenSendFailed, + int times, + DefaultMQProducerImplPtr producer); + + void operationComplete(ResponseFuture* responseFuture) noexcept override; + void onExceptionImpl(ResponseFuture* responseFuture, long timeoutMillis, MQException& e, bool needRetry); + + const std::string& getAddr() { return m_addr; } + const MQMessagePtr getMessage() { return m_msg; } + RemotingCommand& getRemotingCommand() { return m_request; } + + void setRetrySendTimes(int retrySendTimes) { m_times = retrySendTimes; } + int getRetrySendTimes() { return m_times; } + int getMaxRetrySendTimes() { return m_timesTotal; } + + private: + std::string m_addr; + std::string m_brokerName; + const MQMessagePtr m_msg; + RemotingCommand m_request; + SendCallback* m_sendCallback; + TopicPublishInfoPtr m_topicPublishInfo; + MQClientInstancePtr m_instance; + int m_timesTotal; + int m_times; + std::weak_ptr m_producer; +}; + +} // namespace rocketmq + +#endif // __SEND_CALLBACK_WRAP_H__ diff --git a/src/common/ServiceState.h b/src/common/ServiceState.h index a8ae79260..726c15090 100644 --- a/src/common/ServiceState.h +++ b/src/common/ServiceState.h @@ -14,12 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __SERVICESTATE_H__ -#define __SERVICESTATE_H__ +#ifndef __SERVICE_STATE_H__ +#define __SERVICE_STATE_H__ + namespace rocketmq { -//start(); +} + +void ServiceThread::shutdown() { + LOG_INFO_NEW("Try to shutdown service thread:{} started:{} lastThread:{}", getServiceName(), m_started.load(), + (void*)m_thread.get()); + bool expected = true; + if (!m_started.compare_exchange_strong(expected, false)) { + return; + } + m_stopped = true; + LOG_INFO_NEW("shutdown thread {}", getServiceName()); + + wakeup(); + + int64_t beginTime = UtilAll::currentTimeMillis(); + m_thread->join(); + int64_t elapsedTime = UtilAll::currentTimeMillis() - beginTime; + LOG_INFO_NEW("join thread {} elapsed time(ms) {}", getServiceName(), elapsedTime); +} + +void ServiceThread::wakeup() { + bool expected = false; + if (m_hasNotified.compare_exchange_strong(expected, true)) { + m_waitPoint.count_down(); // notify + } +} + +void ServiceThread::waitForRunning(long interval) { + bool expected = true; + if (m_hasNotified.compare_exchange_strong(expected, false)) { + onWaitEnd(); + return; + } + + // entry to wait + m_waitPoint.reset(); + + try { + m_waitPoint.wait(interval, time_unit::milliseconds); + } catch (const std::exception& e) { + LOG_WARN_NEW("encounter unexpected exception: {}", e.what()); + } + m_hasNotified.store(false); + onWaitEnd(); +} + +void ServiceThread::onWaitEnd() {} + +bool ServiceThread::isStopped() { + return m_stopped; +}; + +} // namespace rocketmq diff --git a/src/common/ServiceThread.h b/src/common/ServiceThread.h new file mode 100644 index 000000000..ff6548951 --- /dev/null +++ b/src/common/ServiceThread.h @@ -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 __SERVICE_THREAD_H__ +#define __SERVICE_THREAD_H__ + +#include +#include + +#include "concurrent/latch.hpp" +#include "concurrent/thread.hpp" + +namespace rocketmq { + +class ServiceThread { + public: + ServiceThread() + : m_waitPoint(1), + m_hasNotified(false), + m_stopped(false), + m_isDaemon(false), + m_thread(nullptr), + m_started(false) {} + virtual ~ServiceThread() = default; + + virtual std::string getServiceName() = 0; + virtual void run() = 0; + + virtual void start(); + virtual void shutdown(); + + void wakeup(); + + bool isStopped(); + + protected: + void waitForRunning(long interval); + virtual void onWaitEnd(); + + protected: + latch m_waitPoint; + std::atomic m_hasNotified; + volatile bool m_stopped; + bool m_isDaemon; + + private: + std::unique_ptr m_thread; + std::atomic m_started; +}; + +} // namespace rocketmq + +#endif // __PULL_MESSAGE_SERVICE_H__ diff --git a/src/consumer/SubscriptionData.h b/src/common/SubscriptionData.h similarity index 58% rename from src/consumer/SubscriptionData.h rename to src/common/SubscriptionData.h index 40e985b2e..85ba26156 100644 --- a/src/consumer/SubscriptionData.h +++ b/src/common/SubscriptionData.h @@ -14,35 +14,44 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __SUBSCRIPTIONDATA_H__ -#define __SUBSCRIPTIONDATA_H__ +#ifndef __SUBSCRIPTION_DATA_H__ +#define __SUBSCRIPTION_DATA_H__ #include -#include "UtilAll.h" -#include "json/json.h" +#include + +#include + +#include "RocketMQClient.h" namespace rocketmq { -//& getTagsSet(); + int64_t getSubVersion() const; - void putCodeSet(const string& tag); + void putTagsSet(const std::string& tag); + bool containTag(const std::string& tag); + std::vector& getTagsSet(); + + void putCodeSet(const int32 code); bool operator==(const SubscriptionData& other) const; bool operator<(const SubscriptionData& other) const; @@ -50,13 +59,13 @@ class SubscriptionData { Json::Value toJson() const; private: - string m_topic; - string m_subString; - int64 m_subVersion; - vector m_tagSet; - vector m_codeSet; + std::string m_topic; + std::string m_subString; + int64_t m_subVersion; + std::vector m_tagSet; + std::vector m_codeSet; }; -// namespace rocketmq { -// -#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 lock(m_addrLock); - vector 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::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; -} -} // #include + #include "PermName.h" namespace rocketmq { -//> m_topicName; ss >> m_readQueueNums; @@ -71,11 +73,11 @@ bool TopicConfig::decode(const string& in) { return true; } -const string& TopicConfig::getTopicName() { +const std::string& TopicConfig::getTopicName() { return m_topicName; } -void TopicConfig::setTopicName(const string& topicName) { +void TopicConfig::setTopicName(const std::string& topicName) { m_topicName = topicName; } @@ -110,5 +112,5 @@ TopicFilterType TopicConfig::getTopicFilterType() { void TopicConfig::setTopicFilterType(TopicFilterType topicFilterType) { m_topicFilterType = topicFilterType; } -// + #include "TopicFilterType.h" #include "UtilAll.h" + namespace rocketmq { -// +#include -namespace rocketmq { -// // gethostbyname +#include // getpwuid +#include // mkdir +#include // gethostname, access, getpid +#else +#include +#include +#include +#endif -bool UtilAll::startsWith_retry(const string& topic) { - return topic.find(RETRY_GROUP_TOPIC_PREFIX) == 0; -} +#include -string UtilAll::getRetryTopic(const string& consumerGroup) { - return RETRY_GROUP_TOPIC_PREFIX + consumerGroup; -} +#define ZLIB_CHUNK 16384 -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 -} +#include "Logging.h" +#include "SocketUtil.h" -bool UtilAll::isBlank(const string& str) { - if (str.empty()) { - return true; - } +namespace rocketmq { - string::size_type left = str.find_first_not_of(WHITESPACE); +std::string UtilAll::s_localHostName; +std::string UtilAll::s_localIpAddress; - if (left == string::npos) { - return true; +bool UtilAll::try_lock_for(std::timed_mutex& mutex, long timeout) { + auto now = std::chrono::steady_clock::now(); + auto deadline = now + std::chrono::milliseconds(timeout); + for (;;) { + if (mutex.try_lock_until(deadline)) { + return true; + } + now = std::chrono::steady_clock::now(); + if (now > deadline) { + return false; + } + std::this_thread::yield(); } +} - return false; +int32_t UtilAll::HashCode(const std::string& str) { + // FIXME: don't equal to String#hashCode in Java + int32 h = 0; + if (!str.empty()) { + for (const auto& c : str) { + h = 31 * h + c; + } + } + return h; } -const int hex2int[256] = { +static 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, @@ -61,8 +79,8 @@ 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, -1, -1, -1, -1, -1}; -uint64 UtilAll::hexstr2ull(const char* str) { - uint64 num = 0; +uint64_t UtilAll::hexstr2ull(const char* str) { + uint64_t num = 0; unsigned char* ch = (unsigned char*)str; while (*ch != '\0') { num = (num << 4) + hex2int[*ch]; @@ -71,43 +89,53 @@ uint64 UtilAll::hexstr2ull(const char* str) { return num; } -int64 UtilAll::str2ll(const char* str) { - return boost::lexical_cast(str); -} +static const char sHexAlphabet[] = "0123456789ABCDEF"; -string UtilAll::bytes2string(const char* bytes, int len) { - if (bytes == NULL || len <= 0) { - return string(); +std::string UtilAll::bytes2string(const char* bytes, size_t len) { + if (bytes == nullptr || len <= 0) { + return std::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); + std::string buffer; + buffer.reserve(len * 2 + 1); + for (std::size_t i = 0; i < len; i++) { + unsigned char v = (unsigned char)bytes[i]; + buffer.append(1, sHexAlphabet[v >> 4]); + buffer.append(1, sHexAlphabet[v & 0x0FU]); } - return buffer; -#else - static const char hex_str[] = "0123456789ABCDEF"; +} - char result[len * 2 + 1]; +bool UtilAll::isRetryTopic(const std::string& topic) { + return topic.find(RETRY_GROUP_TOPIC_PREFIX) == 0; +} + +std::string UtilAll::getRetryTopic(const std::string& consumerGroup) { + return RETRY_GROUP_TOPIC_PREFIX + consumerGroup; +} + +void UtilAll::Trim(std::string& str) { + str.erase(0, str.find_first_not_of(' ')); // prefixing spaces + str.erase(str.find_last_not_of(' ') + 1); // surfixing spaces +} - 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]; +bool UtilAll::isBlank(const std::string& str) { + if (str.empty()) { + return true; } - string buffer(result); - return buffer; -#endif + std::string::size_type left = str.find_first_not_of(WHITESPACE); + + if (left == std::string::npos) { + return true; + } + + return false; } -bool UtilAll::SplitURL(const string& serverURL, string& addr, short& nPort) { - size_t pos = serverURL.find(':'); - if (pos == string::npos) { +bool UtilAll::SplitURL(const std::string& serverURL, std::string& addr, short& nPort) { + auto pos = serverURL.find(':'); + if (pos == std::string::npos) { return false; } @@ -117,7 +145,7 @@ bool UtilAll::SplitURL(const string& serverURL, string& addr, short& nPort) { } pos++; - string port = serverURL.substr(pos, serverURL.length() - pos); + std::string port = serverURL.substr(pos, serverURL.length() - pos); nPort = atoi(port.c_str()); if (nPort == 0) { return false; @@ -125,17 +153,17 @@ bool UtilAll::SplitURL(const string& serverURL, string& addr, short& nPort) { return true; } -int UtilAll::Split(vector& ret_, const string& strIn, const char sep) { +int UtilAll::Split(std::vector& ret_, const std::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; + std::string tmp; + std::string::size_type pos_begin = strIn.find_first_not_of(sep); + std::string::size_type comma_pos = 0; - while (pos_begin != string::npos) { + while (pos_begin != std::string::npos) { comma_pos = strIn.find(sep, pos_begin); - if (comma_pos != string::npos) { + if (comma_pos != std::string::npos) { tmp = strIn.substr(pos_begin, comma_pos - pos_begin); pos_begin = comma_pos + 1; } else { @@ -150,17 +178,18 @@ int UtilAll::Split(vector& ret_, const string& strIn, const char sep) { } return ret_.size(); } -int UtilAll::Split(vector& ret_, const string& strIn, const string& sep) { + +int UtilAll::Split(std::vector& ret_, const std::string& strIn, const std::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; + std::string tmp; + std::string::size_type pos_begin = strIn.find_first_not_of(sep); + std::string::size_type comma_pos = 0; - while (pos_begin != string::npos) { + while (pos_begin != std::string::npos) { comma_pos = strIn.find(sep, pos_begin); - if (comma_pos != string::npos) { + if (comma_pos != std::string::npos) { tmp = strIn.substr(pos_begin, comma_pos - pos_begin); pos_begin = comma_pos + sep.length(); } else { @@ -176,104 +205,120 @@ int UtilAll::Split(vector& ret_, const string& strIn, const string& sep) return ret_.size(); } -int32_t 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; -} - -int64_t 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() { +std::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(); + if (::gethostname(name, sizeof(name)) != 0) { + return null; } s_localHostName.append(name, strlen(name)); } return s_localHostName; } -string UtilAll::getLocalAddress() { +std::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++; + auto hostname = getLocalHostName(); + if (!hostname.empty()) { + try { + s_localIpAddress = lookupNameServers(hostname); + } catch (std::exception& e) { + LOG_WARN(e.what()); + s_localIpAddress = "127.0.0.1"; + } } - s_localIpAddress = ep.address().to_string(); } return s_localIpAddress; } -string UtilAll::getHomeDirectory() { +uint32_t UtilAll::getIP() { + std::string ip = UtilAll::getLocalAddress(); + if (ip.empty()) { + return 0; + } + + char* ip_str = new char[ip.length() + 1]; + std::strncpy(ip_str, ip.c_str(), ip.length()); + ip_str[ip.length()] = '\0'; + + int i = 3; + uint32_t nResult = 0; + for (char* token = std::strtok(ip_str, "."); token != nullptr && i >= 0; token = std::strtok(nullptr, ".")) { + uint32_t n = std::atoi(token); + nResult |= n << (8 * i--); + } + + delete[] ip_str; + + return nResult; +} + +std::string UtilAll::getHomeDirectory() { #ifndef WIN32 - char* homeEnv = getenv("HOME"); - string homeDir; + char* homeEnv = std::getenv("HOME"); + std::string homeDir; if (homeEnv == NULL) { homeDir.append(getpwuid(getuid())->pw_dir); } else { homeDir.append(homeEnv); } #else - string homeDir(getenv("USERPROFILE")); + std::string homeDir(std::getenv("USERPROFILE")); #endif return homeDir; } -string UtilAll::getProcessName() { +static bool createDirectoryInner(const char* dir) { + if (dir == nullptr) { + std::cerr << "directory is nullptr" << std::endl; + return false; + } + if (access(dir, F_OK) == -1) { +#ifdef _WIN32 + int flag = mkdir(dir); +#else + int flag = mkdir(dir, 0755); +#endif + return flag == 0; + } + return true; +} + +void UtilAll::createDirectory(std::string const& dir) { + const char* ptr = dir.c_str(); + if (access(ptr, F_OK) == 0) { + return; + } + char buff[2048] = {0}; + for (unsigned int i = 0; i < dir.size(); i++) { + if (i != 0 && (*(ptr + i) == '/' || *(ptr + i) == '\\')) { + memcpy(buff, ptr, i); + createDirectoryInner(buff); + memset(buff, 0, 1024); + } + } + return; +} + +bool UtilAll::existDirectory(std::string const& dir) { + return access(dir.c_str(), F_OK) == 0; +} + +int UtilAll::getProcessId() { #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()); + return getpid(); +#else + return ::GetCurrentProcessId(); +#endif +} +std::string UtilAll::getProcessName() { +#ifndef WIN32 + char buf[PATH_MAX] = {0}; + char procpath[PATH_MAX] = {0}; + int count = PATH_MAX; + + sprintf(procpath, "/proc/%d/exe", getpid()); if (access(procpath, F_OK) == -1) { return ""; } @@ -294,51 +339,121 @@ string UtilAll::getProcessName() { return ""; } #else - TCHAR szFileName[MAX_PATH + 1]; - GetModuleFileName(NULL, szFileName, MAX_PATH + 1); + TCHAR szFileName[MAX_PATH]; + ::GetModuleFileName(NULL, szFileName, MAX_PATH); return std::string(szFileName); #endif } -uint64_t UtilAll::currentTimeMillis() { +int64_t UtilAll::currentTimeMillis() { auto since_epoch = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); - return static_cast(since_epoch.count()); + return static_cast(since_epoch.count()); } -uint64_t UtilAll::currentTimeSeconds() { +int64_t UtilAll::currentTimeSeconds() { auto since_epoch = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); - return static_cast(since_epoch.count()); + return static_cast(since_epoch.count()); +} + +bool UtilAll::deflate(const std::string& input, std::string& out, int level) { + return deflate(input.data(), input.length(), out, level); } -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); +bool UtilAll::deflate(const char* input, size_t len, std::string& out, int level) { + int ret; + unsigned have; + z_stream strm; + unsigned char buf[ZLIB_CHUNK]; + + /* allocate deflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = ::deflateInit(&strm, level); + if (ret != Z_OK) { + return false; + } + + strm.avail_in = len; + strm.next_in = (z_const Bytef*)input; + + /* run deflate() on input until output buffer not full, finish + compression if all of source has been read in */ + do { + strm.avail_out = ZLIB_CHUNK; + strm.next_out = buf; + ret = ::deflate(&strm, Z_FINISH); /* no bad return value */ + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + have = ZLIB_CHUNK - strm.avail_out; + out.append((char*)buf, have); + } while (strm.avail_out == 0); + assert(strm.avail_in == 0); /* all input will be used */ + assert(ret == Z_STREAM_END); /* stream will be complete */ + + /* clean up and return */ + (void)::deflateEnd(&strm); 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); +bool UtilAll::inflate(const std::string& input, std::string& out) { + return inflate(input.data(), input.length(), out); +} - return true; +bool UtilAll::inflate(const char* input, size_t len, std::string& out) { + int ret; + unsigned have; + z_stream strm; + unsigned char buf[ZLIB_CHUNK]; + + /* allocate inflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = ::inflateInit(&strm); + if (ret != Z_OK) { + return false; + } + + strm.avail_in = len; + strm.next_in = (z_const Bytef*)input; + + /* run inflate() on input until output buffer not full */ + do { + strm.avail_out = ZLIB_CHUNK; + strm.next_out = buf; + ret = ::inflate(&strm, Z_NO_FLUSH); + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + switch (ret) { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; /* and fall through */ + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd(&strm); + return false; + } + have = ZLIB_CHUNK - strm.avail_out; + out.append((char*)buf, have); + } while (strm.avail_out == 0); + + /* clean up and return */ + (void)::inflateEnd(&strm); + + return ret == Z_STREAM_END; } 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())) + 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 @@ -346,11 +461,11 @@ bool UtilAll::ReplaceFile(const std::string& from_path, const std::string& to_pa 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; + return rename(from_path.c_str(), to_path.c_str()) == 0; #endif } -} + +} // namespace rocketmq diff --git a/src/common/UtilAll.h b/src/common/UtilAll.h index 98fc906a2..63042a947 100644 --- a/src/common/UtilAll.h +++ b/src/common/UtilAll.h @@ -14,118 +14,115 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __UTILALL_H__ -#define __UTILALL_H__ - -#include -#include -#include -#include -#include -#ifndef WIN32 -#include -#include -#include -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#ifndef __UTIL_ALL_H__ +#define __UTIL_ALL_H__ + +#include +#include +#include + #include "RocketMQClient.h" -using namespace std; namespace rocketmq { -// -inline void deleteAndZero(Type& pointer) { +const std::string null = ""; + +template +inline void deleteAndZero(T& pointer) { delete pointer; - pointer = NULL; + pointer = nullptr; } -#define EMPTY_STR_PTR(ptr) (ptr == NULL || ptr[0] == '\0') + +#define EMPTY_STR_PTR(ptr) (ptr == nullptr || ptr[0] == '\0') + #ifdef WIN32 -#define SIZET_FMT "%lu" -#else -#define SIZET_FMT "%zu" +typedef pid_t DWORD; #endif -// - static string to_string(const T& n) { - std::ostringstream stm; - stm << n; - return stm.str(); - } + static std::string to_string(T value); + + static int32_t HashCode(const std::string& str); - static bool to_bool(std::string const& s) { return atoi(s.c_str()); } + static uint64_t hexstr2ull(const char* str); - static bool SplitURL(const string& serverURL, string& addr, short& nPort); - static int Split(vector& ret_, const string& strIn, const char sep); - static int Split(vector& ret_, const string& strIn, const string& sep); + static std::string bytes2string(const char* bytes, size_t len); - static int32_t StringToInt32(const std::string& str, int32_t& out); - static int64_t StringToInt64(const std::string& str, int64_t& val); + static bool isRetryTopic(const std::string& topic); + static std::string getRetryTopic(const std::string& consumerGroup); - static string getLocalHostName(); - static string getLocalAddress(); - static string getHomeDirectory(); + static void Trim(std::string& str); + static bool isBlank(const std::string& str); - static string getProcessName(); + static bool SplitURL(const std::string& serverURL, std::string& addr, short& nPort); + static int Split(std::vector& ret_, const std::string& strIn, const char sep); + static int Split(std::vector& ret_, const std::string& strIn, const std::string& sep); - static uint64_t currentTimeMillis(); - static uint64_t currentTimeSeconds(); + static std::string getLocalHostName(); + static std::string getLocalAddress(); + static uint32_t getIP(); + + static std::string getHomeDirectory(); + static void createDirectory(std::string const& dir); + static bool existDirectory(std::string const& dir); + + static pid_t getProcessId(); + static std::string getProcessName(); + + static int64_t currentTimeMillis(); + static int64_t currentTimeSeconds(); + + static bool deflate(const std::string& input, std::string& out, int level); + static bool deflate(const char* input, size_t len, std::string& out, int level); + static bool inflate(const std::string& input, std::string& out); + static bool inflate(const char* input, size_t len, std::string& out); - 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 @@ -138,6 +135,34 @@ class UtilAll { static std::string s_localHostName; static std::string s_localIpAddress; }; -// +inline std::string UtilAll::to_string(T value) { + return std::to_string(value); +} + +template <> +inline std::string UtilAll::to_string(bool value) { + return value ? "true" : "false"; +} + +template <> +inline std::string UtilAll::to_string(char* value) { + return std::string(value); +} + +template <> +inline std::string UtilAll::to_string(std::exception_ptr eptr) { + try { + if (eptr) { + std::rethrow_exception(eptr); + } + } catch (const std::exception& e) { + return e.what(); + } + return null; +} + +} // namespace rocketmq + +#endif // __UTIL_ALL_H__ diff --git a/src/common/Validators.cpp b/src/common/Validators.cpp index 8743a20dc..138417239 100644 --- a/src/common/Validators.cpp +++ b/src/common/Validators.cpp @@ -15,14 +15,19 @@ * limitations under the License. */ #include "Validators.h" + #include #include + +#include "MQProtos.h" +#include "UtilAll.h" + namespace rocketmq { -const string Validators::validPatternStr = "^[a-zA-Z0-9_-]+$"; +const std::string Validators::validPatternStr = "^[a-zA-Z0-9_-]+$"; const int Validators::CHARACTER_MAX_LENGTH = 255; -// CHARACTER_MAX_LENGTH) { THROW_MQEXCEPTION(MQClientException, "the specified group is longer than group max length 255.", -1); @@ -87,18 +88,15 @@ void Validators::checkGroup(const string& group) { void Validators::checkMessage(const MQMessage& msg, int maxMessageSize) { checkTopic(msg.getTopic()); - string body = msg.getBody(); - // maxMessageSize) { - char info[256]; - sprintf(info, "the message body size over max value, MAX: %d", maxMessageSize); - THROW_MQEXCEPTION(MQClientException, info, -1); + if (body.length() > (size_t)maxMessageSize) { + std::string info = "the message body size over max value, MAX: " + UtilAll::to_string(maxMessageSize); + THROW_MQEXCEPTION(MQClientException, info, MESSAGE_ILLEGAL); } } -// + #include "MQClientException.h" #include "MQMessage.h" #include "UtilAll.h" + namespace rocketmq { -// #include + #include "UtilAll.h" namespace rocketmq { + const char* VirtualEnvUtil::VIRTUAL_APPGROUP_PREFIX = "%%PROJECT_%s%%"; -// + namespace rocketmq { -// #include @@ -93,4 +93,4 @@ bool BigEndianWriter::WriteU64(uint64_t value) { return Write(value); } -} // namespace base +} // namespace rocketmq diff --git a/src/common/big_endian.h b/src/common/big_endian.h index b7729e505..ad591962c 100644 --- a/src/common/big_endian.h +++ b/src/common/big_endian.h @@ -1,4 +1,3 @@ - // 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. @@ -97,6 +96,6 @@ class BigEndianWriter { char* end_; }; -} // namespace base +} // namespace rocketmq #endif // BASE_BIG_ENDIAN_H_ diff --git a/src/common/dataBlock.cpp b/src/common/dataBlock.cpp deleted file mode 100644 index daca4e4ea..000000000 --- a/src/common/dataBlock.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* -* 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 - -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(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(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(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(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(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(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(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); -} -} diff --git a/src/common/dataBlock.h b/src/common/dataBlock.h deleted file mode 100644 index 4419af31d..000000000 --- a/src/common/dataBlock.h +++ /dev/null @@ -1,208 +0,0 @@ -/* -* 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 -#include -#include -#include -#include - -#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 - 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; -}; -} - -#endif diff --git a/src/common/noncopyable.h b/src/common/noncopyable.h index f52f98806..50f1b5d57 100644 --- a/src/common/noncopyable.h +++ b/src/common/noncopyable.h @@ -30,4 +30,4 @@ class noncopyable { } // namespace rocketmq -#endif //__NONCOPYABLE_H__ +#endif // __NONCOPYABLE_H__ diff --git a/src/common/sync_http_client.cpp b/src/common/sync_http_client.cpp deleted file mode 100644 index 78f0292c6..000000000 --- a/src/common/sync_http_client.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include "Logging.h" -#include "url.h" - -using boost::lambda::var; -using boost::asio::ip::tcp; -using boost::asio::deadline_timer; - -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; -} -} // end of namespace ons diff --git a/src/common/url.cpp b/src/common/url.cpp deleted file mode 100644 index f8d915528..000000000 --- a/src/common/url.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 -#include -#include -#include -#include - -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(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(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 ons diff --git a/src/concurrent/concurrent_queue.hpp b/src/concurrent/concurrent_queue.hpp new file mode 100644 index 000000000..1a844e895 --- /dev/null +++ b/src/concurrent/concurrent_queue.hpp @@ -0,0 +1,143 @@ +/* + * 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 __CONCURRENT_QUEUE_HPP__ +#define __CONCURRENT_QUEUE_HPP__ + +#include +#include +#include +#include +#include + +namespace rocketmq { + +template +class concurrent_queue; + +template +class concurrent_queue_node { + public: + // types: + typedef T value_type; + typedef concurrent_queue_node type; + + private: + template ::type, value_type>::value, int>::type = 0> + explicit concurrent_queue_node(E v) : value_(new value_type(std::forward(v))) {} + + template ::value, int>::type = 0> + explicit concurrent_queue_node(E v) : value_(v) {} + + value_type* value_; + type* volatile next_; + + friend concurrent_queue; +}; + +template +class concurrent_queue { + public: + // types: + typedef T value_type; + typedef concurrent_queue_node node_type; + + ~concurrent_queue() { delete[](char*) sentinel; } + + concurrent_queue() : sentinel((node_type*)new char[sizeof(node_type)]) { + sentinel->next_ = sentinel; + head_ = tail_ = sentinel; + } + + bool empty() { return sentinel == tail_.load(); } + + template + void push_back(E v) { + auto* node = new node_type(std::forward(v)); + push_back_impl(node); + } + + std::unique_ptr pop_front() { + node_type* node = pop_front_impl(); + if (node == sentinel) { + return std::unique_ptr(); + } else { + auto val = node->value_; + delete node; + return std::unique_ptr(val); + } + } + + private: + void push_back_impl(node_type* node) noexcept { + node->next_ = sentinel; + auto tail = tail_.exchange(node); + if (tail == sentinel) { + head_.store(node); + } else { + // guarantee: tail is not released + tail->next_ = node; + } + } + + node_type* pop_front_impl() noexcept { + auto head = head_.load(); + for (size_t i = 1;; i++) { + if (head == sentinel) { + // no task, or it is/are not ready + return sentinel; + } + if (head != nullptr) { + if (head_.compare_exchange_weak(head, nullptr)) { + auto next = head->next_; + if (next == sentinel) { + auto t = head; + // only one element + if (tail_.compare_exchange_strong(t, sentinel)) { + t = nullptr; + head_.compare_exchange_strong(t, sentinel); + return head; + } + size_t j = 0; + do { + // push-pop conflict, spin + if (0 == j++ % 10) { + std::this_thread::yield(); + } + next = head->next_; + } while (next == sentinel); + } + head_.store(next); + return head; + } + } else { + head = head_.load(); + } + if (0 == i % 15 && head != sentinel) { + std::this_thread::yield(); + head = head_.load(); + } + } + } + + std::atomic head_, tail_; + node_type* const sentinel; +}; + +} // namespace rocketmq + +#endif // __CONCURRENT_QUEUE_HPP__ diff --git a/src/concurrent/executor.hpp b/src/concurrent/executor.hpp new file mode 100644 index 000000000..06c62b5d4 --- /dev/null +++ b/src/concurrent/executor.hpp @@ -0,0 +1,86 @@ +/* + * 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 __EXECUTOR_HPP__ +#define __EXECUTOR_HPP__ + +#include +#include +#include + +#include "time.hpp" + +namespace rocketmq { + +typedef std::function handler_type; + +struct executor_handler { + handler_type handler_; + std::unique_ptr> promise_; + + template ::type, handler_type>::value, int>::type = 0> + explicit executor_handler(H handler) + : handler_(std::forward(handler)), promise_(new std::promise) {} + + void operator()() noexcept { + // call handler, then set promise + try { + // handler that may throw + handler_(); + promise_->set_value(); + } catch (...) { + try { + // store anything thrown in the promise + promise_->set_exception(std::current_exception()); + } catch (...) { + } // set_exception() may throw too + } + } + + template + void abort(_Ep&& exception) noexcept { + promise_->set_exception(std::make_exception_ptr(std::forward<_Ep>(exception))); + } + + private: + executor_handler() = delete; +}; + +class executor { + public: + virtual ~executor() = default; + + virtual void execute(std::unique_ptr command) = 0; +}; + +class executor_service : virtual public executor { + public: + virtual void shutdown() = 0; + virtual bool is_shutdown() = 0; + virtual std::future submit(const handler_type& task) = 0; +}; + +class scheduled_executor_service : virtual public executor_service { + public: + virtual std::future schedule(const handler_type& task, long delay, time_unit unit) = 0; +}; + +} // namespace rocketmq + +#include "executor_impl.hpp" + +#endif // __EXECUTOR_HPP__ diff --git a/src/concurrent/executor_impl.hpp b/src/concurrent/executor_impl.hpp new file mode 100644 index 000000000..b4b94720e --- /dev/null +++ b/src/concurrent/executor_impl.hpp @@ -0,0 +1,306 @@ +/* + * 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 __EXECUTOR_IMPL_HPP__ +#define __EXECUTOR_IMPL_HPP__ + +#include +#include +#include +#include + +#include "concurrent_queue.hpp" +#include "thread_group.hpp" +#include "time.hpp" + +namespace rocketmq { + +class abstract_executor_service : virtual public executor_service { + public: + std::future submit(const handler_type& task) override { + std::unique_ptr handler(new executor_handler(task)); + std::future fut = handler->promise_->get_future(); + execute(std::move(handler)); + return fut; + } +}; + +class thread_pool_executor : public abstract_executor_service { + public: + explicit thread_pool_executor(std::size_t num_threads, bool start_immediately = true) + : task_queue_(), state_(STOP), num_threads_(num_threads), free_threads_(0) { + if (start_immediately) { + startup(); + } + } + explicit thread_pool_executor(const std::string& name, std::size_t num_threads, bool start_immediately = true) + : task_queue_(), state_(STOP), num_threads_(num_threads), thread_group_(name), free_threads_(0) { + if (start_immediately) { + startup(); + } + } + + virtual void startup() { + if (state_ == STOP) { + state_ = RUNNING; + thread_group_.create_threads(std::bind(&thread_pool_executor::run, this), num_threads_); + thread_group_.start(); + } + } + + void shutdown() override { + if (state_ == RUNNING) { + state_ = STOP; + wakeup_event_.notify_all(); + thread_group_.join(); + } + } + + bool is_shutdown() override { return state_ != RUNNING; } + + std::size_t num_threads() { return num_threads_; } + + protected: + static const unsigned int ACCEPT_NEW_TASKS = 1U << 0U; + static const unsigned int PROCESS_QUEUED_TASKS = 1U << 1U; + + enum state { STOP = 0, SHUTDOWN = PROCESS_QUEUED_TASKS, RUNNING = ACCEPT_NEW_TASKS | PROCESS_QUEUED_TASKS }; + + void execute(std::unique_ptr command) override { + if (state_ & ACCEPT_NEW_TASKS) { + task_queue_.push_back(command.release()); + if (free_threads_ > 0) { + wakeup_event_.notify_one(); + } + } else { + command->abort(std::logic_error("executor don't accept new tasks.")); + } + } + + void run() { + while (state_ & PROCESS_QUEUED_TASKS) { + auto task = task_queue_.pop_front(); + if (task != nullptr) { + task->operator()(); + } else { + if (!(state_ & ACCEPT_NEW_TASKS)) { + // don't accept new tasks + break; + } + + // wait new tasks + std::unique_lock lock(wakeup_mutex_); + if (task_queue_.empty()) { + free_threads_++; + wakeup_event_.wait_for(lock, std::chrono::seconds(5)); + free_threads_--; + } + } + } + } + + protected: + concurrent_queue task_queue_; + + private: + state state_; + + std::size_t num_threads_; + thread_group thread_group_; + + std::mutex wakeup_mutex_; + std::condition_variable wakeup_event_; + std::atomic free_threads_; +}; + +struct scheduled_executor_handler : public executor_handler { + std::chrono::steady_clock::time_point wakeup_time_; + + template ::type, handler_type>::value, int>::type = 0> + explicit scheduled_executor_handler(H handler, const std::chrono::steady_clock::time_point& time) + : executor_handler(std::forward(handler)), wakeup_time_(time) {} + + bool operator<(const scheduled_executor_handler& other) const { return (wakeup_time_ > other.wakeup_time_); } + + static bool less(const std::unique_ptr& a, + const std::unique_ptr& b) { + return *a < *b; + } +}; + +class scheduled_thread_pool_executor : public thread_pool_executor, virtual public scheduled_executor_service { + public: + explicit scheduled_thread_pool_executor(std::size_t num_threads, bool start_immediately = true) + : thread_pool_executor(num_threads, false), + time_queue_(&scheduled_executor_handler::less), + stopped_(true), + single_thread_(false), + timer_thread_() { + timer_thread_.set_target(&scheduled_thread_pool_executor::time_daemon, this); + if (start_immediately) { + startup(); + } + } + explicit scheduled_thread_pool_executor(const std::string& name, + std::size_t num_threads, + bool start_immediately = true) + : thread_pool_executor(name, num_threads, false), + time_queue_(&scheduled_executor_handler::less), + stopped_(true), + single_thread_(false), + timer_thread_(name + "-Timer") { + timer_thread_.set_target(&scheduled_thread_pool_executor::time_daemon, this); + if (start_immediately) { + startup(); + } + } + + explicit scheduled_thread_pool_executor(bool start_immediately = true) + : thread_pool_executor(0, false), + time_queue_(&scheduled_executor_handler::less), + stopped_(true), + single_thread_(true), + timer_thread_() { + timer_thread_.set_target(&scheduled_thread_pool_executor::time_daemon, this); + if (start_immediately) { + startup(); + } + } + explicit scheduled_thread_pool_executor(const std::string& name, bool start_immediately = true) + : thread_pool_executor(name, 0, false), + time_queue_(&scheduled_executor_handler::less), + stopped_(true), + single_thread_(true), + timer_thread_(name + "-Timer") { + timer_thread_.set_target(&scheduled_thread_pool_executor::time_daemon, this); + if (start_immediately) { + startup(); + } + } + + void startup() override { + if (stopped_) { + stopped_ = false; + + // startup task threads + if (!single_thread_) { + thread_pool_executor::startup(); + } + + // start time daemon + timer_thread_.start(); + } + } + + void shutdown() override { + if (!stopped_) { + stopped_ = true; + + time_event_.notify_one(); + timer_thread_.join(); + + if (!single_thread_) { + thread_pool_executor::shutdown(); + } + } + } + + bool is_shutdown() override { return stopped_; } + + std::future submit(const handler_type& task) override { + if (!single_thread_) { + return thread_pool_executor::submit(task); + } else { + return schedule(task, 0, time_unit::milliseconds); + } + } + + std::future schedule(const handler_type& task, long delay, time_unit unit) override { + auto time_point = until_time_point(delay, unit); + std::unique_ptr handler(new scheduled_executor_handler(task, time_point)); + std::future fut = handler->promise_->get_future(); + + { + std::unique_lock lock(time_mutex_); + if (time_queue_.empty() || time_queue_.top()->wakeup_time_ < time_point) { + time_queue_.push(std::move(handler)); + time_event_.notify_one(); + } else { + time_queue_.push(std::move(handler)); + } + } + + return fut; + } + + protected: + void time_daemon() { + std::unique_lock lock(time_mutex_); + while (!stopped_) { + auto now = std::chrono::steady_clock::now(); + while (!time_queue_.empty()) { + auto& top = const_cast&>(time_queue_.top()); + if (top->wakeup_time_ <= now) { + if (!single_thread_) { + thread_pool_executor::execute(std::move(top)); + time_queue_.pop(); + } else { + auto copy = std::move(top); + time_queue_.pop(); + lock.unlock(); + (*copy)(); + lock.lock(); + + // if function cost more time, we need re-watch clock + now = std::chrono::steady_clock::now(); + } + } else { + break; + } + } + + if (!time_queue_.empty()) { + const auto& top = time_queue_.top(); + // wait more 10 milliseconds + time_event_.wait_for(lock, top->wakeup_time_ - now + std::chrono::milliseconds(10)); + } else { + // default, wakeup after 10 seconds for check stopped flag. + time_event_.wait_for(lock, std::chrono::seconds(10)); + } + } + } + + protected: + std::priority_queue, + std::vector>, + std::function&, + const std::unique_ptr&)>> + time_queue_; + + private: + bool stopped_; + + bool single_thread_; + thread timer_thread_; + + std::mutex time_mutex_; + std::condition_variable time_event_; +}; + +} // namespace rocketmq + +#endif // __EXECUTOR_IMPL_HPP__ diff --git a/src/concurrent/latch.hpp b/src/concurrent/latch.hpp new file mode 100644 index 000000000..088dc326a --- /dev/null +++ b/src/concurrent/latch.hpp @@ -0,0 +1,146 @@ +/* + * 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 __LATCH_HPP__ +#define __LATCH_HPP__ + +#include +#include +#include +#include +#include + +#include "time.hpp" + +namespace rocketmq { + +class latch { + public: + explicit latch(ptrdiff_t value) + : start_count_(value), count_(value), promise_(), future_(promise_.get_future()), waiting_(0) { + assert(count_ >= 0); + } + + ~latch() { + if (!is_ready()) { + count_ = -1; + cancel_wait("latch is destructed"); + } + + while (waiting_ > 0) { + std::this_thread::sleep_for(std::chrono::microseconds(100)); + } + } + + latch(const latch&) = delete; + latch& operator=(const latch&) = delete; + + void count_down_and_wait() { + if (try_count_down(1)) { + awake_waiter(); + } else { + wait(); + } + } + + void count_down(ptrdiff_t n = 1) { + if (try_count_down(n)) { + awake_waiter(); + } + } + + bool is_ready() const noexcept { return count_ == 0; } + + void wait() const { + if (count_ > 0) { + waiting_++; + if (count_ > 0) { + future_.wait(); + } + waiting_--; + } + } + + void wait(long timeout, time_unit unit) const { + if (count_ > 0) { + waiting_++; + if (count_ > 0) { + auto time_point = until_time_point(timeout, unit); + future_.wait_until(time_point); + } + waiting_--; + } + } + + void reset() { + ptrdiff_t expected = count_.load(); + if (expected == start_count_ || expected == -1) { + return; + } + while (!count_.compare_exchange_strong(expected, -1)) { + expected = count_.load(); + } + if (expected > 0) { + cancel_wait("reset"); + } + while (waiting_ > 0) { // spin + std::this_thread::yield(); + } + promise_ = std::promise(); + future_ = promise_.get_future(); + count_ = start_count_; + } + + private: + bool try_count_down(ptrdiff_t n) { + for (;;) { + auto c = count_.load(); + if (c <= 0) { + return false; + } + auto nextc = c - n; + if (count_.compare_exchange_weak(c, nextc)) { + return nextc <= 0; + } + } + } + + void awake_waiter() { + try { + promise_.set_value(true); + } catch (...) { + } + } + + void cancel_wait(const char* reason) { + try { + promise_.set_value(false); + } catch (...) { + } + } + + private: + ptrdiff_t start_count_; + std::atomic count_; + std::promise promise_; + std::future future_; + + mutable std::atomic waiting_; +}; + +} // namespace rocketmq + +#endif // __LATCH_HPP__ diff --git a/src/concurrent/thread.hpp b/src/concurrent/thread.hpp new file mode 100644 index 000000000..67d3d8e0c --- /dev/null +++ b/src/concurrent/thread.hpp @@ -0,0 +1,168 @@ +/* + * 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 __THREAD_HPP__ +#define __THREAD_HPP__ + +#include +#include +#include +#include +#include + +#if defined(_WIN32) +#include +#elif defined(__APPLE__) || defined(__linux__) +#include +#if defined(__APPLE__) +#include +#endif +#endif + +namespace rocketmq { + +#ifdef _WIN32 +// From https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx +// Note: The thread name is only set for the thread if the debugger is attached. + +const DWORD MS_VC_EXCEPTION = 0x406D1388; +#pragma pack(push, 8) +typedef struct tagTHREADNAME_INFO { + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. +} THREADNAME_INFO; +#pragma pack(pop) + +void setWindowsThreadName(DWORD dwThreadID, const char* threadName) { + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = threadName; + info.dwThreadID = dwThreadID; + info.dwFlags = 0; +#pragma warning(push) +#pragma warning(disable : 6320 6322) + __try { + RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info); + } __except (EXCEPTION_EXECUTE_HANDLER) { + } +#pragma warning(pop) +} +#endif + +class thread { + public: + thread() {} + thread(const std::string& name) : name_(name) {} + virtual ~thread() = default; + + template + thread(const std::string& name, Function&& f, Args&&... args) + : name_(name), target_(std::bind(std::forward(f), std::forward(args)...)) {} + + template + void set_target(Function&& f, Args&&... args) { + target_ = std::bind(std::forward(f), std::forward(args)...); + } + + void start() { thread_.reset(new std::thread(&thread::run_wrapper, this)); } + + virtual void run() { + if (target_ != nullptr) { + target_(); + } + } + + bool joinable() const noexcept { + if (thread_ != nullptr) { + return thread_->joinable(); + } + return false; + } + + std::thread::id get_id() const noexcept { + if (thread_ != nullptr) { + return thread_->get_id(); + } + return std::thread::id(); + } + + void join() { + if (thread_ != nullptr) { + return thread_->join(); + } + throw std::system_error(std::make_error_code(std::errc::invalid_argument)); + } + + static void set_thread_name(const std::string& name) { + thread*& t_this = get_this_thread(); + if (t_this != nullptr) { + if (t_this->name_ == name) { + return; + } + t_this->name_ = name; + } + +#if defined(_WIN32) + // Naming should not be expensive compared to thread creation and connection set up, but if + // testing shows otherwise we should make this depend on DEBUG again. + setWindowsThreadName(::GetCurrentThreadId(), name.c_str()); +#elif defined(__APPLE__) + // Maximum thread name length on OS X is MAXTHREADNAMESIZE (64 characters). This assumes + // OS X 10.6 or later. + pthread_setname_np(name.substr(0, MAXTHREADNAMESIZE - 1).c_str()); +#elif defined(__linux__) + // Maximum thread name length supported on Linux is 16 including the null terminator. Ideally + // we use short and descriptive thread names that fit: this helps for log readibility as well. + // Since several components set verbose thread names with a uniqifier at the end, we do a split + // truncation of "first7bytes.last7bytes". + if (name.size() > 15) { + std::string shortName = name.substr(0, 7) + '.' + name.substr(name.size() - 7); + pthread_setname_np(pthread_self(), shortName.c_str()); + } else { + pthread_setname_np(pthread_self(), name.c_str()); + } +#endif + } + + static thread*& get_this_thread() { + static thread_local thread* t_this_; + return t_this_; + } + + private: + void run_wrapper() { + get_this_thread() = this; + + if (!name_.empty()) { + std::string name = name_; + name_.clear(); + set_thread_name(name); + } + + run(); + } + + private: + std::string name_; + std::unique_ptr thread_; + std::function target_; +}; + +} // namespace rocketmq + +#endif // __THREAD_HPP__ diff --git a/src/concurrent/thread_group.hpp b/src/concurrent/thread_group.hpp new file mode 100644 index 000000000..a7ea833d4 --- /dev/null +++ b/src/concurrent/thread_group.hpp @@ -0,0 +1,93 @@ +/* + * 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 __THREAD_GROUP_HPP__ +#define __THREAD_GROUP_HPP__ + +#include "thread.hpp" + +namespace rocketmq { + +class thread_group { + public: + // Constructor initialises an empty thread group. + thread_group() : first_(nullptr) {} + thread_group(const std::string& name) : name_(name), first_(nullptr) {} + + template + thread_group(const std::string& name, Function f, std::size_t num_threads) : name_(name), first_(nullptr) { + create_thread(f, num_threads); + } + + // Destructor joins any remaining threads in the group. + ~thread_group() { join(); } + + // Create a new thread in the group. + template + void create_thread(Function f) { + first_ = new item(name_, f, first_); + } + + // Create new threads in the group. + template + void create_threads(Function f, std::size_t num_threads) { + for (std::size_t i = 0; i < num_threads; ++i) { + create_thread(f); + } + } + + void start() { + auto* it = first_; + while (it != nullptr) { + it->start(); + it = it->next_; + } + } + + // Wait for all threads in the group to exit. + void join() { + while (first_) { + first_->thread_.join(); + auto* tmp = first_; + first_ = first_->next_; + delete tmp; + } + } + + private: + // Structure used to track a single thread in the group. + struct item { + template + explicit item(const std::string& name, Function f, item* next) : thread_(name), next_(next) { + thread_.set_target(f); + } + + void start() { thread_.start(); } + + thread thread_; + item* next_; + }; + + private: + std::string name_; + + // The first thread in the group. + item* first_; +}; + +} // namespace rocketmq + +#endif // __THREAD_GROUP_HPP__ diff --git a/src/concurrent/time.hpp b/src/concurrent/time.hpp new file mode 100644 index 000000000..ccb3c0abe --- /dev/null +++ b/src/concurrent/time.hpp @@ -0,0 +1,51 @@ +/* + * 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 __TIME_HPP__ +#define __TIME_HPP__ + +#include +#include + +namespace rocketmq { + +enum time_unit { nanoseconds, microseconds, milliseconds, seconds, minutes, hours }; + +inline std::chrono::steady_clock::time_point until_time_point(long delay, time_unit unit) { + auto now = std::chrono::steady_clock::now(); + switch (unit) { + case nanoseconds: + return now + std::chrono::nanoseconds(delay); + case microseconds: + return now + std::chrono::microseconds(delay); + case milliseconds: + return now + std::chrono::milliseconds(delay); + case seconds: + return now + std::chrono::seconds(delay); + case minutes: + return now + std::chrono::minutes(delay); + case hours: + return now + std::chrono::hours(delay); + default: + break; + } + assert(false); + return now; +} + +} // namespace rocketmq + +#endif // __TIME_HPP__ diff --git a/src/consumer/AllocateMQStrategy.h b/src/consumer/AllocateMQAveragely.h similarity index 61% rename from src/consumer/AllocateMQStrategy.h rename to src/consumer/AllocateMQAveragely.h index e24966c84..6fe0ff75e 100644 --- a/src/consumer/AllocateMQStrategy.h +++ b/src/consumer/AllocateMQAveragely.h @@ -14,34 +14,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef __ALLOCATE_MQ_AVERAGELY_H__ +#define __ALLOCATE_MQ_AVERAGELY_H__ -#ifndef __ALLOCATEMESSAGEQUEUESTRATEGY_H__ -#define __ALLOCATEMESSAGEQUEUESTRATEGY_H__ +#include +#include "AllocateMQStrategy.h" #include "Logging.h" -#include "MQClientException.h" -#include "MQMessageQueue.h" namespace rocketmq { -//& mqAll, - std::vector& cidAll, - std::vector& outReuslt) = 0; -}; -//& mqAll, - std::vector& cidAll, - std::vector& outReuslt) { + void allocate(const std::string& currentCID, + std::vector& mqAll, + std::vector& cidAll, + std::vector& outReuslt) override { outReuslt.clear(); + if (currentCID.empty()) { THROW_MQEXCEPTION(MQClientException, "currentCID is empty", -1); } @@ -74,14 +64,10 @@ class AllocateMQAveragely : public AllocateMQStrategy { 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); - //= 0) // example: range is:-1, index is:1, mqAllSize is:1, - // averageSize is:1, startIndex is:2 - { + 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)); @@ -91,6 +77,6 @@ class AllocateMQAveragely : public AllocateMQStrategy { } }; -// -#endif -#include "ConsumeMsgService.h" -#include "DefaultMQPushConsumer.h" -#include "Logging.h" -#include "MessageAccessor.h" -#include "UtilAll.h" -namespace rocketmq { - -//getMessageListenerType(); -} - -void ConsumeMessageConcurrentlyService::submitConsumeRequest(boost::weak_ptr pullRequest, - vector& msgs) { - boost::shared_ptr 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.post(boost::bind(&ConsumeMessageConcurrentlyService::ConsumeRequest, this, request, msgs)); - } -} -void ConsumeMessageConcurrentlyService::submitConsumeRequestLater(boost::weak_ptr pullRequest, - vector& msgs, - int millis) { - if (msgs.empty()) { - return; - } - boost::shared_ptr 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()) { - 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); - } -} - -void ConsumeMessageConcurrentlyService::static_submitConsumeRequest(void* context, - boost::asio::deadline_timer* t, - boost::weak_ptr pullRequest, - vector& msgs) { - boost::shared_ptr 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, - vector& msgs) { - boost::shared_ptr 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, - vector& msgs) { - boost::shared_ptr 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; - } - - 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()); - } - 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 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::iterator itOrigin = msgs.begin(); itOrigin != msgs.end();) { - bool remove = false; - for (std::vector::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& 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); - } - } -} - -//& msgs, + ProcessQueuePtr processQueue, + const MQMessageQueue& messageQueue, + const bool dispathToConsume) { + m_consumeExecutor.submit( + std::bind(&ConsumeMessageConcurrentlyService::ConsumeRequest, this, msgs, processQueue, messageQueue)); +} + +void ConsumeMessageConcurrentlyService::submitConsumeRequestLater(std::vector& msgs, + ProcessQueuePtr processQueue, + const MQMessageQueue& messageQueue) { + m_scheduledExecutorService.schedule( + std::bind(&ConsumeMessageConcurrentlyService::submitConsumeRequest, this, msgs, processQueue, messageQueue, true), + 5000L, time_unit::milliseconds); +} + +void ConsumeMessageConcurrentlyService::ConsumeRequest(std::vector& msgs, + ProcessQueuePtr processQueue, + const MQMessageQueue& messageQueue) { + if (processQueue->isDropped()) { + LOG_WARN_NEW("the message queue not be able to consume, because it's dropped. group={} {}", + m_consumer->getDefaultMQPushConsumerConfig()->getGroupName(), messageQueue.toString()); + return; + } + + // empty + if (msgs.empty()) { + LOG_WARN_NEW("the msg of pull result is EMPTY, its mq:{}", messageQueue.toString()); + return; + } + + m_consumer->resetRetryTopic( + msgs, m_consumer->getDefaultMQPushConsumerConfig()->getGroupName()); // set where to sendMessageBack + + ConsumeStatus status = RECONSUME_LATER; + try { + auto consumeTimestamp = UtilAll::currentTimeMillis(); + processQueue->setLastConsumeTimestamp(consumeTimestamp); + if (!msgs.empty()) { + auto timestamp = UtilAll::to_string(consumeTimestamp); + for (auto& msg : msgs) { + MessageAccessor::setConsumeStartTimeStamp(*msg, timestamp); + } + } + status = m_messageListener->consumeMessage(msgs); + } catch (std::exception& e) { + // ... + } + + // processConsumeResult + if (!processQueue->isDropped()) { + int ackIndex = -1; + switch (status) { + case CONSUME_SUCCESS: + ackIndex = msgs.size() - 1; + break; + case RECONSUME_LATER: + ackIndex = -1; + break; + default: + break; + } + + switch (m_consumer->messageModel()) { + case BROADCASTING: + // Note: broadcasting reconsume should do by application, as it has big affect to broker cluster + for (size_t i = ackIndex + 1; i < msgs.size(); i++) { + const auto& msg = msgs[i]; + LOG_WARN_NEW("BROADCASTING, the message consume failed, drop it, {}", msg->toString()); + } + break; + case CLUSTERING: { + // send back msg to broker + std::vector msgBackFailed; + int idx = ackIndex + 1; + for (auto iter = msgs.begin() + idx; iter != msgs.end(); idx++) { + LOG_WARN_NEW("consume fail, MQ is:{}, its msgId is:{}, index is:{}, reconsume times is:{}", + messageQueue.toString(), (*iter)->getMsgId(), idx, (*iter)->getReconsumeTimes()); + auto& msg = (*iter); + bool result = m_consumer->sendMessageBack(*msg, 0, messageQueue.getBrokerName()); + if (!result) { + msg->setReconsumeTimes(msg->getReconsumeTimes() + 1); + msgBackFailed.push_back(msg); + iter = msgs.erase(iter); + } else { + iter++; + } + } + + if (!msgBackFailed.empty()) { + // send back failed, reconsume later + submitConsumeRequestLater(msgBackFailed, processQueue, messageQueue); + } + } break; + default: + break; + } + + // update offset + int64_t offset = processQueue->removeMessage(msgs); + if (offset >= 0 && !processQueue->isDropped()) { + m_consumer->getOffsetStore()->updateOffset(messageQueue, offset, true); + } + } +} + +} // namespace rocketmq diff --git a/src/consumer/ConsumeMessageOrderlyService.cpp b/src/consumer/ConsumeMessageOrderlyService.cpp old mode 100644 new mode 100755 index fcff4a406..449281b80 --- a/src/consumer/ConsumeMessageOrderlyService.cpp +++ b/src/consumer/ConsumeMessageOrderlyService.cpp @@ -1,241 +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. - */ -#if !defined(WIN32) && !defined(__APPLE__) -#include -#endif - -#include -#include "ConsumeMsgService.h" -#include "DefaultMQPushConsumer.h" -#include "Logging.h" -#include "Rebalance.h" -#include "UtilAll.h" - -namespace rocketmq { - -//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, - vector& msgs) { - boost::shared_ptr 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, - bool tryLockMQ, - boost::asio::deadline_timer* t) { - boost::shared_ptr 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 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) { - boost::shared_ptr request = pullRequest.lock(); - if (!request) { - LOG_WARN("Pull request has been released"); - return; - } - bool bGetMutex = false; - boost::unique_lock 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 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()); - } - ConsumeStatus consumeStatus = m_pMessageListener->consumeMessage(msgs); - if (consumeStatus == RECONSUME_LATER) { - 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 { - 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, - bool tryLockMQ, - int millisDelay) { - boost::shared_ptr 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 +/* + * 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 "ConsumeMsgService.h" +#include "Logging.h" +#include "OffsetStore.h" +#include "RebalanceImpl.h" +#include "UtilAll.h" + +namespace rocketmq { + +const uint64_t ConsumeMessageOrderlyService::MaxTimeConsumeContinuously = 60000; + +ConsumeMessageOrderlyService::ConsumeMessageOrderlyService(DefaultMQPushConsumerImpl* consumer, + int threadCount, + MQMessageListener* msgListener) + : m_consumer(consumer), + m_messageListener(msgListener), + m_consumeExecutor("OderlyConsumeService", threadCount, false), + m_scheduledExecutorService(false) {} + +ConsumeMessageOrderlyService::~ConsumeMessageOrderlyService() = default; + +void ConsumeMessageOrderlyService::start() { + m_consumeExecutor.startup(); + + m_scheduledExecutorService.startup(); + m_scheduledExecutorService.schedule(std::bind(&ConsumeMessageOrderlyService::lockMQPeriodically, this), + ProcessQueue::RebalanceLockInterval, time_unit::milliseconds); +} + +void ConsumeMessageOrderlyService::shutdown() { + stopThreadPool(); + unlockAllMQ(); +} + +void ConsumeMessageOrderlyService::stopThreadPool() { + m_consumeExecutor.shutdown(); + m_scheduledExecutorService.shutdown(); +} + +void ConsumeMessageOrderlyService::lockMQPeriodically() { + m_consumer->getRebalanceImpl()->lockAll(); + + m_scheduledExecutorService.schedule(std::bind(&ConsumeMessageOrderlyService::lockMQPeriodically, this), + ProcessQueue::RebalanceLockInterval, time_unit::milliseconds); +} + +void ConsumeMessageOrderlyService::unlockAllMQ() { + m_consumer->getRebalanceImpl()->unlockAll(false); +} + +bool ConsumeMessageOrderlyService::lockOneMQ(const MQMessageQueue& mq) { + return m_consumer->getRebalanceImpl()->lock(mq); +} + +void ConsumeMessageOrderlyService::submitConsumeRequest(std::vector& msgs, + ProcessQueuePtr processQueue, + const MQMessageQueue& messageQueue, + const bool dispathToConsume) { + if (dispathToConsume) { + m_consumeExecutor.submit( + std::bind(&ConsumeMessageOrderlyService::ConsumeRequest, this, processQueue, messageQueue)); + } +} + +void ConsumeMessageOrderlyService::submitConsumeRequestLater(ProcessQueuePtr processQueue, + const MQMessageQueue& messageQueue, + const long suspendTimeMillis) { + long timeMillis = suspendTimeMillis; + if (timeMillis == -1) { + timeMillis = 1000; + } + + timeMillis = std::max(10L, std::min(timeMillis, 30000L)); + + static std::vector dummy; + m_scheduledExecutorService.schedule(std::bind(&ConsumeMessageOrderlyService::submitConsumeRequest, this, + std::ref(dummy), processQueue, messageQueue, true), + timeMillis, time_unit::milliseconds); +} + +void ConsumeMessageOrderlyService::tryLockLaterAndReconsume(const MQMessageQueue& mq, + ProcessQueuePtr processQueue, + const long delayMills) { + m_scheduledExecutorService.schedule( + [this, mq, processQueue]() { + bool lockOK = lockOneMQ(mq); + if (lockOK) { + submitConsumeRequestLater(processQueue, mq, 10); + } else { + submitConsumeRequestLater(processQueue, mq, 3000); + } + }, + delayMills, time_unit::milliseconds); +} + +void ConsumeMessageOrderlyService::ConsumeRequest(ProcessQueuePtr processQueue, const MQMessageQueue& messageQueue) { + if (processQueue->isDropped()) { + LOG_WARN_NEW("run, the message queue not be able to consume, because it's dropped. {}", messageQueue.toString()); + return; + } + + auto objLock = m_messageQueueLock.fetchLockObject(messageQueue); + std::lock_guard lock(*objLock); + + if (BROADCASTING == m_consumer->messageModel() || (processQueue->isLocked() && !processQueue->isLockExpired())) { + auto beginTime = UtilAll::currentTimeMillis(); + for (bool continueConsume = true; continueConsume;) { + if (processQueue->isDropped()) { + LOG_WARN_NEW("the message queue not be able to consume, because it's dropped. {}", messageQueue.toString()); + break; + } + + if (CLUSTERING == m_consumer->messageModel() && !processQueue->isLocked()) { + LOG_WARN_NEW("the message queue not locked, so consume later, {}", messageQueue.toString()); + tryLockLaterAndReconsume(messageQueue, processQueue, 10); + break; + } + + if (CLUSTERING == m_consumer->messageModel() && !processQueue->isLockExpired()) { + LOG_WARN_NEW("the message queue lock expired, so consume later, {}", messageQueue.toString()); + tryLockLaterAndReconsume(messageQueue, processQueue, 10); + break; + } + + auto interval = UtilAll::currentTimeMillis() - beginTime; + if (interval > MaxTimeConsumeContinuously) { + submitConsumeRequestLater(processQueue, messageQueue, 10); + break; + } + + const int consumeBatchSize = m_consumer->getDefaultMQPushConsumerConfig()->getConsumeMessageBatchMaxSize(); + + std::vector msgs; + processQueue->takeMessages(msgs, consumeBatchSize); + m_consumer->resetRetryTopic(msgs, m_consumer->getDefaultMQPushConsumerConfig()->getGroupName()); + if (!msgs.empty()) { + ConsumeStatus status = RECONSUME_LATER; + try { + std::lock_guard lock(processQueue->getLockConsume()); + if (processQueue->isDropped()) { + LOG_WARN_NEW("consumeMessage, the message queue not be able to consume, because it's dropped. {}", + messageQueue.toString()); + break; + } + + status = m_messageListener->consumeMessage(msgs); + } catch (std::exception& e) { + // ... + } + + // processConsumeResult + long commitOffset = -1L; + switch (status) { + case CONSUME_SUCCESS: + commitOffset = processQueue->commit(); + break; + case RECONSUME_LATER: + processQueue->makeMessageToCosumeAgain(msgs); + submitConsumeRequestLater(processQueue, messageQueue, -1); + continueConsume = false; + break; + default: + break; + } + + if (commitOffset >= 0 && !processQueue->isDropped()) { + m_consumer->getOffsetStore()->updateOffset(messageQueue, commitOffset, false); + } + } else { + continueConsume = false; + } + } + } else { + if (processQueue->isDropped()) { + LOG_WARN_NEW("the message queue not be able to consume, because it's dropped. {}", messageQueue.toString()); + return; + } + + tryLockLaterAndReconsume(messageQueue, processQueue, 100); + } +} + +} // namespace rocketmq diff --git a/src/consumer/ConsumeMsgService.h b/src/consumer/ConsumeMsgService.h old mode 100644 new mode 100755 index a6c720617..c854d76cf --- a/src/consumer/ConsumeMsgService.h +++ b/src/consumer/ConsumeMsgService.h @@ -1,114 +1,110 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include "Logging.h" -#include "MQMessageListener.h" -#include "PullRequest.h" - -namespace rocketmq { -class MQConsumer; -// request, vector& 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 request, vector& msgs); - virtual MessageListenerType getConsumeMsgSerivceListenerType(); - virtual void stopThreadPool(); - - void ConsumeRequest(boost::weak_ptr request, vector& msgs); - void submitConsumeRequestLater(boost::weak_ptr request, vector& msgs, int millis); - - void triggersubmitConsumeRequestLater(boost::asio::deadline_timer* t, - boost::weak_ptr pullRequest, - vector& msgs); - static void static_submitConsumeRequest(void* context, - boost::asio::deadline_timer* t, - boost::weak_ptr pullRequest, - vector& msgs); - - private: - void resetRetryTopic(vector& 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 request, vector& msgs); - virtual void stopThreadPool(); - virtual MessageListenerType getConsumeMsgSerivceListenerType(); - - void boost_asio_work(); - // void tryLockLaterAndReconsume(boost::weak_ptr request, bool tryLockMQ); - void tryLockLaterAndReconsumeDelay(boost::weak_ptr request, bool tryLockMQ, int millisDelay); - static void static_submitConsumeRequestLater(void* context, - boost::weak_ptr request, - bool tryLockMQ, - boost::asio::deadline_timer* t); - void ConsumeRequest(boost::weak_ptr 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 m_async_service_thread; -}; - -//& msgs, + ProcessQueuePtr processQueue, + const MQMessageQueue& messageQueue, + const bool dispathToConsume) = 0; +}; + +class ConsumeMessageConcurrentlyService : public ConsumeMsgService { + public: + ConsumeMessageConcurrentlyService(DefaultMQPushConsumerImpl*, int threadCount, MQMessageListener* msgListener); + ~ConsumeMessageConcurrentlyService() override; + + void start() override; + void shutdown() override; + + void submitConsumeRequest(std::vector& msgs, + ProcessQueuePtr processQueue, + const MQMessageQueue& messageQueue, + const bool dispathToConsume) override; + + void ConsumeRequest(std::vector& msgs, + ProcessQueuePtr processQueue, + const MQMessageQueue& messageQueue); + + private: + void submitConsumeRequestLater(std::vector& msgs, + ProcessQueuePtr processQueue, + const MQMessageQueue& messageQueue); + + private: + DefaultMQPushConsumerImpl* m_consumer; + MQMessageListener* m_messageListener; + + thread_pool_executor m_consumeExecutor; + scheduled_thread_pool_executor m_scheduledExecutorService; +}; + +class ConsumeMessageOrderlyService : public ConsumeMsgService { + public: + ConsumeMessageOrderlyService(DefaultMQPushConsumerImpl*, int threadCount, MQMessageListener* msgListener); + ~ConsumeMessageOrderlyService() override; + + void start() override; + void shutdown() override; + void stopThreadPool(); + + void submitConsumeRequest(std::vector& msgs, + ProcessQueuePtr processQueue, + const MQMessageQueue& messageQueue, + const bool dispathToConsume) override; + void submitConsumeRequestLater(ProcessQueuePtr processQueue, + const MQMessageQueue& messageQueue, + const long suspendTimeMillis); + void tryLockLaterAndReconsume(const MQMessageQueue& mq, ProcessQueuePtr processQueue, const long delayMills); + + void ConsumeRequest(ProcessQueuePtr processQueue, const MQMessageQueue& messageQueue); + + void lockMQPeriodically(); + void unlockAllMQ(); + bool lockOneMQ(const MQMessageQueue& mq); + + private: + static const uint64_t MaxTimeConsumeContinuously; + + private: + DefaultMQPushConsumerImpl* m_consumer; + MQMessageListener* m_messageListener; + + MessageQueueLock m_messageQueueLock; + thread_pool_executor m_consumeExecutor; + scheduled_thread_pool_executor m_scheduledExecutorService; +}; + +} // namespace rocketmq + +#endif // __CONSUME_MESSAGE_SERVICE_H__ diff --git a/src/consumer/DefaultMQPullConsumer.cpp b/src/consumer/DefaultMQPullConsumer.cpp index 1f58e86a4..295e73da4 100644 --- a/src/consumer/DefaultMQPullConsumer.cpp +++ b/src/consumer/DefaultMQPullConsumer.cpp @@ -14,406 +14,99 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "DefaultMQPullConsumer.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 { -// rpcHook) { + // set default group name + if (groupname.empty()) { + setGroupName(DEFAULT_CONSUMER_GROUP); + } else { + setGroupName(groupname); + } - //registerConsumer(this); - if (!registerOK) { - m_serviceState = CREATE_JUST; - THROW_MQEXCEPTION( - MQClientException, - "The cousumer group[" + getGroupName() + "] has been created before, specify another name please.", -1); - } + // TODO: DefaultMQPullConsumerImpl +} - //load(); - } catch (MQClientException& e) { - bStartFailed = true; - errorMsg = std::string(e.what()); - } +DefaultMQPullConsumer::~DefaultMQPullConsumer() = default; - 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 DefaultMQPullConsumer::start() { + m_pullConsumerDelegate->start(); } void DefaultMQPullConsumer::shutdown() { - switch (m_serviceState) { - case RUNNING: { - LOG_INFO("DefaultMQPullConsumer:%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; - } + m_pullConsumerDelegate->shutdown(); } -bool DefaultMQPullConsumer::sendMessageBack(MQMessageExt& msg, int delayLevel, string& brokerName) { - return true; +bool DefaultMQPullConsumer::sendMessageBack(MQMessageExt& msg, int delayLevel) { + return m_pullConsumerDelegate->sendMessageBack(msg, delayLevel); } -void DefaultMQPullConsumer::fetchSubscribeMessageQueues(const string& topic, vector& mqs) { - mqs.clear(); - try { - const string localTopic = NameSpaceUtil::withNameSpace(topic, getNameSpace()); - getFactory()->fetchSubscribeMessageQueues(localTopic, mqs, getSessionCredentials()); - } catch (MQException& e) { - LOG_ERROR(e.what()); - } +bool DefaultMQPullConsumer::sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) { + return m_pullConsumerDelegate->sendMessageBack(msg, delayLevel, brokerName); } -void DefaultMQPullConsumer::updateTopicSubscribeInfo(const string& topic, vector& info) {} +void DefaultMQPullConsumer::fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) { + m_pullConsumerDelegate->fetchMessageQueuesInBalance(topic, mqs); +} -void DefaultMQPullConsumer::registerMessageQueueListener(const string& topic, MQueueListener* pListener) { - m_registerTopics.insert(topic); - if (pListener) { - m_pMessageQueueListener = pListener; - } +void DefaultMQPullConsumer::registerMessageQueueListener(const std::string& topic, MQueueListener* listener) { + m_pullConsumerDelegate->registerMessageQueueListener(topic, listener); } PullResult DefaultMQPullConsumer::pull(const MQMessageQueue& mq, - const string& subExpression, - int64 offset, + const std::string& subExpression, + int64_t offset, int maxNums) { - return pullSyncImpl(mq, subExpression, offset, maxNums, false); + return m_pullConsumerDelegate->pull(mq, subExpression, offset, maxNums); } void DefaultMQPullConsumer::pull(const MQMessageQueue& mq, - const string& subExpression, - int64 offset, + const std::string& subExpression, + int64_t offset, int maxNums, - PullCallback* pPullCallback) { - pullAsyncImpl(mq, subExpression, offset, maxNums, false, pPullCallback); + PullCallback* pullCallback) { + m_pullConsumerDelegate->pull(mq, subExpression, offset, maxNums, pullCallback); } PullResult DefaultMQPullConsumer::pullBlockIfNotFound(const MQMessageQueue& mq, - const string& subExpression, - int64 offset, + const std::string& subExpression, + int64_t offset, int maxNums) { - return pullSyncImpl(mq, subExpression, offset, maxNums, true); + return m_pullConsumerDelegate->pullBlockIfNotFound(mq, subExpression, offset, maxNums); } void DefaultMQPullConsumer::pullBlockIfNotFound(const MQMessageQueue& mq, - const string& subExpression, - int64 offset, + const std::string& subExpression, + int64_t offset, int maxNums, - PullCallback* pPullCallback) { - pullAsyncImpl(mq, subExpression, offset, maxNums, true, pPullCallback); -} - -PullResult DefaultMQPullConsumer::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); - - // pSData(FilterAPI::buildSubscriptionData(mq.getTopic(), subExpression)); - - int timeoutMillis = block ? 1000 * 30 : 1000 * 10; - - try { - unique_ptr 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, //processPullResult(mq, pullResult.get(), pSData.get()); - if (m_useNameSpaceMode) { - MessageAccessor::withoutNameSpace(pr.msgFoundList, m_nameSpace); - } - return pr; - } catch (MQException& e) { - LOG_ERROR(e.what()); - } - return PullResult(BROKER_TIMEOUT); -} - -void DefaultMQPullConsumer::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); - - // pSData(FilterAPI::buildSubscriptionData(mq.getTopic(), subExpression)); - - int timeoutMillis = block ? 1000 * 30 : 1000 * 10; - - // 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(e.what()); - } -} - -void DefaultMQPullConsumer::subscriptionAutomatically(const string& topic) { - SubscriptionData* pSdata = m_pRebalance->getSubscriptionData(topic); - if (pSdata == NULL) { - unique_ptr subscriptionData(FilterAPI::buildSubscriptionData(topic, SUB_ALL)); - m_pRebalance->setSubscriptionData(topic, subscriptionData.release()); - } -} - -void DefaultMQPullConsumer::updateConsumeOffset(const MQMessageQueue& mq, int64 offset) { - m_pOffsetStore->updateOffset(mq, offset); -} - -void DefaultMQPullConsumer::removeConsumeOffset(const MQMessageQueue& mq) { - m_pOffsetStore->removeOffset(mq); + PullCallback* pullCallback) { + m_pullConsumerDelegate->pullBlockIfNotFound(mq, subExpression, offset, maxNums, pullCallback); } -int64 DefaultMQPullConsumer::fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore) { - return m_pOffsetStore->readOffset(mq, fromStore ? READ_FROM_STORE : MEMORY_FIRST_THEN_STORE, getSessionCredentials()); +void DefaultMQPullConsumer::updateConsumeOffset(const MQMessageQueue& mq, int64_t offset) { + m_pullConsumerDelegate->updateConsumeOffset(mq, offset); } -void DefaultMQPullConsumer::persistConsumerOffset() { - /*As do not execute rebalance for pullConsumer now, requestTable is always - empty - map requestTable = - m_pRebalance->getPullRequestTable(); - map::iterator it = requestTable.begin(); - vector mqs; - for (; it != requestTable.end(); ++it) - { - if (it->second) - { - mqs.push_back(it->first); - } - } - m_pOffsetStore->persistAll(mqs);*/ +int64_t DefaultMQPullConsumer::fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore) { + return m_pullConsumerDelegate->fetchConsumeOffset(mq, fromStore); } -void DefaultMQPullConsumer::persistConsumerOffsetByResetOffset() {} - -void DefaultMQPullConsumer::persistConsumerOffset4PullConsumer(const MQMessageQueue& mq) { - if (isServiceStateOk()) { - m_pOffsetStore->persist(mq, getSessionCredentials()); - } +void DefaultMQPullConsumer::fetchMessageQueuesInBalance(const std::string& topic, std::vector& mqs) { + m_pullConsumerDelegate->fetchMessageQueuesInBalance(topic, mqs); } -void DefaultMQPullConsumer::fetchMessageQueuesInBalance(const string& topic, vector mqs) {} - -void DefaultMQPullConsumer::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 DefaultMQPullConsumer::setRPCHook(std::shared_ptr rpcHook) { + // dynamic_cast(m_pullConsumerDelegate.get())->setRPCHook(rpcHook); } -void DefaultMQPullConsumer::doRebalance() {} - -void DefaultMQPullConsumer::copySubscription() { - set::iterator it = m_registerTopics.begin(); - for (; it != m_registerTopics.end(); ++it) { - unique_ptr subscriptionData(FilterAPI::buildSubscriptionData((*it), SUB_ALL)); - m_pRebalance->setSubscriptionData((*it), subscriptionData.release()); - } -} - -ConsumeType DefaultMQPullConsumer::getConsumeType() { - return CONSUME_ACTIVELY; -} - -ConsumeFromWhere DefaultMQPullConsumer::getConsumeFromWhere() { - return CONSUME_FROM_LAST_OFFSET; -} - -void DefaultMQPullConsumer::getSubscriptions(vector& result) { - set::iterator it = m_registerTopics.begin(); - for (; it != m_registerTopics.end(); ++it) { - SubscriptionData ms(*it, SUB_ALL); - result.push_back(ms); - } -} - -bool DefaultMQPullConsumer::producePullMsgTask(boost::weak_ptr pullRequest) { - return true; -} - -Rebalance* DefaultMQPullConsumer::getRebalance() const { - return NULL; -} -// we should deal with name space before producer start. -bool DefaultMQPullConsumer::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 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; -} -// +// #endif + +// #include "AllocateMQAveragely.h" +// #include "CommunicationMode.h" +// #include "FilterAPI.h" +// #include "Logging.h" +// #include "MQAdminImpl.h" +// #include "MQClientAPIImpl.h" +// #include "MQClientInstance.h" +// #include "MQClientManager.h" +// #include "MQProtos.h" +// #include "OffsetStore.h" +// #include "PullAPIWrapper.h" +// #include "PullSysFlag.h" +// #include "RebalanceImpl.h" +// #include "Validators.h" + +// namespace rocketmq { + +// DefaultMQPullConsumer::DefaultMQPullConsumer(const string& groupname) : DefaultMQPullConsumer(groupname, nullptr) {} + +// DefaultMQPullConsumer::DefaultMQPullConsumer(const string& groupname, std::shared_ptr rpcHook) +// : MQClient(rpcHook), +// m_rebalanceImpl(new RebalancePullImpl(this)), +// m_pullAPIWrapper(nullptr), +// m_offsetStore(nullptr), +// m_messageQueueListener(nullptr) { +// // set default group name +// if (groupname.empty()) { +// setGroupName(DEFAULT_CONSUMER_GROUP); +// } else { +// setGroupName(groupname); +// } +// } + +// DefaultMQPullConsumer::~DefaultMQPullConsumer() = default; + +// void DefaultMQPullConsumer::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 +// switch (m_serviceState) { +// case CREATE_JUST: { +// m_serviceState = START_FAILED; + +// // data +// checkConfig(); + +// copySubscription(); + +// if (getMessageModel() == CLUSTERING) { +// changeInstanceNameToPID(); +// } + +// MQClient::start(); +// LOG_INFO_NEW("DefaultMQPullConsumer:{} start", getGroupName()); + +// // reset rebalance; +// m_rebalanceImpl->setConsumerGroup(getGroupName()); +// m_rebalanceImpl->setMessageModel(getMessageModel()); +// m_rebalanceImpl->setAllocateMQStrategy(getAllocateMQStrategy()); +// m_rebalanceImpl->setMQClientFactory(m_clientInstance.get()); + +// m_pullAPIWrapper.reset(new PullAPIWrapper(m_clientInstance.get(), getGroupName())); + +// // msg model +// switch (getMessageModel()) { +// case BROADCASTING: +// m_offsetStore.reset(new LocalFileOffsetStore(m_clientInstance.get(), getGroupName())); +// break; +// case CLUSTERING: +// m_offsetStore.reset(new RemoteBrokerOffsetStore(m_clientInstance.get(), getGroupName())); +// break; +// } +// m_offsetStore->load(); + +// // register consumer +// bool registerOK = m_clientInstance->registerConsumer(getGroupName(), this); +// if (!registerOK) { +// m_serviceState = CREATE_JUST; +// THROW_MQEXCEPTION( +// MQClientException, +// "The cousumer group[" + getGroupName() + "] has been created before, specify another name please.", -1); +// } + +// m_clientInstance->start(); +// LOG_INFO_NEW("the consumer [{}] start OK", getGroupName()); +// m_serviceState = RUNNING; +// break; +// } +// case RUNNING: +// case START_FAILED: +// case SHUTDOWN_ALREADY: +// break; +// default: +// break; +// } +// } + +// void DefaultMQPullConsumer::shutdown() { +// switch (m_serviceState) { +// case RUNNING: { +// LOG_INFO("DefaultMQPullConsumer:%s shutdown", m_groupName.c_str()); +// persistConsumerOffset(); +// m_clientInstance->unregisterConsumer(getGroupName()); +// m_clientInstance->shutdown(); +// m_serviceState = SHUTDOWN_ALREADY; +// break; +// } +// case SHUTDOWN_ALREADY: +// case CREATE_JUST: +// break; +// default: +// break; +// } +// } + +// bool DefaultMQPullConsumer::sendMessageBack(MQMessageExt& msg, int delayLevel) { +// return false; +// } + +// void DefaultMQPullConsumer::fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) { +// mqs.clear(); +// try { +// m_clientInstance->getMQAdminImpl()->fetchSubscribeMessageQueues(topic, mqs); +// } catch (MQException& e) { +// LOG_ERROR(e.what()); +// } +// } + +// void DefaultMQPullConsumer::updateTopicSubscribeInfo(const std::string& topic, std::vector& info) {} + +// void DefaultMQPullConsumer::registerMessageQueueListener(const std::string& topic, MQueueListener* listener) { +// m_registerTopics.insert(topic); +// if (listener != nullptr) { +// m_messageQueueListener = listener; +// } +// } + +// PullResult DefaultMQPullConsumer::pull(const MQMessageQueue& mq, +// const std::string& subExpression, +// int64_t offset, +// int maxNums) { +// return pullSyncImpl(mq, subExpression, offset, maxNums, false); +// } + +// void DefaultMQPullConsumer::pull(const MQMessageQueue& mq, +// const std::string& subExpression, +// int64_t offset, +// int maxNums, +// PullCallback* pPullCallback) { +// pullAsyncImpl(mq, subExpression, offset, maxNums, false, pPullCallback); +// } + +// PullResult DefaultMQPullConsumer::pullBlockIfNotFound(const MQMessageQueue& mq, +// const std::string& subExpression, +// int64_t offset, +// int maxNums) { +// return pullSyncImpl(mq, subExpression, offset, maxNums, true); +// } + +// void DefaultMQPullConsumer::pullBlockIfNotFound(const MQMessageQueue& mq, +// const std::string& subExpression, +// int64_t offset, +// int maxNums, +// PullCallback* pPullCallback) { +// pullAsyncImpl(mq, subExpression, offset, maxNums, true, pPullCallback); +// } + +// PullResult DefaultMQPullConsumer::pullSyncImpl(const MQMessageQueue& mq, +// const std::string& subExpression, +// int64_t 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 +// std::unique_ptr pSData(FilterAPI::buildSubscriptionData(mq.getTopic(), subExpression)); + +// int timeoutMillis = block ? 1000 * 30 : 1000 * 10; + +// try { +// std::unique_ptr pullResult(m_pullAPIWrapper->pullKernelImpl(mq, // 1 +// pSData->getSubString(), // 2 +// 0L, // 3 +// offset, // 4 +// maxNums, // 5 +// sysFlag, // 6 +// 0, // 7 +// 1000 * 20, // 8 +// timeoutMillis, // 9 +// ComMode_SYNC, // 10 +// nullptr)); // callback +// assert(pullResult != nullptr); +// return m_pullAPIWrapper->processPullResult(mq, *pullResult, pSData.get()); +// } catch (MQException& e) { +// LOG_ERROR(e.what()); +// } +// return PullResult(BROKER_TIMEOUT); +// } + +// void DefaultMQPullConsumer::pullAsyncImpl(const MQMessageQueue& mq, +// const std::string& subExpression, +// int64_t 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 +// std::unique_ptr pSData(FilterAPI::buildSubscriptionData(mq.getTopic(), subExpression)); + +// int timeoutMillis = block ? 1000 * 30 : 1000 * 10; + +// try { +// std::unique_ptr pullResult(m_pullAPIWrapper->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)); +// } catch (MQException& e) { +// LOG_ERROR(e.what()); +// } +// } + +// void DefaultMQPullConsumer::subscriptionAutomatically(const std::string& topic) { +// SubscriptionDataPtr pSdata = m_rebalanceImpl->getSubscriptionData(topic); +// if (pSdata == nullptr) { +// std::unique_ptr subscriptionData(FilterAPI::buildSubscriptionData(topic, SUB_ALL)); +// m_rebalanceImpl->setSubscriptionData(topic, subscriptionData.release()); +// } +// } + +// void DefaultMQPullConsumer::updateConsumeOffset(const MQMessageQueue& mq, int64_t offset) { +// m_offsetStore->updateOffset(mq, offset, false); +// } + +// void DefaultMQPullConsumer::removeConsumeOffset(const MQMessageQueue& mq) { +// m_offsetStore->removeOffset(mq); +// } + +// int64_t DefaultMQPullConsumer::fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore) { +// return m_offsetStore->readOffset(mq, fromStore ? READ_FROM_STORE : MEMORY_FIRST_THEN_STORE); +// } + +// void DefaultMQPullConsumer::persistConsumerOffset() { +// /*As do not execute rebalance for pullConsumer now, requestTable is always +// empty +// map requestTable = +// m_pRebalance->getPullRequestTable(); +// map::iterator it = requestTable.begin(); +// vector mqs; +// for (; it != requestTable.end(); ++it) +// { +// if (it->second) +// { +// mqs.push_back(it->first); +// } +// } +// m_pOffsetStore->persistAll(mqs);*/ +// } + +// void DefaultMQPullConsumer::persistConsumerOffset4PullConsumer(const MQMessageQueue& mq) { +// if (isServiceStateOk()) { +// m_offsetStore->persist(mq); +// } +// } + +// void DefaultMQPullConsumer::fetchMessageQueuesInBalance(const std::string& topic, std::vector& mqs) {} + +// void DefaultMQPullConsumer::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 DefaultMQPullConsumer::doRebalance() {} + +// void DefaultMQPullConsumer::copySubscription() { +// std::set::iterator it = m_registerTopics.begin(); +// for (; it != m_registerTopics.end(); ++it) { +// std::unique_ptr subscriptionData(FilterAPI::buildSubscriptionData((*it), SUB_ALL)); +// m_rebalanceImpl->setSubscriptionData((*it), subscriptionData.release()); +// } +// } + +// std::string DefaultMQPullConsumer::groupName() const { +// return getGroupName(); +// } + +// MessageModel DefaultMQPullConsumer::messageModel() const { +// return getMessageModel(); +// } + +// ConsumeType DefaultMQPullConsumer::consumeType() const { +// return CONSUME_ACTIVELY; +// } + +// ConsumeFromWhere DefaultMQPullConsumer::consumeFromWhere() const { +// return CONSUME_FROM_LAST_OFFSET; +// } + +// std::vector DefaultMQPullConsumer::subscriptions() const { +// std::vector result; +// std::set::iterator it = m_registerTopics.begin(); +// for (; it != m_registerTopics.end(); ++it) { +// SubscriptionData ms(*it, SUB_ALL); +// result.push_back(ms); +// } +// return result; +// } + +// } // namespace rocketmq diff --git a/src/consumer/DefaultMQPullConsumerImpl.h b/src/consumer/DefaultMQPullConsumerImpl.h new file mode 100755 index 000000000..dc39eb4d4 --- /dev/null +++ b/src/consumer/DefaultMQPullConsumerImpl.h @@ -0,0 +1,173 @@ +// /* +// * 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 __DEFAULT_MQ_PULL_CONSUMER_IMPL_H__ +// #define __DEFAULT_MQ_PULL_CONSUMER_IMPL_H__ + +// #include +// #include + +// #include "AllocateMQStrategy.h" +// #include "MQClientConfig.h" +// #include "MQConsumer.h" +// #include "MQueueListener.h" + +// namespace rocketmq { + +// class RebalanceImpl; +// class SubscriptionData; +// class OffsetStore; +// class PullAPIWrapper; + +// class ROCKETMQCLIENT_API DefaultMQPullConsumer : public MQPullConsumer, +// public MQClientImpl, +// public DefaultMQPullConsumerConfig { +// public: +// DefaultMQPullConsumer(const std::string& groupname); +// DefaultMQPullConsumer(const std::string& groupname, RPCHookPtr rpcHook); +// virtual ~DefaultMQPullConsumer(); + +// public: // MQClient +// void start() override; +// void shutdown() override; + +// public: // MQConsumer +// bool sendMessageBack(MQMessageExt& msg, int delayLevel) override; +// void fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) override; + +// std::string groupName() const override; +// MessageModel messageModel() const override; +// ConsumeType consumeType() const override; +// ConsumeFromWhere consumeFromWhere() const override; +// std::vector subscriptions() const override; + +// void doRebalance() override; +// void persistConsumerOffset() override; +// void updateTopicSubscribeInfo(const std::string& topic, std::vector& info) override; +// ConsumerRunningInfo* consumerRunningInfo() override { return nullptr; } + +// public: // MQPullConsumer +// void pull(const MQMessageQueue& mq, +// const std::string& subExpression, +// int64_t offset, +// int maxNums, +// PullCallback* pullCallback) override; + +// /** +// * pull msg 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 +// * accroding to PullResult +// */ +// PullResult pull(const MQMessageQueue& mq, const std::string& subExpression, int64_t offset, int maxNums) override; + +// virtual void updateConsumeOffset(const MQMessageQueue& mq, int64_t offset); +// virtual void removeConsumeOffset(const MQMessageQueue& mq); + +// void registerMessageQueueListener(const std::string& topic, MQueueListener* pListener); + +// /** +// * 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_t offset, +// int maxNums); + +// void pullBlockIfNotFound(const MQMessageQueue& mq, +// const std::string& subExpression, +// int64_t offset, +// int maxNums, +// PullCallback* pullCallback); + +// /** +// * Fetch the offset +// * +// * @param mq +// * @param fromStore +// * @return +// */ +// int64_t fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore); + +// /** +// * Fetch the message queues according to the topic +// * +// * @param topic Message Topic +// * @return +// */ +// void fetchMessageQueuesInBalance(const std::string& topic, std::vector& mqs); + +// // temp persist consumer offset interface, only valid with +// // RemoteBrokerOffsetStore, updateConsumeOffset should be called before. +// void persistConsumerOffset4PullConsumer(const MQMessageQueue& mq); + +// public: +// OffsetStore* getOffsetStore() const { return m_offsetStore.get(); } + +// private: +// void checkConfig(); +// void copySubscription(); + +// PullResult pullSyncImpl(const MQMessageQueue& mq, +// const std::string& subExpression, +// int64_t offset, +// int maxNums, +// bool block); + +// void pullAsyncImpl(const MQMessageQueue& mq, +// const std::string& subExpression, +// int64_t offset, +// int maxNums, +// bool block, +// PullCallback* pPullCallback); + +// void subscriptionAutomatically(const std::string& topic); + +// private: +// std::set m_registerTopics; + +// std::unique_ptr m_rebalanceImpl; +// std::unique_ptr m_pullAPIWrapper; +// std::unique_ptr m_offsetStore; +// MQueueListener* m_messageQueueListener; +// }; + +// } // namespace rocketmq + +// #endif // __DEFAULT_MQ_PULL_CONSUMER_IMPL_H__ diff --git a/src/consumer/DefaultMQPushConsumer.cpp b/src/consumer/DefaultMQPushConsumer.cpp index 8e2541ea7..4116b4175 100644 --- a/src/consumer/DefaultMQPushConsumer.cpp +++ b/src/consumer/DefaultMQPushConsumer.cpp @@ -14,1023 +14,87 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "DefaultMQPushConsumer.h" -#include "CommunicationMode.h" -#include "ConsumeMsgService.h" -#include "ConsumerRunningInfo.h" -#include "FilterAPI.h" -#include "Logging.h" -#include "MQClientAPIImpl.h" -#include "MQClientFactory.h" -#include "NameSpaceUtil.h" -#include "OffsetStore.h" -#include "PullAPIWrapper.h" -#include "PullSysFlag.h" -#include "Rebalance.h" + +#include "AllocateMQAveragely.h" +#include "DefaultMQPushConsumerImpl.h" #include "UtilAll.h" -#include "Validators.h" -#include "task_queue.h" namespace rocketmq { -class AsyncPullCallback : public PullCallback { - public: - AsyncPullCallback(DefaultMQPushConsumer* pushConsumer, boost::weak_ptr request) - : m_callbackOwner(pushConsumer), m_pullRequest(request), m_bShutdown(false) {} - - virtual ~AsyncPullCallback() { m_callbackOwner = NULL; } - - virtual void onSuccess(MQMessageQueue& mq, PullResult& result, bool bProducePullRequest) { - boost::shared_ptr pullRequest = m_pullRequest.lock(); - if (!pullRequest) { - LOG_WARN("Pull request for[%s] has been released", mq.toString().c_str()); - return; - } - - if (m_bShutdown) { - LOG_INFO("pullrequest for:%s in shutdown, return", (pullRequest->m_messageQueue).toString().c_str()); - return; - } - if (pullRequest->isDropped()) { - LOG_INFO("Pull request for queue[%s] has been set as dropped. Will NOT pull this queue any more", - pullRequest->m_messageQueue.toString().c_str()); - return; - } - switch (result.pullStatus) { - case FOUND: { - if (pullRequest->isDropped()) { - LOG_INFO("[Dropped]Remove pullmsg event of mq:%s", (pullRequest->m_messageQueue).toString().c_str()); - break; - } - pullRequest->setNextOffset(result.nextBeginOffset); - pullRequest->putMessage(result.msgFoundList); - - m_callbackOwner->getConsumerMsgService()->submitConsumeRequest(pullRequest, result.msgFoundList); - - if (bProducePullRequest) { - m_callbackOwner->producePullMsgTask(pullRequest); - } else { - LOG_INFO("[bProducePullRequest = false]Stop pullmsg event of mq:%s", - (pullRequest->m_messageQueue).toString().c_str()); - } - - LOG_DEBUG("FOUND:%s with size:" SIZET_FMT ", nextBeginOffset:%lld", - (pullRequest->m_messageQueue).toString().c_str(), result.msgFoundList.size(), result.nextBeginOffset); - - break; - } - case NO_NEW_MSG: { - if (pullRequest->isDropped()) { - LOG_INFO("[Dropped]Remove pullmsg event of mq:%s", (pullRequest->m_messageQueue).toString().c_str()); - break; - } - pullRequest->setNextOffset(result.nextBeginOffset); - - vector msgs; - pullRequest->getMessage(msgs); - if ((msgs.size() == 0) && (result.nextBeginOffset > 0)) { - m_callbackOwner->updateConsumeOffset(pullRequest->m_messageQueue, result.nextBeginOffset); - } - if (bProducePullRequest) { - m_callbackOwner->producePullMsgTask(pullRequest); - } else { - LOG_INFO("[bProducePullRequest = false]Stop pullmsg event of mq:%s", - (pullRequest->m_messageQueue).toString().c_str()); - } - LOG_DEBUG("NO_NEW_MSG:%s,nextBeginOffset:%lld", pullRequest->m_messageQueue.toString().c_str(), - result.nextBeginOffset); - break; - } - case NO_MATCHED_MSG: { - if (pullRequest->isDropped()) { - LOG_INFO("[Dropped]Remove pullmsg event of mq:%s", (pullRequest->m_messageQueue).toString().c_str()); - break; - } - pullRequest->setNextOffset(result.nextBeginOffset); - - vector msgs; - pullRequest->getMessage(msgs); - if ((msgs.size() == 0) && (result.nextBeginOffset > 0)) { - m_callbackOwner->updateConsumeOffset(pullRequest->m_messageQueue, result.nextBeginOffset); - } - if (bProducePullRequest) { - m_callbackOwner->producePullMsgTask(pullRequest); - } else { - LOG_INFO("[bProducePullRequest = false]Stop pullmsg event of mq:%s", - (pullRequest->m_messageQueue).toString().c_str()); - } - LOG_DEBUG("NO_MATCHED_MSG:%s,nextBeginOffset:%lld", pullRequest->m_messageQueue.toString().c_str(), - result.nextBeginOffset); - break; - } - case OFFSET_ILLEGAL: { - if (pullRequest->isDropped()) { - LOG_INFO("[Dropped]Remove pullmsg event of mq:%s", (pullRequest->m_messageQueue).toString().c_str()); - break; - } - pullRequest->setNextOffset(result.nextBeginOffset); - if (bProducePullRequest) { - m_callbackOwner->producePullMsgTask(pullRequest); - } else { - LOG_INFO("[bProducePullRequest = false]Stop pullmsg event of mq:%s", - (pullRequest->m_messageQueue).toString().c_str()); - } - - LOG_DEBUG("OFFSET_ILLEGAL:%s,nextBeginOffset:%lld", pullRequest->m_messageQueue.toString().c_str(), - result.nextBeginOffset); - break; - } - case BROKER_TIMEOUT: { - if (pullRequest->isDropped()) { - LOG_INFO("[Dropped]Remove pullmsg event of mq:%s", (pullRequest->m_messageQueue).toString().c_str()); - break; - } - LOG_ERROR("impossible BROKER_TIMEOUT Occurs"); - pullRequest->setNextOffset(result.nextBeginOffset); - if (bProducePullRequest) { - m_callbackOwner->producePullMsgTask(pullRequest); - } else { - LOG_INFO("[bProducePullRequest = false]Stop pullmsg event of mq:%s", - (pullRequest->m_messageQueue).toString().c_str()); - } - break; - } - } - } - - virtual void onException(MQException& e) { - boost::shared_ptr pullRequest = m_pullRequest.lock(); - if (!pullRequest) { - LOG_WARN("Pull request has been released."); - return; - } - std::string queueName = pullRequest->m_messageQueue.toString(); - if (m_bShutdown) { - LOG_INFO("pullrequest for:%s in shutdown, return", queueName.c_str()); - return; - } - if (pullRequest->isDropped()) { - LOG_INFO("[Dropped]Remove pullmsg event of mq:%s", queueName.c_str()); - return; - } - LOG_WARN("Pullrequest for:%s occurs exception, reproduce it after 1s.", queueName.c_str()); - m_callbackOwner->producePullMsgTaskLater(pullRequest, 1000); - } - - void setShutdownStatus() { m_bShutdown = true; } - - const boost::weak_ptr& getPullRequest() const { return m_pullRequest; } - - void setPullRequest(boost::weak_ptr& pullRequest) { m_pullRequest = pullRequest; } - - private: - DefaultMQPushConsumer* m_callbackOwner; - boost::weak_ptr m_pullRequest; - bool m_bShutdown; -}; - -//second); - } - m_PullCallback.clear(); - m_subTopics.clear(); -} - -bool DefaultMQPushConsumer::sendMessageBack(MQMessageExt& msg, int delayLevel, string& brokerName) { - string brokerAddr; - if (!brokerName.empty()) - brokerAddr = getFactory()->findBrokerAddressInPublish(brokerName); - else - brokerAddr = socketAddress2IPPort(msg.getStoreHost()); - try { - getFactory()->getMQClientAPIImpl()->consumerSendMessageBack(brokerAddr, msg, getGroupName(), delayLevel, - getMaxReconsumeTimes(), 3000, getSessionCredentials()); - } catch (MQException& e) { - LOG_ERROR(e.what()); - return false; - } - return true; -} - -void DefaultMQPushConsumer::fetchSubscribeMessageQueues(const string& topic, vector& mqs) { - mqs.clear(); - try { - getFactory()->fetchSubscribeMessageQueues(topic, mqs, getSessionCredentials()); - } catch (MQException& e) { - LOG_ERROR(e.what()); - } -} - -void DefaultMQPushConsumer::doRebalance() { - if (isServiceStateOk()) { - try { - m_pRebalance->doRebalance(); - } catch (MQException& e) { - LOG_ERROR(e.what()); - } + m_asyncPullTimeout(30 * 1000), + m_maxReconsumeTimes(-1), + m_allocateMQStrategy(new AllocateMQAveragely()) {} + +DefaultMQPushConsumer::DefaultMQPushConsumer(const std::string& groupname) + : DefaultMQPushConsumer(groupname, nullptr) {} + +DefaultMQPushConsumer::DefaultMQPushConsumer(const std::string& groupname, std::shared_ptr rpcHook) + : m_pushConsumerDelegate(nullptr) { + // set default group name + if (groupname.empty()) { + setGroupName(DEFAULT_CONSUMER_GROUP); + } else { + setGroupName(groupname); } -} -void DefaultMQPushConsumer::persistConsumerOffset() { - if (isServiceStateOk()) { - m_pRebalance->persistConsumerOffset(); - } + m_pushConsumerDelegate = DefaultMQPushConsumerImpl::create(this, rpcHook); } -void DefaultMQPushConsumer::persistConsumerOffsetByResetOffset() { - if (isServiceStateOk()) { - m_pRebalance->persistConsumerOffsetByResetOffset(); - } -} +DefaultMQPushConsumer::~DefaultMQPushConsumer() = default; void DefaultMQPushConsumer::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 - // deal with name space before start - dealWithNameSpace(); - switch (m_serviceState) { - case CREATE_JUST: { - m_serviceState = START_FAILED; - MQClient::start(); - LOG_INFO("DefaultMQPushConsumer:%s start", m_GroupName.c_str()); - - //getMessageListenerType() == messageListenerOrderly) { - LOG_INFO("start orderly consume service:%s", getGroupName().c_str()); - m_consumerService = new ConsumeMessageOrderlyService(this, m_consumeThreadCount, m_pMessageListener); - } else // for backward compatible, defaultly and concurrently listeners - // are allocating ConsumeMessageConcurrentlyService - { - LOG_INFO("start concurrently consume service:%s", getGroupName().c_str()); - m_consumerService = new ConsumeMessageConcurrentlyService(this, m_consumeThreadCount, m_pMessageListener); - } - } - - m_pullmsgQueue = new TaskQueue(m_pullMsgThreadPoolNum); - m_pullmsgThread.reset( - new boost::thread(boost::bind(&DefaultMQPushConsumer::runPullMsgQueue, this, m_pullmsgQueue))); - - copySubscription(); - - //registerConsumer(this); - if (!registerOK) { - m_serviceState = CREATE_JUST; - THROW_MQEXCEPTION( - MQClientException, - "The cousumer group[" + getGroupName() + "] has been created before, specify another name please.", -1); - } - - //load(); - } catch (MQClientException& e) { - bStartFailed = true; - errorMsg = std::string(e.what()); - } - m_consumerService->start(); - - getFactory()->start(); - - updateTopicSubscribeInfoWhenSubscriptionChanged(); - getFactory()->sendHeartbeatToAllBroker(); - - m_serviceState = RUNNING; - if (bStartFailed) { - shutdown(); - THROW_MQEXCEPTION(MQClientException, errorMsg, -1); - } - break; - } - case RUNNING: - case START_FAILED: - case SHUTDOWN_ALREADY: - break; - default: - break; - } - - getFactory()->rebalanceImmediately(); + m_pushConsumerDelegate->start(); } void DefaultMQPushConsumer::shutdown() { - switch (m_serviceState) { - case RUNNING: { - LOG_INFO("DefaultMQPushConsumer shutdown"); - m_async_ioService.stop(); - m_async_service_thread->interrupt(); - m_async_service_thread->join(); - m_pullmsgQueue->close(); - m_pullmsgThread->interrupt(); - m_pullmsgThread->join(); - m_consumerService->shutdown(); - persistConsumerOffset(); - shutdownAsyncPullCallBack(); // delete aync pullMsg resources - getFactory()->unregisterConsumer(this); - getFactory()->shutdown(); - m_serviceState = SHUTDOWN_ALREADY; - break; - } - case CREATE_JUST: - case SHUTDOWN_ALREADY: - break; - default: - break; - } -} - -void DefaultMQPushConsumer::registerMessageListener(MQMessageListener* pMessageListener) { - if (NULL != pMessageListener) { - m_pMessageListener = pMessageListener; - } -} - -MessageListenerType DefaultMQPushConsumer::getMessageListenerType() { - if (NULL != m_pMessageListener) { - return m_pMessageListener->getMessageListenerType(); - } - return messageListenerDefaultly; -} - -ConsumeMsgService* DefaultMQPushConsumer::getConsumerMsgService() const { - return m_consumerService; -} - -OffsetStore* DefaultMQPushConsumer::getOffsetStore() const { - return m_pOffsetStore; -} - -Rebalance* DefaultMQPushConsumer::getRebalance() const { - return m_pRebalance; -} - -void DefaultMQPushConsumer::subscribe(const string& topic, const string& subExpression) { - m_subTopics[topic] = subExpression; -} - -void DefaultMQPushConsumer::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); - } - - if (m_pMessageListener == NULL) { - THROW_MQEXCEPTION(MQClientException, "messageListener is null ", -1); - } -} - -void DefaultMQPushConsumer::copySubscription() { - map::iterator it = m_subTopics.begin(); - for (; it != m_subTopics.end(); ++it) { - LOG_INFO("buildSubscriptionData,:%s,%s", it->first.c_str(), it->second.c_str()); - unique_ptr pSData(FilterAPI::buildSubscriptionData(it->first, it->second)); - - m_pRebalance->setSubscriptionData(it->first, pSData.release()); - } - - switch (getMessageModel()) { - case BROADCASTING: - break; - case CLUSTERING: { - string retryTopic = UtilAll::getRetryTopic(getGroupName()); - - // pSData(FilterAPI::buildSubscriptionData(retryTopic, SUB_ALL)); - - m_pRebalance->setSubscriptionData(retryTopic, pSData.release()); - break; - } - default: - break; - } -} - -void DefaultMQPushConsumer::updateTopicSubscribeInfo(const string& topic, vector& info) { - m_pRebalance->setTopicSubscribeInfo(topic, info); -} - -void DefaultMQPushConsumer::updateTopicSubscribeInfoWhenSubscriptionChanged() { - map& subTable = m_pRebalance->getSubscriptionInner(); - map::iterator it = subTable.begin(); - for (; it != subTable.end(); ++it) { - bool btopic = getFactory()->updateTopicRouteInfoFromNameServer(it->first, getSessionCredentials()); - if (btopic == false) { - LOG_WARN("The topic:[%s] not exist", it->first.c_str()); - } - } -} - -ConsumeType DefaultMQPushConsumer::getConsumeType() { - return CONSUME_PASSIVELY; -} - -ConsumeFromWhere DefaultMQPushConsumer::getConsumeFromWhere() { - return m_consumeFromWhere; + m_pushConsumerDelegate->shutdown(); } -void DefaultMQPushConsumer::setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) { - m_consumeFromWhere = consumeFromWhere; +bool DefaultMQPushConsumer::sendMessageBack(MQMessageExt& msg, int delayLevel) { + return m_pushConsumerDelegate->sendMessageBack(msg, delayLevel); } -void DefaultMQPushConsumer::getSubscriptions(vector& result) { - map& subTable = m_pRebalance->getSubscriptionInner(); - map::iterator it = subTable.begin(); - for (; it != subTable.end(); ++it) { - result.push_back(*(it->second)); - } +bool DefaultMQPushConsumer::sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) { + return m_pushConsumerDelegate->sendMessageBack(msg, delayLevel, brokerName); } -void DefaultMQPushConsumer::updateConsumeOffset(const MQMessageQueue& mq, int64 offset) { - if (offset >= 0) { - m_pOffsetStore->updateOffset(mq, offset); - } else { - LOG_ERROR("updateConsumeOffset of mq:%s error", mq.toString().c_str()); - } +void DefaultMQPushConsumer::fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) { + m_pushConsumerDelegate->fetchSubscribeMessageQueues(topic, mqs); } -void DefaultMQPushConsumer::removeConsumeOffset(const MQMessageQueue& mq) { - m_pOffsetStore->removeOffset(mq); +void DefaultMQPushConsumer::registerMessageListener(MQMessageListener* messageListener) { + m_pushConsumerDelegate->registerMessageListener(messageListener); } -void DefaultMQPushConsumer::static_triggerNextPullRequest(void* context, - boost::asio::deadline_timer* t, - boost::weak_ptr pullRequest) { - if (pullRequest.expired()) { - LOG_WARN("Pull request has been released before."); - return; - } - DefaultMQPushConsumer* pDefaultMQPushConsumer = (DefaultMQPushConsumer*)context; - if (pDefaultMQPushConsumer) { - pDefaultMQPushConsumer->triggerNextPullRequest(t, pullRequest); - } +void DefaultMQPushConsumer::registerMessageListener(MessageListenerConcurrently* messageListener) { + m_pushConsumerDelegate->registerMessageListener(messageListener); } -void DefaultMQPushConsumer::triggerNextPullRequest(boost::asio::deadline_timer* t, - boost::weak_ptr pullRequest) { - // delete first to avoild memleak - deleteAndZero(t); - boost::shared_ptr request = pullRequest.lock(); - if (!request) { - LOG_WARN("Pull request has been released before."); - return; - } - producePullMsgTask(request); +void DefaultMQPushConsumer::registerMessageListener(MessageListenerOrderly* messageListener) { + m_pushConsumerDelegate->registerMessageListener(messageListener); } -bool DefaultMQPushConsumer::producePullMsgTaskLater(boost::weak_ptr pullRequest, int millis) { - boost::shared_ptr request = pullRequest.lock(); - if (!request) { - LOG_INFO("Pull request is invalid. Maybe it is dropped before."); - return false; - } - if (request->isDropped()) { - LOG_INFO("[Dropped]Remove pullmsg event of mq:%s", request->m_messageQueue.toString().c_str()); - return false; - } - boost::asio::deadline_timer* t = - new boost::asio::deadline_timer(m_async_ioService, boost::posix_time::milliseconds(millis)); - t->async_wait(boost::bind(&(DefaultMQPushConsumer::static_triggerNextPullRequest), this, t, request)); - LOG_INFO("Produce Pull request [%s] Later and Sleep [%d]ms.", (request->m_messageQueue).toString().c_str(), millis); - return true; +void DefaultMQPushConsumer::subscribe(const std::string& topic, const std::string& subExpression) { + m_pushConsumerDelegate->subscribe(topic, subExpression); } -bool DefaultMQPushConsumer::producePullMsgTask(boost::weak_ptr pullRequest) { - boost::shared_ptr request = pullRequest.lock(); - if (!request) { - LOG_WARN("Pull request has been released."); - return false; - } - if (request->isDropped()) { - LOG_INFO("[Dropped]Remove pullmsg event of mq:%s", request->m_messageQueue.toString().c_str()); - return false; - } - if (m_pullmsgQueue->bTaskQueueStatusOK() && isServiceStateOk()) { - if (m_asyncPull) { - m_pullmsgQueue->produce(TaskBinder::gen(&DefaultMQPushConsumer::pullMessageAsync, this, request)); - } else { - m_pullmsgQueue->produce(TaskBinder::gen(&DefaultMQPushConsumer::pullMessage, this, request)); - } - } else { - LOG_WARN("produce PullRequest of mq:%s failed", request->m_messageQueue.toString().c_str()); - return false; - } - return true; +void DefaultMQPushConsumer::suspend() { + m_pushConsumerDelegate->suspend(); } -void DefaultMQPushConsumer::runPullMsgQueue(TaskQueue* pTaskQueue) { - pTaskQueue->run(); +void DefaultMQPushConsumer::resume() { + m_pushConsumerDelegate->resume(); } -void DefaultMQPushConsumer::pullMessage(boost::weak_ptr pullRequest) { - boost::shared_ptr request = pullRequest.lock(); - if (!request) { - LOG_ERROR("Pull request is released, return"); - return; - } - if (request->isDropped()) { - LOG_WARN("Pull request is set drop with mq:%s, return", (request->m_messageQueue).toString().c_str()); - // request->removePullMsgEvent(); - return; - } - - MQMessageQueue& messageQueue = request->m_messageQueue; - if (m_consumerService->getConsumeMsgSerivceListenerType() == messageListenerOrderly) { - if (!request->isLocked() || request->isLockExpired()) { - if (!m_pRebalance->lock(messageQueue)) { - request->setLastPullTimestamp(UtilAll::currentTimeMillis()); - producePullMsgTaskLater(request, 1000); - return; - } - } - } - - if (request->getCacheMsgCount() > m_maxMsgCacheSize) { - LOG_INFO("Sync Pull request for %s has Cached with %d Messages and The Max size is %d, Sleep 1s.", - (request->m_messageQueue).toString().c_str(), request->getCacheMsgCount(), m_maxMsgCacheSize); - request->setLastPullTimestamp(UtilAll::currentTimeMillis()); - // Retry 1s, - producePullMsgTaskLater(request, 1000); - return; - } - - bool commitOffsetEnable = false; - int64 commitOffsetValue = 0; - if (CLUSTERING == getMessageModel()) { - commitOffsetValue = m_pOffsetStore->readOffset(messageQueue, READ_FROM_MEMORY, getSessionCredentials()); - if (commitOffsetValue > 0) { - commitOffsetEnable = true; - } - } - - string subExpression; - SubscriptionData* pSdata = m_pRebalance->getSubscriptionData(messageQueue.getTopic()); - if (pSdata == NULL) { - LOG_INFO("Can not get SubscriptionData of Pull request for [%s], Sleep 1s.", - (request->m_messageQueue).toString().c_str()); - producePullMsgTaskLater(request, 1000); - return; - } - subExpression = pSdata->getSubString(); - - int sysFlag = PullSysFlag::buildSysFlag(commitOffsetEnable, // commitOffset - false, // suspend - !subExpression.empty(), // subscription - false); // class filter - if (request->isDropped()) { - LOG_WARN("Pull request is set as dropped with mq:%s, return", (request->m_messageQueue).toString().c_str()); - return; - } - try { - request->setLastPullTimestamp(UtilAll::currentTimeMillis()); - unique_ptr result(m_pPullAPIWrapper->pullKernelImpl(messageQueue, // 1 - subExpression, // 2 - pSdata->getSubVersion(), // 3 - request->getNextOffset(), // 4 - 32, // 5 - sysFlag, // 6 - commitOffsetValue, // 7 - 1000 * 15, // 8 - 1000 * 30, // 9 - ComMode_SYNC, // 10 - NULL, getSessionCredentials())); - - PullResult pullResult = m_pPullAPIWrapper->processPullResult(messageQueue, result.get(), pSdata); - switch (pullResult.pullStatus) { - case FOUND: { - if (request->isDropped()) { - LOG_INFO("Get pull result but the queue has been marked as dropped. Queue: %s", - messageQueue.toString().c_str()); - break; - } - // and this request is dropped, and then received pulled msgs. - request->setNextOffset(pullResult.nextBeginOffset); - request->putMessage(pullResult.msgFoundList); - - m_consumerService->submitConsumeRequest(request, pullResult.msgFoundList); - producePullMsgTask(request); - - LOG_DEBUG("FOUND:%s with size:" SIZET_FMT ",nextBeginOffset:%lld", messageQueue.toString().c_str(), - pullResult.msgFoundList.size(), pullResult.nextBeginOffset); - - break; - } - case NO_NEW_MSG: { - if (request->isDropped()) { - LOG_INFO("Get pull result but the queue has been marked as dropped. Queue: %s", - messageQueue.toString().c_str()); - break; - } - request->setNextOffset(pullResult.nextBeginOffset); - vector msgs; - request->getMessage(msgs); - if ((msgs.size() == 0) && (pullResult.nextBeginOffset > 0)) { - updateConsumeOffset(messageQueue, pullResult.nextBeginOffset); - } - producePullMsgTask(request); - LOG_DEBUG("NO_NEW_MSG:%s,nextBeginOffset:%lld", messageQueue.toString().c_str(), pullResult.nextBeginOffset); - break; - } - case NO_MATCHED_MSG: { - if (request->isDropped()) { - LOG_INFO("Get pull result but the queue has been marked as dropped. Queue: %s", - messageQueue.toString().c_str()); - break; - } - request->setNextOffset(pullResult.nextBeginOffset); - vector msgs; - request->getMessage(msgs); - if ((msgs.size() == 0) && (pullResult.nextBeginOffset > 0)) { - updateConsumeOffset(messageQueue, pullResult.nextBeginOffset); - } - producePullMsgTask(request); - - LOG_DEBUG("NO_MATCHED_MSG:%s,nextBeginOffset:%lld", messageQueue.toString().c_str(), - pullResult.nextBeginOffset); - break; - } - case OFFSET_ILLEGAL: { - if (request->isDropped()) { - LOG_INFO("Get pull result but the queue has been marked as dropped. Queue: %s", - messageQueue.toString().c_str()); - break; - } - request->setNextOffset(pullResult.nextBeginOffset); - producePullMsgTask(request); - - LOG_DEBUG("OFFSET_ILLEGAL:%s,nextBeginOffset:%lld", messageQueue.toString().c_str(), - pullResult.nextBeginOffset); - break; - } - case BROKER_TIMEOUT: { // as BROKER_TIMEOUT is defined by client, broker - // will not returns this status, so this case - // could not be entered. - LOG_ERROR("impossible BROKER_TIMEOUT Occurs"); - request->setNextOffset(pullResult.nextBeginOffset); - producePullMsgTask(request); - break; - } - } - } catch (MQException& e) { - LOG_ERROR(e.what()); - LOG_WARN("Pull %s occur exception, restart 1s later.", messageQueue.toString().c_str()); - producePullMsgTaskLater(request, 1000); - } -} - -AsyncPullCallback* DefaultMQPushConsumer::getAsyncPullCallBack(boost::weak_ptr pullRequest, - MQMessageQueue msgQueue) { - boost::shared_ptr request = pullRequest.lock(); - if (!request) { - return NULL; - } - boost::lock_guard lock(m_asyncCallbackLock); - if (m_asyncPull && request) { - PullMAP::iterator it = m_PullCallback.find(msgQueue); - if (it == m_PullCallback.end()) { - LOG_INFO("new pull callback for mq:%s", msgQueue.toString().c_str()); - m_PullCallback[msgQueue] = new AsyncPullCallback(this, request); - } - AsyncPullCallback* asyncPullCallback = m_PullCallback[msgQueue]; - if (asyncPullCallback && asyncPullCallback->getPullRequest().expired()) { - asyncPullCallback->setPullRequest(pullRequest); - } - return asyncPullCallback; - } - - return NULL; +void DefaultMQPushConsumer::setRPCHook(std::shared_ptr rpcHook) { + dynamic_cast(m_pushConsumerDelegate.get())->setRPCHook(rpcHook); } -void DefaultMQPushConsumer::shutdownAsyncPullCallBack() { - boost::lock_guard lock(m_asyncCallbackLock); - if (m_asyncPull) { - PullMAP::iterator it = m_PullCallback.begin(); - for (; it != m_PullCallback.end(); ++it) { - if (it->second) { - it->second->setShutdownStatus(); - } else { - LOG_ERROR("could not find asyncPullCallback for:%s", it->first.toString().c_str()); - } - } - } -} - -void DefaultMQPushConsumer::pullMessageAsync(boost::weak_ptr pullRequest) { - boost::shared_ptr request = pullRequest.lock(); - if (!request) { - LOG_ERROR("Pull request is released, return"); - return; - } - if (request->isDropped()) { - LOG_WARN("Pull request is set drop with mq:%s, return", (request->m_messageQueue).toString().c_str()); - return; - } - MQMessageQueue& messageQueue = request->m_messageQueue; - if (m_consumerService->getConsumeMsgSerivceListenerType() == messageListenerOrderly) { - if (!request->isLocked() || request->isLockExpired()) { - if (!m_pRebalance->lock(messageQueue)) { - request->setLastPullTimestamp(UtilAll::currentTimeMillis()); - // Retry later. - producePullMsgTaskLater(request, 1000); - return; - } - } - } - - if (request->getCacheMsgCount() > m_maxMsgCacheSize) { - LOG_INFO("Pull request for [%s] has Cached with %d Messages and The Max size is %d, Sleep 3s.", - (request->m_messageQueue).toString().c_str(), request->getCacheMsgCount(), m_maxMsgCacheSize); - request->setLastPullTimestamp(UtilAll::currentTimeMillis()); - // Retry 3s, - producePullMsgTaskLater(request, 3000); - return; - } - - bool commitOffsetEnable = false; - int64 commitOffsetValue = 0; - if (CLUSTERING == getMessageModel()) { - commitOffsetValue = m_pOffsetStore->readOffset(messageQueue, READ_FROM_MEMORY, getSessionCredentials()); - if (commitOffsetValue > 0) { - commitOffsetEnable = true; - } - } - - string subExpression; - SubscriptionData* pSdata = (m_pRebalance->getSubscriptionData(messageQueue.getTopic())); - if (pSdata == NULL) { - LOG_INFO("Can not get SubscriptionData of Pull request for [%s], Sleep 1s.", - (request->m_messageQueue).toString().c_str()); - // Subscribe data error, retry later. - producePullMsgTaskLater(request, 1000); - return; - } - subExpression = pSdata->getSubString(); - - int sysFlag = PullSysFlag::buildSysFlag(commitOffsetEnable, // commitOffset - true, // suspend - !subExpression.empty(), // subscription - false); // class filter - - AsyncArg arg; - arg.mq = messageQueue; - arg.subData = *pSdata; - arg.pPullWrapper = m_pPullAPIWrapper; - if (request->isDropped()) { - LOG_WARN("Pull request is set as dropped with mq:%s, return", request->m_messageQueue.toString().c_str()); - return; - } - try { - request->setLastPullTimestamp(UtilAll::currentTimeMillis()); - AsyncPullCallback* pullCallback = getAsyncPullCallBack(request, messageQueue); - if (pullCallback == NULL) { - LOG_WARN("Can not get pull callback for:%s, Maybe this pull request has been released.", - request->m_messageQueue.toString().c_str()); - return; - } - m_pPullAPIWrapper->pullKernelImpl(messageQueue, // 1 - subExpression, // 2 - pSdata->getSubVersion(), // 3 - request->getNextOffset(), // 4 - 32, // 5 - sysFlag, // 6 - commitOffsetValue, // 7 - 1000 * 15, // 8 - m_asyncPullTimeout, // 9 - ComMode_ASYNC, // 10 - pullCallback, // 11 - getSessionCredentials(), // 12 - &arg); // 13 - } catch (MQException& e) { - LOG_ERROR(e.what()); - if (request->isDropped()) { - LOG_WARN("Pull request is set as dropped with mq:%s, return", (request->m_messageQueue).toString().c_str()); - return; - } - LOG_INFO("Pull %s occur exception, restart 1s later.", (request->m_messageQueue).toString().c_str()); - producePullMsgTaskLater(request, 1000); - } -} - -void DefaultMQPushConsumer::setAsyncPull(bool asyncFlag) { - if (asyncFlag) { - LOG_INFO("set pushConsumer:%s to async default pull mode", getGroupName().c_str()); - } else { - LOG_INFO("set pushConsumer:%s to sync pull mode", getGroupName().c_str()); - } - m_asyncPull = asyncFlag; -} - -void DefaultMQPushConsumer::setConsumeThreadCount(int threadCount) { - if (threadCount > 0) { - m_consumeThreadCount = threadCount; - } else { - LOG_ERROR("setConsumeThreadCount with invalid value"); - } -} - -int DefaultMQPushConsumer::getConsumeThreadCount() const { - return m_consumeThreadCount; -} -void DefaultMQPushConsumer::setMaxReconsumeTimes(int maxReconsumeTimes) { - if (maxReconsumeTimes > 0) { - m_maxReconsumeTimes = maxReconsumeTimes; - } else { - LOG_ERROR("set maxReconsumeTimes with invalid value"); - } -} - -int DefaultMQPushConsumer::getMaxReconsumeTimes() const { - if (m_maxReconsumeTimes >= 0) { - return m_maxReconsumeTimes; - } - // return 16 as default; - return 16; -} - -void DefaultMQPushConsumer::setPullMsgThreadPoolCount(int threadCount) { - m_pullMsgThreadPoolNum = threadCount; -} - -int DefaultMQPushConsumer::getPullMsgThreadPoolCount() const { - return m_pullMsgThreadPoolNum; -} - -int DefaultMQPushConsumer::getConsumeMessageBatchMaxSize() const { - return m_consumeMessageBatchMaxSize; -} - -void DefaultMQPushConsumer::setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) { - if (consumeMessageBatchMaxSize >= 1) - m_consumeMessageBatchMaxSize = consumeMessageBatchMaxSize; -} - -void DefaultMQPushConsumer::setMaxCacheMsgSizePerQueue(int maxCacheSize) { - if (maxCacheSize > 0 && maxCacheSize < 65535) { - LOG_INFO("set maxCacheSize to:%d for consumer:%s", maxCacheSize, getGroupName().c_str()); - m_maxMsgCacheSize = maxCacheSize; - } -} - -int DefaultMQPushConsumer::getMaxCacheMsgSizePerQueue() const { - return m_maxMsgCacheSize; -} - -ConsumerRunningInfo* DefaultMQPushConsumer::getConsumerRunningInfo() { - auto* info = new ConsumerRunningInfo(); - if (m_consumerService->getConsumeMsgSerivceListenerType() == messageListenerOrderly) { - info->setProperty(ConsumerRunningInfo::PROP_CONSUME_ORDERLY, "true"); - } else { - info->setProperty(ConsumerRunningInfo::PROP_CONSUME_ORDERLY, "false"); - } - info->setProperty(ConsumerRunningInfo::PROP_THREADPOOL_CORE_SIZE, UtilAll::to_string(m_consumeThreadCount)); - info->setProperty(ConsumerRunningInfo::PROP_CONSUMER_START_TIMESTAMP, UtilAll::to_string(m_startTime)); - - std::vector result; - getSubscriptions(result); - info->setSubscriptionSet(result); - - std::map> requestTable = m_pRebalance->getPullRequestTable(); - - for (const auto& it : requestTable) { - if (!it.second->isDropped()) { - MessageQueue queue((it.first).getTopic(), (it.first).getBrokerName(), (it.first).getQueueId()); - ProcessQueueInfo processQueue; - processQueue.cachedMsgMinOffset = it.second->getCacheMinOffset(); - processQueue.cachedMsgMaxOffset = it.second->getCacheMaxOffset(); - processQueue.cachedMsgCount = it.second->getCacheMsgCount(); - processQueue.setCommitOffset( - m_pOffsetStore->readOffset(it.first, MEMORY_FIRST_THEN_STORE, getSessionCredentials())); - processQueue.setDroped(it.second->isDropped()); - processQueue.setLocked(it.second->isLocked()); - processQueue.lastLockTimestamp = it.second->getLastLockTimestamp(); - processQueue.lastPullTimestamp = it.second->getLastPullTimestamp(); - processQueue.lastConsumeTimestamp = it.second->getLastConsumeTimestamp(); - info->setMqTable(queue, processQueue); - } - } - - return info; -} -// we should deal with name space before producer start. -bool DefaultMQPushConsumer::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); - } - map subTmp; - map::iterator it = m_subTopics.begin(); - for (; it != m_subTopics.end(); ++it) { - string topic = it->first; - string subs = it->second; - if (!NameSpaceUtil::hasNameSpace(topic, ns)) { - LOG_INFO("Update Subscribe[%s:%s] with NameSpace:%s", it->first.c_str(), it->second.c_str(), ns.c_str()); - topic = NameSpaceUtil::withNameSpace(topic, ns); - // let other mode to known, the name space model opened. - m_useNameSpaceMode = true; - } - subTmp[topic] = subs; - } - m_subTopics.swap(subTmp); - - return true; -} -// +#endif + +#include "AllocateMQAveragely.h" +#include "CommunicationMode.h" +#include "ConsumeMsgService.h" +#include "ConsumerRunningInfo.h" +#include "FilterAPI.h" +#include "Logging.h" +#include "MQAdminImpl.h" +#include "MQClientAPIImpl.h" +#include "MQClientInstance.h" +#include "MQClientManager.h" +#include "MQProtos.h" +#include "OffsetStore.h" +#include "PullAPIWrapper.h" +#include "PullMessageService.h" +#include "PullSysFlag.h" +#include "RebalancePushImpl.h" +#include "SocketUtil.h" +#include "UtilAll.h" +#include "Validators.h" + +namespace rocketmq { + +class AsyncPullCallback : public AutoDeletePullCallback { + public: + AsyncPullCallback(DefaultMQPushConsumerImplPtr pushConsumer, + PullRequestPtr request, + SubscriptionDataPtr subscriptionData) + : m_defaultMQPushConsumer(pushConsumer), m_pullRequest(request), m_subscriptionData(subscriptionData) {} + + ~AsyncPullCallback() override { + m_defaultMQPushConsumer.reset(); + m_pullRequest.reset(); + m_subscriptionData = nullptr; + } + + void onSuccess(PullResult& pullResult) override { + auto defaultMQPushConsumer = m_defaultMQPushConsumer.lock(); + if (nullptr == defaultMQPushConsumer) { + LOG_WARN_NEW("AsyncPullCallback::onSuccess: DefaultMQPushConsumerImpl is released."); + return; + } + + PullResult result = defaultMQPushConsumer->getPullAPIWrapper()->processPullResult(m_pullRequest->getMessageQueue(), + pullResult, m_subscriptionData); + switch (result.pullStatus) { + case FOUND: { + int64_t prevRequestOffset = m_pullRequest->getNextOffset(); + m_pullRequest->setNextOffset(result.nextBeginOffset); + + int64_t firstMsgOffset = (std::numeric_limits::max)(); + if (result.msgFoundList.empty()) { + defaultMQPushConsumer->executePullRequestImmediately(m_pullRequest); + } else { + firstMsgOffset = (*result.msgFoundList.begin())->getQueueOffset(); + + m_pullRequest->getProcessQueue()->putMessage(result.msgFoundList); + defaultMQPushConsumer->getConsumerMsgService()->submitConsumeRequest( + result.msgFoundList, m_pullRequest->getProcessQueue(), m_pullRequest->getMessageQueue(), true); + + defaultMQPushConsumer->executePullRequestImmediately(m_pullRequest); + } + + if (result.nextBeginOffset < prevRequestOffset || firstMsgOffset < prevRequestOffset) { + LOG_WARN_NEW( + "[BUG] pull message result maybe data wrong, nextBeginOffset:{} firstMsgOffset:{} prevRequestOffset:{}", + result.nextBeginOffset, firstMsgOffset, prevRequestOffset); + } + + } break; + case NO_NEW_MSG: + case NO_MATCHED_MSG: + m_pullRequest->setNextOffset(result.nextBeginOffset); + defaultMQPushConsumer->correctTagsOffset(m_pullRequest); + defaultMQPushConsumer->executePullRequestImmediately(m_pullRequest); + break; + case OFFSET_ILLEGAL: { + LOG_WARN_NEW("the pull request offset illegal, {} {}", m_pullRequest->toString(), result.toString()); + + m_pullRequest->setNextOffset(result.nextBeginOffset); + m_pullRequest->getProcessQueue()->setDropped(true); + + // update and persist offset, then removeProcessQueue + auto pullRequest = m_pullRequest; + defaultMQPushConsumer->executeTaskLater( + [defaultMQPushConsumer, pullRequest]() { + try { + defaultMQPushConsumer->getOffsetStore()->updateOffset(pullRequest->getMessageQueue(), + pullRequest->getNextOffset(), false); + defaultMQPushConsumer->getOffsetStore()->persist(pullRequest->getMessageQueue()); + defaultMQPushConsumer->getRebalanceImpl()->removeProcessQueue(pullRequest->getMessageQueue()); + + LOG_WARN_NEW("fix the pull request offset, {}", pullRequest->toString()); + } catch (std::exception& e) { + LOG_ERROR_NEW("executeTaskLater Exception: {}", e.what()); + } + }, + 10000); + } break; + default: + break; + } + } + + void onException(MQException& e) noexcept override { + auto defaultMQPushConsumer = m_defaultMQPushConsumer.lock(); + if (nullptr == defaultMQPushConsumer) { + LOG_WARN_NEW("AsyncPullCallback::onException: DefaultMQPushConsumerImpl is released."); + return; + } + + if (!UtilAll::isRetryTopic(m_pullRequest->getMessageQueue().getTopic())) { + LOG_WARN_NEW("execute the pull request exception: {}", e.what()); + } + + defaultMQPushConsumer->executePullRequestLater(m_pullRequest, 3000); + } + + private: + std::weak_ptr m_defaultMQPushConsumer; + PullRequestPtr m_pullRequest; + SubscriptionDataPtr m_subscriptionData; +}; + +DefaultMQPushConsumerImpl::DefaultMQPushConsumerImpl(DefaultMQPushConsumerConfig* config) + : DefaultMQPushConsumerImpl(config, nullptr) {} + +DefaultMQPushConsumerImpl::DefaultMQPushConsumerImpl(DefaultMQPushConsumerConfig* config, + std::shared_ptr rpcHook) + : MQClientImpl(config, rpcHook), + m_pushConsumerConfig(config), + m_startTime(UtilAll::currentTimeMillis()), + m_pause(false), + m_consumeOrderly(false), + m_rebalanceImpl(new RebalancePushImpl(this)), + m_pullAPIWrapper(nullptr), + m_offsetStore(nullptr), + m_consumeService(nullptr), + m_messageListener(nullptr) {} + +DefaultMQPushConsumerImpl::~DefaultMQPushConsumerImpl() = default; + +int DefaultMQPushConsumerImpl::getMaxReconsumeTimes() { + // default reconsume times: 16 + if (m_pushConsumerConfig->getMaxReconsumeTimes() == -1) { + return 16; + } else { + return m_pushConsumerConfig->getMaxReconsumeTimes(); + } +} + +bool DefaultMQPushConsumerImpl::sendMessageBack(MQMessageExt& msg, int delayLevel) { + return sendMessageBack(msg, delayLevel, null); +} + +bool DefaultMQPushConsumerImpl::sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) { + try { + std::string brokerAddr = brokerName.empty() ? socketAddress2IPPort(&msg.getStoreHost()) + : m_clientInstance->findBrokerAddressInPublish(brokerName); + + m_clientInstance->getMQClientAPIImpl()->consumerSendMessageBack( + brokerAddr, msg, m_pushConsumerConfig->getGroupName(), delayLevel, 5000, getMaxReconsumeTimes()); + return true; + } catch (std::exception& e) { + LOG_ERROR_NEW("sendMessageBack exception, group: {}, msg: {}. {}", m_pushConsumerConfig->getGroupName(), + msg.toString(), e.what()); + } + return false; +} + +void DefaultMQPushConsumerImpl::fetchSubscribeMessageQueues(const std::string& topic, + std::vector& mqs) { + mqs.clear(); + try { + m_clientInstance->getMQAdminImpl()->fetchSubscribeMessageQueues(topic, mqs); + } catch (MQException& e) { + LOG_ERROR_NEW("{}", e.what()); + } +} + +void DefaultMQPushConsumerImpl::doRebalance() { + if (!m_pause) { + m_rebalanceImpl->doRebalance(isConsumeOrderly()); + } +} + +void DefaultMQPushConsumerImpl::persistConsumerOffset() { + if (isServiceStateOk()) { + std::vector mqs = m_rebalanceImpl->getAllocatedMQ(); + if (m_pushConsumerConfig->getMessageModel() == BROADCASTING) { + m_offsetStore->persistAll(mqs); + } else { + for (const auto& mq : mqs) { + m_offsetStore->persist(mq); + } + } + } +} + +void DefaultMQPushConsumerImpl::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 + + switch (m_serviceState) { + case CREATE_JUST: { + LOG_INFO_NEW("the consumer [{}] start beginning.", m_pushConsumerConfig->getGroupName()); + + m_serviceState = START_FAILED; + + // data + checkConfig(); + + copySubscription(); + + if (messageModel() == CLUSTERING) { + m_pushConsumerConfig->changeInstanceNameToPID(); + } + + // ensure m_clientFactory + MQClientImpl::start(); + + // reset rebalance + m_rebalanceImpl->setConsumerGroup(m_pushConsumerConfig->getGroupName()); + m_rebalanceImpl->setMessageModel(m_pushConsumerConfig->getMessageModel()); + m_rebalanceImpl->setAllocateMQStrategy(m_pushConsumerConfig->getAllocateMQStrategy()); + m_rebalanceImpl->setMQClientFactory(m_clientInstance.get()); + + m_pullAPIWrapper.reset(new PullAPIWrapper(m_clientInstance.get(), m_pushConsumerConfig->getGroupName())); + + switch (m_pushConsumerConfig->getMessageModel()) { + case BROADCASTING: + m_offsetStore.reset(new LocalFileOffsetStore(m_clientInstance.get(), m_pushConsumerConfig->getGroupName())); + break; + case CLUSTERING: + m_offsetStore.reset( + new RemoteBrokerOffsetStore(m_clientInstance.get(), m_pushConsumerConfig->getGroupName())); + break; + } + m_offsetStore->load(); + + // checkConfig() guarantee m_pMessageListener is not nullptr + if (m_messageListener->getMessageListenerType() == messageListenerOrderly) { + LOG_INFO_NEW("start orderly consume service: {}", m_pushConsumerConfig->getGroupName()); + m_consumeOrderly = true; + m_consumeService.reset( + new ConsumeMessageOrderlyService(this, m_pushConsumerConfig->getConsumeThreadNum(), m_messageListener)); + } else { + // for backward compatible, defaultly and concurrently listeners are allocating + // ConsumeMessageConcurrentlyService + LOG_INFO_NEW("start concurrently consume service: {}", m_pushConsumerConfig->getGroupName()); + m_consumeOrderly = false; + m_consumeService.reset(new ConsumeMessageConcurrentlyService(this, m_pushConsumerConfig->getConsumeThreadNum(), + m_messageListener)); + } + m_consumeService->start(); + + // register consumer + bool registerOK = m_clientInstance->registerConsumer(m_pushConsumerConfig->getGroupName(), this); + if (!registerOK) { + m_serviceState = CREATE_JUST; + m_consumeService->shutdown(); + THROW_MQEXCEPTION(MQClientException, + "The cousumer group[" + m_pushConsumerConfig->getGroupName() + + "] has been created before, specify another name please.", + -1); + } + + m_clientInstance->start(); + LOG_INFO_NEW("the consumer [{}] start OK", m_pushConsumerConfig->getGroupName()); + m_serviceState = RUNNING; + break; + } + case RUNNING: + case START_FAILED: + case SHUTDOWN_ALREADY: + break; + default: + break; + } + + updateTopicSubscribeInfoWhenSubscriptionChanged(); + m_clientInstance->sendHeartbeatToAllBrokerWithLock(); + m_clientInstance->rebalanceImmediately(); +} + +void DefaultMQPushConsumerImpl::shutdown() { + switch (m_serviceState) { + case RUNNING: { + m_consumeService->shutdown(); + persistConsumerOffset(); + m_clientInstance->unregisterConsumer(m_pushConsumerConfig->getGroupName()); + m_clientInstance->shutdown(); + LOG_INFO_NEW("the consumer [{}] shutdown OK", m_pushConsumerConfig->getGroupName()); + m_rebalanceImpl->destroy(); + m_serviceState = SHUTDOWN_ALREADY; + break; + } + case CREATE_JUST: + case SHUTDOWN_ALREADY: + break; + default: + break; + } +} + +void DefaultMQPushConsumerImpl::registerMessageListener(MQMessageListener* messageListener) { + if (nullptr != messageListener) { + m_messageListener = messageListener; + } +} + +void DefaultMQPushConsumerImpl::registerMessageListener(MessageListenerConcurrently* messageListener) { + registerMessageListener((MQMessageListener*)messageListener); +} + +void DefaultMQPushConsumerImpl::registerMessageListener(MessageListenerOrderly* messageListener) { + registerMessageListener((MQMessageListener*)messageListener); +} + +void DefaultMQPushConsumerImpl::subscribe(const std::string& topic, const std::string& subExpression) { + m_subTopics[topic] = subExpression; +} + +void DefaultMQPushConsumerImpl::checkConfig() { + std::string groupname = m_pushConsumerConfig->getGroupName(); + + // check consumerGroup + Validators::checkGroup(groupname); + + // consumerGroup + if (!groupname.compare(DEFAULT_CONSUMER_GROUP)) { + THROW_MQEXCEPTION(MQClientException, "consumerGroup can not equal DEFAULT_CONSUMER", -1); + } + + if (m_pushConsumerConfig->getMessageModel() != BROADCASTING && + m_pushConsumerConfig->getMessageModel() != CLUSTERING) { + THROW_MQEXCEPTION(MQClientException, "messageModel is valid ", -1); + } + + if (m_messageListener == nullptr) { + THROW_MQEXCEPTION(MQClientException, "messageListener is null ", -1); + } +} + +void DefaultMQPushConsumerImpl::copySubscription() { + for (const auto& it : m_subTopics) { + LOG_INFO_NEW("buildSubscriptionData: {}, {}", it.first, it.second); + SubscriptionDataPtr subscriptionData = FilterAPI::buildSubscriptionData(it.first, it.second); + m_rebalanceImpl->setSubscriptionData(it.first, subscriptionData); + } + + switch (m_pushConsumerConfig->getMessageModel()) { + case BROADCASTING: + break; + case CLUSTERING: { + // auto subscript retry topic + std::string retryTopic = UtilAll::getRetryTopic(m_pushConsumerConfig->getGroupName()); + SubscriptionDataPtr subscriptionData = FilterAPI::buildSubscriptionData(retryTopic, SUB_ALL); + m_rebalanceImpl->setSubscriptionData(retryTopic, subscriptionData); + break; + } + default: + break; + } +} + +void DefaultMQPushConsumerImpl::updateTopicSubscribeInfo(const std::string& topic, std::vector& info) { + m_rebalanceImpl->setTopicSubscribeInfo(topic, info); +} + +void DefaultMQPushConsumerImpl::updateTopicSubscribeInfoWhenSubscriptionChanged() { + auto& subTable = m_rebalanceImpl->getSubscriptionInner(); + for (const auto& sub : subTable) { + bool ret = m_clientInstance->updateTopicRouteInfoFromNameServer(sub.first); + if (!ret) { + LOG_WARN_NEW("The topic:[{}] not exist", sub.first); + } + } +} + +std::string DefaultMQPushConsumerImpl::groupName() const { + return m_pushConsumerConfig->getGroupName(); +} + +MessageModel DefaultMQPushConsumerImpl::messageModel() const { + return m_pushConsumerConfig->getMessageModel(); +}; + +ConsumeType DefaultMQPushConsumerImpl::consumeType() const { + return CONSUME_PASSIVELY; +} + +ConsumeFromWhere DefaultMQPushConsumerImpl::consumeFromWhere() const { + return m_pushConsumerConfig->getConsumeFromWhere(); +} + +std::vector DefaultMQPushConsumerImpl::subscriptions() const { + std::vector result; + auto& subTable = m_rebalanceImpl->getSubscriptionInner(); + for (const auto& it : subTable) { + result.push_back(*(it.second)); + } + return result; +} + +void DefaultMQPushConsumerImpl::suspend() { + m_pause = true; + LOG_INFO_NEW("suspend this consumer, {}", m_pushConsumerConfig->getGroupName()); +} + +void DefaultMQPushConsumerImpl::resume() { + m_pause = false; + doRebalance(); + LOG_INFO_NEW("resume this consumer, {}", m_pushConsumerConfig->getGroupName()); +} + +bool DefaultMQPushConsumerImpl::isPause() { + return m_pause; +} + +void DefaultMQPushConsumerImpl::setPause(bool pause) { + m_pause = pause; +} + +void DefaultMQPushConsumerImpl::updateConsumeOffset(const MQMessageQueue& mq, int64_t offset) { + if (offset >= 0) { + m_offsetStore->updateOffset(mq, offset, false); + } else { + LOG_ERROR_NEW("updateConsumeOffset of mq:{} error", mq.toString()); + } +} + +void DefaultMQPushConsumerImpl::correctTagsOffset(PullRequestPtr pullRequest) { + if (0L == pullRequest->getProcessQueue()->getCacheMsgCount()) { + m_offsetStore->updateOffset(pullRequest->getMessageQueue(), pullRequest->getNextOffset(), true); + } +} + +void DefaultMQPushConsumerImpl::executePullRequestLater(PullRequestPtr pullRequest, long timeDelay) { + m_clientInstance->getPullMessageService()->executePullRequestLater(pullRequest, timeDelay); +} + +void DefaultMQPushConsumerImpl::executePullRequestImmediately(PullRequestPtr pullRequest) { + m_clientInstance->getPullMessageService()->executePullRequestImmediately(pullRequest); +} + +void DefaultMQPushConsumerImpl::executeTaskLater(const handler_type& task, long timeDelay) { + m_clientInstance->getPullMessageService()->executeTaskLater(task, timeDelay); +} + +void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pullRequest) { + if (nullptr == pullRequest) { + LOG_ERROR("PullRequest is NULL, return"); + return; + } + + auto processQueue = pullRequest->getProcessQueue(); + if (processQueue->isDropped()) { + LOG_WARN_NEW("the pull request[{}] is dropped.", pullRequest->toString()); + return; + } + + processQueue->setLastPullTimestamp(UtilAll::currentTimeMillis()); + + int cachedMessageCount = processQueue->getCacheMsgCount(); + if (cachedMessageCount > m_pushConsumerConfig->getMaxCacheMsgSizePerQueue()) { + // too many message in cache, wait to process + executePullRequestLater(pullRequest, 1000); + return; + } + + if (isConsumeOrderly()) { + if (processQueue->isLocked()) { + if (!pullRequest->isLockedFirst()) { + const auto offset = m_rebalanceImpl->computePullFromWhere(pullRequest->getMessageQueue()); + bool brokerBusy = offset < pullRequest->getNextOffset(); + LOG_INFO_NEW( + "the first time to pull message, so fix offset from broker. pullRequest: {} NewOffset: {} brokerBusy: {}", + pullRequest->toString(), offset, UtilAll::to_string(brokerBusy)); + if (brokerBusy) { + LOG_INFO_NEW( + "[NOTIFYME] the first time to pull message, but pull request offset larger than broker consume offset. " + "pullRequest: {} NewOffset: {}", + pullRequest->toString(), offset); + } + + pullRequest->setLockedFirst(true); + pullRequest->setNextOffset(offset); + } + } else { + executePullRequestLater(pullRequest, 3000); + LOG_INFO_NEW("pull message later because not locked in broker, {}", pullRequest->toString()); + return; + } + } + + const auto& messageQueue = pullRequest->getMessageQueue(); + SubscriptionDataPtr subscriptionData = m_rebalanceImpl->getSubscriptionData(messageQueue.getTopic()); + if (nullptr == subscriptionData) { + executePullRequestLater(pullRequest, 3000); + LOG_WARN_NEW("find the consumer's subscription failed, {}", pullRequest->toString()); + return; + } + + bool commitOffsetEnable = false; + int64_t commitOffsetValue = 0; + if (CLUSTERING == m_pushConsumerConfig->getMessageModel()) { + commitOffsetValue = m_offsetStore->readOffset(messageQueue, READ_FROM_MEMORY); + if (commitOffsetValue > 0) { + commitOffsetEnable = true; + } + } + + const auto& subExpression = subscriptionData->getSubString(); + + int sysFlag = PullSysFlag::buildSysFlag(commitOffsetEnable, // commitOffset + true, // suspend + !subExpression.empty(), // subscription + false); // class filter + + try { + auto* callback = new AsyncPullCallback(shared_from_this(), pullRequest, subscriptionData); + m_pullAPIWrapper->pullKernelImpl(messageQueue, // 1 + subExpression, // 2 + subscriptionData->getSubVersion(), // 3 + pullRequest->getNextOffset(), // 4 + 32, // 5 + sysFlag, // 6 + commitOffsetValue, // 7 + 1000 * 15, // 8 + m_pushConsumerConfig->getAsyncPullTimeout(), // 9 + ComMode_ASYNC, // 10 + callback); // 11 + } catch (MQException& e) { + LOG_ERROR_NEW("pullKernelImpl exception: {}", e.what()); + executePullRequestLater(pullRequest, 3000); + } +} + +void DefaultMQPushConsumerImpl::resetRetryTopic(std::vector& msgs, const std::string& consumerGroup) { + std::string groupTopic = UtilAll::getRetryTopic(consumerGroup); + for (auto& msg : msgs) { + std::string retryTopic = msg->getProperty(MQMessageConst::PROPERTY_RETRY_TOPIC); + if (!retryTopic.empty() && groupTopic == msg->getTopic()) { + msg->setTopic(retryTopic); + } + } +} + +ConsumerRunningInfo* DefaultMQPushConsumerImpl::consumerRunningInfo() { + auto* info = new ConsumerRunningInfo(); + + info->setProperty(ConsumerRunningInfo::PROP_CONSUME_ORDERLY, UtilAll::to_string(m_consumeOrderly)); + info->setProperty(ConsumerRunningInfo::PROP_THREADPOOL_CORE_SIZE, + UtilAll::to_string(m_pushConsumerConfig->getConsumeThreadNum())); + info->setProperty(ConsumerRunningInfo::PROP_CONSUMER_START_TIMESTAMP, UtilAll::to_string(m_startTime)); + + auto subSet = subscriptions(); + info->setSubscriptionSet(subSet); + + auto processQueueTable = m_rebalanceImpl->getProcessQueueTable(); + + for (const auto& it : processQueueTable) { + const auto& mq = it.first; + const auto& pq = it.second; + + ProcessQueueInfo pqinfo; + pqinfo.setCommitOffset(m_offsetStore->readOffset(mq, MEMORY_FIRST_THEN_STORE)); + pq->fillProcessQueueInfo(pqinfo); + info->setMqTable(mq, pqinfo); + } + + return info; +} + +} // namespace rocketmq diff --git a/src/consumer/DefaultMQPushConsumerImpl.h b/src/consumer/DefaultMQPushConsumerImpl.h new file mode 100755 index 000000000..bd3a5909e --- /dev/null +++ b/src/consumer/DefaultMQPushConsumerImpl.h @@ -0,0 +1,153 @@ +/* + * 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 __DEFAULT_MQ_PUSH_CONSUMER_IMPL_H__ +#define __DEFAULT_MQ_PUSH_CONSUMER_IMPL_H__ + +#include +#include +#include + +#include "DefaultMQPushConsumer.h" +#include "MQClientImpl.h" +#include "MQConsumerInner.h" +#include "PullRequest.h" +#include "concurrent/executor.hpp" + +namespace rocketmq { + +class RebalanceImpl; +class SubscriptionData; +class OffsetStore; +class PullAPIWrapper; +class ConsumeMsgService; +class AsyncPullCallback; + +class DefaultMQPushConsumerImpl; +typedef std::shared_ptr DefaultMQPushConsumerImplPtr; + +class DefaultMQPushConsumerImpl : public std::enable_shared_from_this, + public MQPushConsumer, + public MQClientImpl, + public MQConsumerInner { + public: + static DefaultMQPushConsumerImplPtr create(DefaultMQPushConsumerConfig* config, RPCHookPtr rpcHook = nullptr) { + if (nullptr == rpcHook) { + return DefaultMQPushConsumerImplPtr(new DefaultMQPushConsumerImpl(config)); + } else { + return DefaultMQPushConsumerImplPtr(new DefaultMQPushConsumerImpl(config, rpcHook)); + } + } + + private: + DefaultMQPushConsumerImpl(DefaultMQPushConsumerConfig* config); + DefaultMQPushConsumerImpl(DefaultMQPushConsumerConfig* config, RPCHookPtr rpcHook); + + public: + virtual ~DefaultMQPushConsumerImpl(); + + public: // MQClient + void start() override; + void shutdown() override; + + public: // MQConsumer + bool sendMessageBack(MQMessageExt& msg, int delayLevel) override; + bool sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) override; + void fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) override; + + public: // MQPushConsumer + void registerMessageListener(MQMessageListener* messageListener) override; + void registerMessageListener(MessageListenerConcurrently* messageListener) override; + void registerMessageListener(MessageListenerOrderly* messageListener) override; + + void subscribe(const std::string& topic, const std::string& subExpression) override; + + void suspend() override; + void resume() override; + + public: // MQConsumerInner + std::string groupName() const override; + MessageModel messageModel() const override; + ConsumeType consumeType() const override; + ConsumeFromWhere consumeFromWhere() const override; + std::vector subscriptions() const override; + + void doRebalance() override; + void persistConsumerOffset() override; + void updateTopicSubscribeInfo(const std::string& topic, std::vector& info) override; + ConsumerRunningInfo* consumerRunningInfo() override; + + public: + bool isPause(); + void setPause(bool pause); + + void updateConsumeOffset(const MQMessageQueue& mq, int64_t offset); + void correctTagsOffset(PullRequestPtr pullRequest); + + void executePullRequestLater(PullRequestPtr pullRequest, long timeDelay); + void executePullRequestImmediately(PullRequestPtr pullRequest); + void executeTaskLater(const handler_type& task, long timeDelay); + + void pullMessage(PullRequestPtr pullrequest); + + void resetRetryTopic(std::vector& msgs, const std::string& consumerGroup); + + public: + bool isConsumeOrderly() { return m_consumeOrderly; } + + RebalanceImpl* getRebalanceImpl() const { return m_rebalanceImpl.get(); } + + PullAPIWrapper* getPullAPIWrapper() const { return m_pullAPIWrapper.get(); } + + OffsetStore* getOffsetStore() const { return m_offsetStore.get(); } + + ConsumeMsgService* getConsumerMsgService() const { return m_consumeService.get(); } + + MessageListenerType getMessageListenerType() const { + if (nullptr != m_messageListener) { + return m_messageListener->getMessageListenerType(); + } + return messageListenerDefaultly; + } + + DefaultMQPushConsumerConfig* getDefaultMQPushConsumerConfig() { return m_pushConsumerConfig; } + + private: + void checkConfig(); + void copySubscription(); + void updateTopicSubscribeInfoWhenSubscriptionChanged(); + + int getMaxReconsumeTimes(); + + private: + DefaultMQPushConsumerConfig* m_pushConsumerConfig; + + uint64_t m_startTime; + + volatile bool m_pause; + bool m_consumeOrderly; + + std::map m_subTopics; + std::unique_ptr m_rebalanceImpl; + std::unique_ptr m_pullAPIWrapper; + std::unique_ptr m_offsetStore; + std::unique_ptr m_consumeService; + MQMessageListener* m_messageListener; +}; + +} // namespace rocketmq + +#endif // __DEFAULT_MQ_PUSH_CONSUMER_IMPL_H__ diff --git a/src/consumer/FindBrokerResult.h b/src/consumer/FindBrokerResult.h index 76ffc9b0a..d1eaa131b 100644 --- a/src/consumer/FindBrokerResult.h +++ b/src/consumer/FindBrokerResult.h @@ -14,12 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#ifndef __FINDBROKERRESULT_H__ -#define __FINDBROKERRESULT_H__ +#ifndef __FIND_BROKER_RESULT_H__ +#define __FIND_BROKER_RESULT_H__ namespace rocketmq { -// +#include + +#include "ConsumeType.h" +#include "SubscriptionData.h" + +namespace rocketmq { + +class ConsumerRunningInfo; + +class MQConsumerInner { + public: + virtual ~MQConsumerInner() = default; + + public: // MQConsumerInner in Java Client + virtual std::string groupName() const = 0; + virtual MessageModel messageModel() const = 0; + virtual ConsumeType consumeType() const = 0; + virtual ConsumeFromWhere consumeFromWhere() const = 0; + virtual std::vector subscriptions() const = 0; + + virtual void doRebalance() = 0; + virtual void persistConsumerOffset() = 0; + virtual void updateTopicSubscribeInfo(const std::string& topic, std::vector& info) = 0; + virtual ConsumerRunningInfo* consumerRunningInfo() = 0; +}; + +} // namespace rocketmq + +#endif // __MQ_CONSUMER_INNER_H__ diff --git a/src/consumer/MessageQueueLock.hpp b/src/consumer/MessageQueueLock.hpp new file mode 100644 index 000000000..3579c28fa --- /dev/null +++ b/src/consumer/MessageQueueLock.hpp @@ -0,0 +1,48 @@ +/* + * 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_QUEUE_LOCK__ +#define __MESSAGE_QUEUE_LOCK__ + +#include +#include +#include + +#include "MQMessageQueue.h" + +namespace rocketmq { + +/** + * Message lock, strictly ensure the single queue only one thread at a time consuming + */ +class MessageQueueLock { + public: + std::shared_ptr fetchLockObject(const MQMessageQueue& mq) { + std::lock_guard lock(m_mqLockTableMutex); + if (m_mqLockTable.find(mq) == m_mqLockTable.end()) { + m_mqLockTable.emplace(mq, std::shared_ptr(new std::mutex())); + } + return m_mqLockTable[mq]; + } + + private: + std::map> m_mqLockTable; + std::mutex m_mqLockTableMutex; +}; + +} // namespace rocketmq + +#endif // __MESSAGE_QUEUE_LOCK__ diff --git a/src/consumer/OffsetStore.cpp b/src/consumer/OffsetStore.cpp index 324653ddb..d68cf2c0a 100644 --- a/src/consumer/OffsetStore.cpp +++ b/src/consumer/OffsetStore.cpp @@ -15,158 +15,92 @@ * limitations under the License. */ #include "OffsetStore.h" -#include "Logging.h" -#include "MQClientFactory.h" -#include "MessageQueue.h" #include -#include - -#include -#include -#include -#include -#include -#include -namespace rocketmq { -//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::LocalFileOffsetStore(MQClientInstance* instance, const std::string& groupName) + : m_clientInstance(instance), m_groupName(groupName) { + LOG_INFO("new LocalFileOffsetStore"); + + std::string clientId = instance->getClientId(); + std::string homeDir(UtilAll::getHomeDirectory()); + std::string storeDir = + homeDir + FILE_SEPARATOR + ".rocketmq_offsets" + FILE_SEPARATOR + clientId + FILE_SEPARATOR + groupName; + m_storePath = storeDir + FILE_SEPARATOR + "offsets.json"; + + if (!UtilAll::existDirectory(storeDir)) { + UtilAll::createDirectory(storeDir); + if (!UtilAll::existDirectory(storeDir)) { + LOG_ERROR("create offset store dir:%s error", storeDir.c_str()); + std::string errorMsg("create offset store dir failed: "); + errorMsg.append(storeDir); + THROW_MQEXCEPTION(MQClientException, errorMsg, -1); } } } -LocalFileOffsetStore::~LocalFileOffsetStore() {} +LocalFileOffsetStore::~LocalFileOffsetStore() { + m_clientInstance = nullptr; + m_offsetTable.clear(); +} 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 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::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); + auto offsetTable = readLocalOffset(); + if (!offsetTable.empty()) { + // update offsetTable + { + std::lock_guard lock(m_lock); + m_offsetTable = offsetTable; + } + + for (const auto& it : offsetTable) { + const auto& mq = it.first; + const auto offset = it.second; + LOG_INFO_NEW("load consumer's offset, {} {} {}", m_groupName, mq.toString(), offset); } - } 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 lock(m_lock); +void LocalFileOffsetStore::updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) { + std::lock_guard lock(m_lock); m_offsetTable[mq] = offset; } -int64 LocalFileOffsetStore::readOffset(const MQMessageQueue& mq, - ReadOffsetType type, - const SessionCredentials& session_credentials) { +int64_t LocalFileOffsetStore::readOffset(const MQMessageQueue& mq, ReadOffsetType type) { switch (type) { case MEMORY_FIRST_THEN_STORE: case READ_FROM_MEMORY: { - boost::lock_guard lock(m_lock); - MQ2OFFSET::iterator it = m_offsetTable.find(mq); + std::lock_guard lock(m_lock); + auto it = m_offsetTable.find(mq); if (it != m_offsetTable.end()) { return it->second; } else if (READ_FROM_MEMORY == type) { return -1; } - } + } break; case READ_FROM_STORE: { - try { - load(); - } catch (MQException& e) { - LOG_ERROR("catch exception when load local file"); - return -1; - } - boost::lock_guard lock(m_lock); - MQ2OFFSET::iterator it = m_offsetTable.find(mq); - if (it != m_offsetTable.end()) { - return it->second; + auto offsetTable = readLocalOffset(); + if (!offsetTable.empty()) { + auto it = offsetTable.find(mq); + if (it != offsetTable.end()) { + auto offset = it->second; + updateOffset(mq, offset, false); + return offset; + } } - } + } break; default: break; } @@ -174,70 +108,126 @@ int64 LocalFileOffsetStore::readOffset(const MQMessageQueue& mq, return -1; } -void LocalFileOffsetStore::persist(const MQMessageQueue& mq, const SessionCredentials& session_credentials) {} +void LocalFileOffsetStore::persist(const MQMessageQueue& mq) {} void LocalFileOffsetStore::persistAll(const std::vector& mqs) { - boost::lock_guard lock(m_lock); - - map m_offsetTable_tmp; - vector::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]; + if (mqs.empty()) { + return; + } + + std::map offsetTable; + { + std::lock_guard lock(m_lock); + offsetTable = m_offsetTable; + } + + Json::Value root(Json::objectValue); + Json::Value jOffsetTable(Json::objectValue); + for (const auto& mq : mqs) { + auto it = offsetTable.find(mq); + if (it != offsetTable.end()) { + std::string strMQ = RemotingSerializable::toJson(toJson(mq)); + jOffsetTable[strMQ] = Json::Value((Json::Int64)it->second); + } } + root["offsetTable"] = jOffsetTable; - 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()) { + std::lock_guard lock2(m_fileMutex); + std::string storePathTmp = m_storePath + ".tmp"; + std::ofstream ofstrm(storePathTmp, std::ios::binary | std::ios::out); + if (ofstrm.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&>(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); + RemotingSerializable::toJson(root, ofstrm, true); + } catch (std::exception& e) { + THROW_MQEXCEPTION(MQClientException, "persistAll failed", -1); + } + + if (!UtilAll::ReplaceFile(m_storePath, m_storePath + ".bak") || !UtilAll::ReplaceFile(storePathTmp, m_storePath)) { + LOG_ERROR("could not rename file: %s", strerror(errno)); } - 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) {} -// LocalFileOffsetStore::readLocalOffset() { + std::lock_guard lock(m_fileMutex); + std::ifstream ifstrm(m_storePath, std::ios::binary | std::ios::in); + if (ifstrm.is_open() && !ifstrm.eof()) { + try { + Json::Value root = RemotingSerializable::fromJson(ifstrm); + std::map offsetTable; + auto& jOffsetTable = root["offsetTable"]; + for (auto& strMQ : jOffsetTable.getMemberNames()) { + auto& offset = jOffsetTable[strMQ]; + Json::Value jMQ = RemotingSerializable::fromJson(strMQ); + MQMessageQueue mq(jMQ["topic"].asString(), jMQ["brokerName"].asString(), jMQ["queueId"].asInt()); + offsetTable.emplace(std::move(mq), offset.asInt64()); + } + return offsetTable; + } catch (std::exception& e) { + // ... + } + } + return readLocalOffsetBak(); +} -RemoteBrokerOffsetStore::~RemoteBrokerOffsetStore() {} +std::map LocalFileOffsetStore::readLocalOffsetBak() { + std::map offsetTable; + std::ifstream ifstrm(m_storePath + ".bak", std::ios::binary | std::ios::in); + if (ifstrm.is_open()) { + if (!ifstrm.eof()) { + try { + Json::Value root = RemotingSerializable::fromJson(ifstrm); + auto& jOffsetTable = root["offsetTable"]; + for (auto& strMQ : jOffsetTable.getMemberNames()) { + auto& offset = jOffsetTable[strMQ]; + Json::Value jMQ = RemotingSerializable::fromJson(strMQ); + MQMessageQueue mq(jMQ["topic"].asString(), jMQ["brokerName"].asString(), jMQ["queueId"].asInt()); + offsetTable.emplace(mq, offset.asInt64()); + } + } catch (const std::exception& e) { + LOG_WARN_NEW("readLocalOffset Exception {}", e.what()); + THROW_MQEXCEPTION(MQClientException, "readLocalOffset Exception", -1); + } + } + } + return offsetTable; +} + +//###################################### +// RemoteBrokerOffsetStore +//###################################### + +RemoteBrokerOffsetStore::RemoteBrokerOffsetStore(MQClientInstance* instance, const std::string& groupName) + : m_clientInstance(instance), m_groupName(groupName) {} + +RemoteBrokerOffsetStore::~RemoteBrokerOffsetStore() { + m_clientInstance = nullptr; + m_offsetTable.clear(); +} void RemoteBrokerOffsetStore::load() {} -void RemoteBrokerOffsetStore::updateOffset(const MQMessageQueue& mq, int64 offset) { - boost::lock_guard lock(m_lock); - m_offsetTable[mq] = offset; +void RemoteBrokerOffsetStore::updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) { + std::lock_guard lock(m_lock); + auto it = m_offsetTable.find(mq); + if (it != m_offsetTable.end()) { + if (!increaseOnly || offset > it->second) { + it->second = offset; + } + } else { + m_offsetTable[mq] = offset; + } } -int64 RemoteBrokerOffsetStore::readOffset(const MQMessageQueue& mq, - ReadOffsetType type, - const SessionCredentials& session_credentials) { +int64_t RemoteBrokerOffsetStore::readOffset(const MQMessageQueue& mq, ReadOffsetType type) { switch (type) { case MEMORY_FIRST_THEN_STORE: case READ_FROM_MEMORY: { - boost::lock_guard lock(m_lock); + std::lock_guard lock(m_lock); - MQ2OFFSET::iterator it = m_offsetTable.find(mq); + auto it = m_offsetTable.find(mq); if (it != m_offsetTable.end()) { return it->second; } else if (READ_FROM_MEMORY == type) { @@ -246,9 +236,9 @@ int64 RemoteBrokerOffsetStore::readOffset(const MQMessageQueue& mq, } case READ_FROM_STORE: { try { - int64 brokerOffset = fetchConsumeOffsetFromBroker(mq, session_credentials); - // offsetTable; { - boost::lock_guard lock(m_lock); + std::lock_guard lock(m_lock); offsetTable = m_offsetTable; } - MQ2OFFSET::iterator it = offsetTable.find(mq); + auto it = offsetTable.find(mq); if (it != offsetTable.end()) { try { - updateConsumeOffsetToBroker(mq, it->second, session_credentials); + updateConsumeOffsetToBroker(mq, it->second); } catch (MQException& e) { - LOG_ERROR("updateConsumeOffsetToBroker %s ,offset:[%lld] error", mq.toString().c_str(), it->second); + LOG_ERROR("updateConsumeOffsetToBroker error"); } } } @@ -284,32 +274,31 @@ void RemoteBrokerOffsetStore::persist(const MQMessageQueue& mq, const SessionCre void RemoteBrokerOffsetStore::persistAll(const std::vector& mq) {} void RemoteBrokerOffsetStore::removeOffset(const MQMessageQueue& mq) { - boost::lock_guard lock(m_lock); - if (m_offsetTable.find(mq) != m_offsetTable.end()) + std::lock_guard 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 pFindBrokerResult(m_pClientFactory->findBrokerAddressInAdmin(mq.getBrokerName())); +void RemoteBrokerOffsetStore::updateConsumeOffsetToBroker(const MQMessageQueue& mq, int64_t offset) { + std::unique_ptr findBrokerResult(m_clientInstance->findBrokerAddressInAdmin(mq.getBrokerName())); - if (pFindBrokerResult == NULL) { - m_pClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic(), session_credentials); - pFindBrokerResult.reset(m_pClientFactory->findBrokerAddressInAdmin(mq.getBrokerName())); + if (findBrokerResult == nullptr) { + m_clientInstance->updateTopicRouteInfoFromNameServer(mq.getTopic()); + findBrokerResult.reset(m_clientInstance->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; + if (findBrokerResult != nullptr) { + UpdateConsumerOffsetRequestHeader* requestHeader = new UpdateConsumerOffsetRequestHeader(); + requestHeader->topic = mq.getTopic(); + requestHeader->consumerGroup = m_groupName; + requestHeader->queueId = mq.getQueueId(); + requestHeader->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); + return m_clientInstance->getMQClientAPIImpl()->updateConsumerOffsetOneway(findBrokerResult->brokerAddr, + requestHeader, 1000 * 5); } catch (MQException& e) { LOG_ERROR(e.what()); } @@ -317,27 +306,26 @@ void RemoteBrokerOffsetStore::updateConsumeOffsetToBroker(const MQMessageQueue& LOG_WARN("The broker not exist"); } -int64 RemoteBrokerOffsetStore::fetchConsumeOffsetFromBroker(const MQMessageQueue& mq, - const SessionCredentials& session_credentials) { - unique_ptr pFindBrokerResult(m_pClientFactory->findBrokerAddressInAdmin(mq.getBrokerName())); +int64_t RemoteBrokerOffsetStore::fetchConsumeOffsetFromBroker(const MQMessageQueue& mq) { + std::unique_ptr findBrokerResult(m_clientInstance->findBrokerAddressInAdmin(mq.getBrokerName())); - if (pFindBrokerResult == NULL) { - m_pClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic(), session_credentials); - pFindBrokerResult.reset(m_pClientFactory->findBrokerAddressInAdmin(mq.getBrokerName())); + if (findBrokerResult == nullptr) { + m_clientInstance->updateTopicRouteInfoFromNameServer(mq.getTopic()); + findBrokerResult.reset(m_clientInstance->findBrokerAddressInAdmin(mq.getBrokerName())); } - if (pFindBrokerResult != NULL) { - QueryConsumerOffsetRequestHeader* pRequestHeader = new QueryConsumerOffsetRequestHeader(); - pRequestHeader->topic = mq.getTopic(); - pRequestHeader->consumerGroup = m_groupName; - pRequestHeader->queueId = mq.getQueueId(); + if (findBrokerResult != nullptr) { + QueryConsumerOffsetRequestHeader* requestHeader = new QueryConsumerOffsetRequestHeader(); + requestHeader->topic = mq.getTopic(); + requestHeader->consumerGroup = m_groupName; + requestHeader->queueId = mq.getQueueId(); - return m_pClientFactory->getMQClientAPIImpl()->queryConsumerOffset(pFindBrokerResult->brokerAddr, pRequestHeader, - 1000 * 5, session_credentials); + return m_clientInstance->getMQClientAPIImpl()->queryConsumerOffset(findBrokerResult->brokerAddr, requestHeader, + 1000 * 5); } else { LOG_ERROR("The broker not exist when fetchConsumeOffsetFromBroker"); THROW_MQEXCEPTION(MQClientException, "The broker not exist", -1); } } -// -#include -#include #include +#include +#include + +#include "MQClientInstance.h" #include "MQMessageQueue.h" -#include "SessionCredentials.h" namespace rocketmq { -class MQClientFactory; -//& mq) = 0; virtual void removeOffset(const MQMessageQueue& mq) = 0; - - protected: - std::string m_groupName; - typedef std::map MQ2OFFSET; - MQ2OFFSET m_offsetTable; - MQClientFactory* m_pClientFactory; - boost::mutex m_lock; }; -//& mq); - virtual void removeOffset(const MQMessageQueue& mq); + void load() override; + void updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) override; + int64_t readOffset(const MQMessageQueue& mq, ReadOffsetType type) override; + void persist(const MQMessageQueue& mq) override; + void persistAll(const std::vector& mq) override; + void removeOffset(const MQMessageQueue& mq) override; private: + std::map readLocalOffset(); + std::map readLocalOffsetBak(); + + private: + MQClientInstance* m_clientInstance; + std::string m_groupName; + + std::map m_offsetTable; + std::mutex m_lock; + std::string m_storePath; - std::string m_storeFile; + std::mutex m_fileMutex; }; -//& mq); - virtual void removeOffset(const MQMessageQueue& mq); + void load() override; + void updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) override; + int64_t readOffset(const MQMessageQueue& mq, ReadOffsetType type) override; + void persist(const MQMessageQueue& mq) override; + void persistAll(const std::vector& mq) override; + void removeOffset(const MQMessageQueue& mq) override; + + private: + void updateConsumeOffsetToBroker(const MQMessageQueue& mq, int64_t offset); + int64_t fetchConsumeOffsetFromBroker(const MQMessageQueue& mq); private: - void updateConsumeOffsetToBroker(const MQMessageQueue& mq, - int64 offset, - const SessionCredentials& session_credentials); - int64 fetchConsumeOffsetFromBroker(const MQMessageQueue& mq, const SessionCredentials& session_credentials); + MQClientInstance* m_clientInstance; + std::string m_groupName; + + std::map m_offsetTable; + std::mutex m_lock; }; -// RebalanceLockMaxLiveTime; +} + +bool ProcessQueue::isPullExpired() const { + return (UtilAll::currentTimeMillis() - m_lastPullTimestamp) > PullMaxIdleTime; +} + +void ProcessQueue::putMessage(std::vector& msgs) { + std::lock_guard lock(m_lockTreeMap); + + for (const auto& msg : msgs) { + int64_t offset = msg->getQueueOffset(); + m_msgTreeMap[offset] = msg; + if (offset > m_queueOffsetMax) { + m_queueOffsetMax = offset; + } + } + + LOG_DEBUG("ProcessQueue: putMessage m_queueOffsetMax:%lld ", m_queueOffsetMax); +} + +int64_t ProcessQueue::removeMessage(std::vector& msgs) { + int64_t result = -1; + const auto now = UtilAll::currentTimeMillis(); + + std::lock_guard lock(m_lockTreeMap); + m_lastConsumeTimestamp = now; + + 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()); + + for (auto& msg : msgs) { + LOG_DEBUG("remove these msg from m_msgTreeMap, its offset:%lld", msg->getQueueOffset()); + m_msgTreeMap.erase(msg->getQueueOffset()); + } + + if (!m_msgTreeMap.empty()) { + auto it = m_msgTreeMap.begin(); + result = it->first; + } + } + + return result; +} + +int ProcessQueue::getCacheMsgCount() { + std::lock_guard lock(m_lockTreeMap); + return static_cast(m_msgTreeMap.size()); +} + +int64_t ProcessQueue::getCacheMinOffset() { + std::lock_guard lock(m_lockTreeMap); + if (m_msgTreeMap.empty()) { + return 0; + } else { + return m_msgTreeMap.begin()->first; + } +} + +int64_t ProcessQueue::getCacheMaxOffset() { + return m_queueOffsetMax; +} + +bool ProcessQueue::isDropped() const { + return m_dropped.load(); +} + +void ProcessQueue::setDropped(bool dropped) { + m_dropped.store(dropped); +} + +bool ProcessQueue::isLocked() const { + return m_locked.load(); +} + +void ProcessQueue::setLocked(bool locked) { + m_locked.store(locked); +} + +int64_t ProcessQueue::commit() { + std::lock_guard lock(m_lockTreeMap); + if (!m_consumingMsgOrderlyTreeMap.empty()) { + int64_t offset = (--m_consumingMsgOrderlyTreeMap.end())->first; + m_consumingMsgOrderlyTreeMap.clear(); + return offset + 1; + } else { + return -1; + } +} + +void ProcessQueue::makeMessageToCosumeAgain(std::vector& msgs) { + std::lock_guard lock(m_lockTreeMap); + for (const auto& msg : msgs) { + m_msgTreeMap[msg->getQueueOffset()] = msg; + m_consumingMsgOrderlyTreeMap.erase(msg->getQueueOffset()); + } +} + +void ProcessQueue::takeMessages(std::vector& out_msgs, int batchSize) { + std::lock_guard lock(m_lockTreeMap); + for (int i = 0; i != batchSize; i++) { + const auto& it = m_msgTreeMap.begin(); + if (it != m_msgTreeMap.end()) { + out_msgs.push_back(it->second); + m_consumingMsgOrderlyTreeMap[it->first] = it->second; + m_msgTreeMap.erase(it); + } + } +} + +void ProcessQueue::clearAllMsgs() { + std::lock_guard lock(m_lockTreeMap); + + if (isDropped()) { + LOG_DEBUG("clear m_msgTreeMap as PullRequest had been dropped."); + m_msgTreeMap.clear(); + m_consumingMsgOrderlyTreeMap.clear(); + m_queueOffsetMax = 0; + } +} + +uint64_t ProcessQueue::getLastLockTimestamp() const { + return m_lastLockTimestamp; +} + +void ProcessQueue::setLastLockTimestamp(int64_t lastLockTimestamp) { + m_lastLockTimestamp = lastLockTimestamp; +} + +std::timed_mutex& ProcessQueue::getLockConsume() { + return m_lockConsume; +} + +uint64_t ProcessQueue::getLastPullTimestamp() const { + return m_lastPullTimestamp; +} + +void ProcessQueue::setLastPullTimestamp(uint64_t lastPullTimestamp) { + m_lastPullTimestamp = lastPullTimestamp; +} + +long ProcessQueue::getTryUnlockTimes() { + return m_tryUnlockTimes.load(); +} + +void ProcessQueue::incTryUnlockTimes() { + m_tryUnlockTimes.fetch_add(1); +} + +uint64_t ProcessQueue::getLastConsumeTimestamp() { + return m_lastConsumeTimestamp; +} + +void ProcessQueue::setLastConsumeTimestamp(uint64_t lastConsumeTimestamp) { + m_lastConsumeTimestamp = lastConsumeTimestamp; +} + +void ProcessQueue::fillProcessQueueInfo(ProcessQueueInfo& info) { + std::lock_guard lock(m_lockTreeMap); + + if (!m_msgTreeMap.empty()) { + info.cachedMsgMinOffset = m_msgTreeMap.begin()->first; + info.cachedMsgMaxOffset = m_queueOffsetMax; + info.cachedMsgCount = m_msgTreeMap.size(); + } + + if (!m_consumingMsgOrderlyTreeMap.empty()) { + info.transactionMsgMinOffset = m_consumingMsgOrderlyTreeMap.begin()->first; + info.transactionMsgMaxOffset = (--m_consumingMsgOrderlyTreeMap.end())->first; + info.transactionMsgCount = m_consumingMsgOrderlyTreeMap.size(); + } + + info.setLocked(m_locked); + info.tryUnlockTimes = m_tryUnlockTimes.load(); + info.lastLockTimestamp = m_lastLockTimestamp; + + info.setDroped(m_dropped); + info.lastPullTimestamp = m_lastPullTimestamp; + info.lastConsumeTimestamp = m_lastConsumeTimestamp; +} + +} // namespace rocketmq diff --git a/src/consumer/ProcessQueue.h b/src/consumer/ProcessQueue.h new file mode 100644 index 000000000..84672c548 --- /dev/null +++ b/src/consumer/ProcessQueue.h @@ -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 __PROCESS_QUEUE_H__ +#define __PROCESS_QUEUE_H__ + +#include +#include +#include +#include +#include + +#include "MQMessageExt.h" + +namespace rocketmq { + +class ProcessQueueInfo; + +class ProcessQueue; +typedef std::shared_ptr ProcessQueuePtr; + +class ROCKETMQCLIENT_API ProcessQueue { + public: + static const uint64_t RebalanceLockMaxLiveTime; // ms + static const uint64_t RebalanceLockInterval; // ms + + public: + ProcessQueue(); + virtual ~ProcessQueue(); + + bool isLockExpired() const; + bool isPullExpired() const; + + void putMessage(std::vector& msgs); + int64_t removeMessage(std::vector& msgs); + + int getCacheMsgCount(); + int64_t getCacheMinOffset(); + int64_t getCacheMaxOffset(); + + bool isDropped() const; + void setDropped(bool dropped); + + bool isLocked() const; + void setLocked(bool locked); + + int64_t commit(); + void makeMessageToCosumeAgain(std::vector& msgs); + void takeMessages(std::vector& out_msgs, int batchSize); + + void clearAllMsgs(); + + uint64_t getLastLockTimestamp() const; + void setLastLockTimestamp(int64_t lastLockTimestamp); + + std::timed_mutex& getLockConsume(); + + uint64_t getLastPullTimestamp() const; + void setLastPullTimestamp(uint64_t lastPullTimestamp); + + long getTryUnlockTimes(); + void incTryUnlockTimes(); + + uint64_t getLastConsumeTimestamp(); + void setLastConsumeTimestamp(uint64_t lastConsumeTimestamp); + + void fillProcessQueueInfo(ProcessQueueInfo& info); + + private: + static const uint64_t PullMaxIdleTime; + + private: + std::mutex m_lockTreeMap; + std::map m_msgTreeMap; + std::timed_mutex m_lockConsume; + std::map m_consumingMsgOrderlyTreeMap; + std::atomic m_tryUnlockTimes; + volatile int64_t m_queueOffsetMax; + std::atomic m_dropped; + volatile uint64_t m_lastPullTimestamp; + volatile uint64_t m_lastConsumeTimestamp; + std::atomic m_locked; + volatile uint64_t m_lastLockTimestamp; // ms +}; + +} // namespace rocketmq + +#endif // __PROCESS_QUEUE_H__ diff --git a/src/consumer/PullAPIWrapper.cpp b/src/consumer/PullAPIWrapper.cpp index a7f115619..cd1b49dfb 100644 --- a/src/consumer/PullAPIWrapper.cpp +++ b/src/consumer/PullAPIWrapper.cpp @@ -1,133 +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. - */ -#include "PullAPIWrapper.h" -#include "CommunicationMode.h" -#include "MQClientFactory.h" -#include "PullResultExt.h" -#include "PullSysFlag.h" -namespace rocketmq { -// lock(m_lock); - m_pullFromWhichNodeTable[mq] = brokerId; -} - -int PullAPIWrapper::recalculatePullFromWhichNode(const MQMessageQueue& mq) { - boost::lock_guard 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(pullResult); - if (pResultExt == NULL) { - string errMsg("The pullResult NULL of"); - errMsg.append(mq.toString()); - THROW_MQEXCEPTION(MQClientException, errMsg, -1); - } - - //suggestWhichBrokerId); - - vector msgFilterList; - if (pResultExt->pullStatus == FOUND) { - // msgAllList; - MQDecoder::decodes(&pResultExt->msgMemBlock, msgAllList); - - //getTagsSet().empty()) { - msgFilterList.reserve(msgAllList.size()); - vector::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 pFindBrokerResult( - m_MQClientFactory->findBrokerAddressInSubscribe(mq.getBrokerName(), recalculatePullFromWhichNode(mq), false)); - //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 +/* + * 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 "MQClientAPIImpl.h" +#include "MQClientInstance.h" +#include "MQDecoder.h" +#include "MessageAccessor.h" +#include "PullResultExt.h" +#include "PullSysFlag.h" + +namespace rocketmq { + +PullAPIWrapper::PullAPIWrapper(MQClientInstance* instance, const std::string& consumerGroup) { + m_clientInstance = instance; + m_consumerGroup = consumerGroup; +} + +PullAPIWrapper::~PullAPIWrapper() { + m_clientInstance = nullptr; + m_pullFromWhichNodeTable.clear(); +} + +void PullAPIWrapper::updatePullFromWhichNode(const MQMessageQueue& mq, int brokerId) { + std::lock_guard lock(m_lock); + m_pullFromWhichNodeTable[mq] = brokerId; +} + +int PullAPIWrapper::recalculatePullFromWhichNode(const MQMessageQueue& mq) { + std::lock_guard 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, + SubscriptionDataPtr subscriptionData) { + assert(std::type_index(typeid(pullResult)) == std::type_index(typeid(PullResultExt))); + auto& pullResultExt = dynamic_cast(pullResult); + + // update node + updatePullFromWhichNode(mq, pullResultExt.suggestWhichBrokerId); + + std::vector msgListFilterAgain; + if (FOUND == pullResultExt.pullStatus) { + // decode all msg list + auto msgList = MQDecoder::decodes(*pullResultExt.msgMemBlock); + + // filter msg list again + if (subscriptionData != nullptr && !subscriptionData->getTagsSet().empty()) { + msgListFilterAgain.reserve(msgList.size()); + for (const auto& msg : msgList) { + const auto& msgTag = msg->getTags(); + if (subscriptionData->containTag(msgTag)) { + msgListFilterAgain.push_back(msg); + } + } + } else { + msgListFilterAgain.swap(msgList); + } + + for (auto& msg : msgListFilterAgain) { + const auto& traFlag = msg->getProperty(MQMessageConst::PROPERTY_TRANSACTION_PREPARED); + if (UtilAll::stob(traFlag)) { + msg->setTransactionId(msg->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX)); + } + MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_MIN_OFFSET, UtilAll::to_string(pullResult.minOffset)); + MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_MAX_OFFSET, UtilAll::to_string(pullResult.maxOffset)); + } + } + + return PullResult(pullResultExt.pullStatus, pullResultExt.nextBeginOffset, pullResultExt.minOffset, + pullResultExt.maxOffset, std::move(msgListFilterAgain)); +} + +PullResult* PullAPIWrapper::pullKernelImpl(const MQMessageQueue& mq, // 1 + const std::string& subExpression, // 2 + int64_t subVersion, // 3 + int64_t offset, // 4 + int maxNums, // 5 + int sysFlag, // 6 + int64_t commitOffset, // 7 + int brokerSuspendMaxTimeMillis, // 8 + int timeoutMillis, // 9 + CommunicationMode communicationMode, // 10 + PullCallback* pullCallback) { + std::unique_ptr findBrokerResult( + m_clientInstance->findBrokerAddressInSubscribe(mq.getBrokerName(), recalculatePullFromWhichNode(mq), false)); + if (findBrokerResult == nullptr) { + m_clientInstance->updateTopicRouteInfoFromNameServer(mq.getTopic()); + findBrokerResult.reset( + m_clientInstance->findBrokerAddressInSubscribe(mq.getBrokerName(), recalculatePullFromWhichNode(mq), false)); + } + + if (findBrokerResult != nullptr) { + int sysFlagInner = sysFlag; + + if (findBrokerResult->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_clientInstance->getMQClientAPIImpl()->pullMessage(findBrokerResult->brokerAddr, pRequestHeader, + timeoutMillis, communicationMode, pullCallback); + } + + THROW_MQEXCEPTION(MQClientException, "The broker [" + mq.getBrokerName() + "] not exist", -1); +} + +} // namespace rocketmq diff --git a/src/consumer/PullAPIWrapper.h b/src/consumer/PullAPIWrapper.h index 29a64fb8e..ce8f5c0a9 100644 --- a/src/consumer/PullAPIWrapper.h +++ b/src/consumer/PullAPIWrapper.h @@ -1,66 +1,63 @@ -/* - * 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 -#include -#include "AsyncCallback.h" -#include "MQMessageQueue.h" -#include "SessionCredentials.h" -#include "SubscriptionData.h" - -namespace rocketmq { -class MQClientFactory; -// m_pullFromWhichNodeTable; -}; - -// + +#include "CommunicationMode.h" +#include "MQClientInstance.h" +#include "MQMessageQueue.h" +#include "PullCallback.h" +#include "SubscriptionData.h" + +namespace rocketmq { + +class PullAPIWrapper { + public: + PullAPIWrapper(MQClientInstance* instance, const std::string& consumerGroup); + ~PullAPIWrapper(); + + PullResult processPullResult(const MQMessageQueue& mq, PullResult& pullResult, SubscriptionDataPtr subscriptionData); + + PullResult* pullKernelImpl(const MQMessageQueue& mq, // 1 + const std::string& subExpression, // 2 + int64_t subVersion, // 3 + int64_t offset, // 4 + int maxNums, // 5 + int sysFlag, // 6 + int64_t commitOffset, // 7 + int brokerSuspendMaxTimeMillis, // 8 + int timeoutMillis, // 9 + CommunicationMode communicationMode, // 10 + PullCallback* pullCallback); + + private: + void updatePullFromWhichNode(const MQMessageQueue& mq, int brokerId); + + int recalculatePullFromWhichNode(const MQMessageQueue& mq); + + private: + MQClientInstance* m_clientInstance; + std::string m_consumerGroup; + std::mutex m_lock; + std::map m_pullFromWhichNodeTable; +}; + +} // namespace rocketmq + +#endif // __PULL_API_WRAPPER_H__ diff --git a/src/consumer/PullMessageService.h b/src/consumer/PullMessageService.h new file mode 100644 index 000000000..7c7b11a1c --- /dev/null +++ b/src/consumer/PullMessageService.h @@ -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. + */ +#ifndef __PULL_MESSAGE_SERVICE_H__ +#define __PULL_MESSAGE_SERVICE_H__ + +#include "DefaultMQPushConsumerImpl.h" +#include "Logging.h" +#include "MQClientInstance.h" +#include "PullRequest.h" +#include "concurrent/executor.hpp" + +namespace rocketmq { + +class PullMessageService { + public: + PullMessageService(MQClientInstance* instance) + : m_clientInstance(instance), m_scheduledExecutorService(getServiceName(), 1, false) {} + + void start() { m_scheduledExecutorService.startup(); } + + void shutdown() { m_scheduledExecutorService.shutdown(); } + + void executePullRequestLater(PullRequestPtr pullRequest, long timeDelay) { + if (m_clientInstance->isRunning()) { + m_scheduledExecutorService.schedule( + std::bind(&PullMessageService::executePullRequestImmediately, this, pullRequest), timeDelay, + time_unit::milliseconds); + } else { + LOG_WARN_NEW("PullMessageServiceScheduledThread has shutdown"); + } + } + + void executePullRequestImmediately(PullRequestPtr pullRequest) { + m_scheduledExecutorService.submit(std::bind(&PullMessageService::pullMessage, this, pullRequest)); + } + + void executeTaskLater(const handler_type& task, long timeDelay) { + m_scheduledExecutorService.schedule(task, timeDelay, time_unit::milliseconds); + } + + std::string getServiceName() { return "PullMessageService"; } + + private: + void pullMessage(PullRequestPtr pullRequest) { + MQConsumerInner* consumer = m_clientInstance->selectConsumer(pullRequest->getConsumerGroup()); + if (consumer != nullptr && std::type_index(typeid(*consumer)) == std::type_index(typeid(DefaultMQPushConsumerImpl))) { + auto* impl = static_cast(consumer); + impl->pullMessage(pullRequest); + } else { + LOG_WARN_NEW("No matched consumer for the PullRequest {}, drop it", pullRequest->toString()); + } + } + + private: + MQClientInstance* m_clientInstance; + scheduled_thread_pool_executor m_scheduledExecutorService; +}; + +} // namespace rocketmq + +#endif // __PULL_MESSAGE_SERVICE_H__ diff --git a/src/consumer/PullRequest.cpp b/src/consumer/PullRequest.cpp index e57884088..2df57609a 100644 --- a/src/consumer/PullRequest.cpp +++ b/src/consumer/PullRequest.cpp @@ -1,278 +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 "PullRequest.h" -#include "Logging.h" - -namespace rocketmq { -// 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& msgs) { - boost::lock_guard lock(m_pullRequestLock); - - vector::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& msgs) { - boost::lock_guard lock(m_pullRequestLock); - - map::iterator it = m_msgTreeMap.begin(); - for (; it != m_msgTreeMap.end(); it++) { - msgs.push_back(it->second); - } -} - -int64 PullRequest::getCacheMinOffset() { - boost::lock_guard lock(m_pullRequestLock); - if (m_msgTreeMap.empty()) { - return 0; - } else { - map::iterator it = m_msgTreeMap.begin(); - MQMessageExt msg = it->second; - return msg.getQueueOffset(); - } -} - -int64 PullRequest::getCacheMaxOffset() { - return m_queueOffsetMax; -} - -int PullRequest::getCacheMsgCount() { - boost::lock_guard lock(m_pullRequestLock); - return m_msgTreeMap.size(); -} - -void PullRequest::getMessageByQueueOffset(vector& msgs, int64 minQueueOffset, int64 maxQueueOffset) { - boost::lock_guard lock(m_pullRequestLock); - - int64 it = minQueueOffset; - for (; it <= maxQueueOffset; it++) { - msgs.push_back(m_msgTreeMap[it]); - } -} - -int64 PullRequest::removeMessage(vector& msgs) { - boost::lock_guard 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::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::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 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 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 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& msgs, int batchSize) { - boost::lock_guard lock(m_pullRequestLock); - for (int i = 0; i != batchSize; i++) { - map::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& msgs) { - boost::lock_guard 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 lock(m_pullRequestLock); - if (!m_msgTreeMapTemp.empty()) { - int64 offset = (--m_msgTreeMapTemp.end())->first; - m_msgTreeMapTemp.clear(); - return offset + 1; - } else { - return -1; - } -} - -// +#include +#include -#include -#include -#include -#include "MQMessageExt.h" #include "MQMessageQueue.h" -#include "UtilAll.h" +#include "ProcessQueue.h" + namespace rocketmq { -//& msgs); - void getMessage(vector& msgs); - int64 getCacheMinOffset(); - int64 getCacheMaxOffset(); - int getCacheMsgCount(); - void getMessageByQueueOffset(vector& msgs, int64 minQueueOffset, int64 maxQueueOffset); - int64 removeMessage(vector& msgs); - void clearAllMsgs(); +class PullRequest; +typedef std::shared_ptr PullRequestPtr; - PullRequest& operator=(const PullRequest& other); +class ROCKETMQCLIENT_API PullRequest { + public: + PullRequest(); + virtual ~PullRequest(); - void setDropped(bool dropped); - bool isDropped() const; + bool isLockedFirst() const; + void setLockedFirst(bool lockedFirst); - int64 getNextOffset(); - void setNextOffset(int64 nextoffset); + const std::string& getConsumerGroup() const; + void setConsumerGroup(const std::string& consumerGroup); - string getGroupName() const; + const MQMessageQueue& getMessageQueue(); + void setMessageQueue(const MQMessageQueue& messageQueue); - void updateQueueMaxOffset(int64 queueOffset); + int64_t getNextOffset(); + void setNextOffset(int64_t nextOffset); - 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& msgs, int batchSize); - int64 commit(); - void makeMessageToCosumeAgain(vector& msgs); - boost::timed_mutex& getPullRequestCriticalSection(); - bool removePullMsgEvent(bool force = false); - bool addPullMsgEvent(); - /** - * Check if there is an in-flight pull request. - */ - bool hasInFlightPullRequest() const; + ProcessQueuePtr getProcessQueue(); + void setProcessQueue(ProcessQueuePtr processQueue); - public: - MQMessageQueue m_messageQueue; - static const uint64 RebalanceLockInterval; // ms - static const uint64 RebalanceLockMaxLiveTime; // ms - static const uint64 MAX_PULL_IDLE_TIME; // ms + std::string toString() const { + std::stringstream ss; + ss << "PullRequest [consumerGroup=" << m_consumerGroup << ", messageQueue=" << m_messageQueue.toString() + << ", nextOffset=" << m_nextOffset << "]"; + return ss.str(); + } private: - string m_groupname; - int64 m_nextOffset; - int64 m_queueOffsetMax; - boost::atomic m_bDropped; - boost::atomic m_bLocked; - map m_msgTreeMap; - map m_msgTreeMapTemp; - boost::mutex m_pullRequestLock; - uint64 m_lastLockTimestamp; // ms - // uint64 m_tryUnlockTimes; - uint64 m_lastPullTimestamp; - uint64 m_lastConsumeTimestamp; - boost::timed_mutex m_consumeLock; + std::string m_consumerGroup; + MQMessageQueue m_messageQueue; + ProcessQueuePtr m_processQueue; + int64_t m_nextOffset; + bool m_lockedFirst; }; -//& 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(); -} - -//& src) + : pullStatus(pullStatus), + nextBeginOffset(nextBeginOffset), + minOffset(minOffset), + maxOffset(maxOffset), + msgFoundList(src) {} + +PullResult::PullResult(PullStatus pullStatus, + int64_t nextBeginOffset, + int64_t minOffset, + int64_t maxOffset, + std::vector&& src) + : pullStatus(pullStatus), + nextBeginOffset(nextBeginOffset), + minOffset(minOffset), + maxOffset(maxOffset), + msgFoundList(std::forward>(src)) {} + +PullResult::~PullResult() = default; + +} // namespace rocketmq diff --git a/src/consumer/PullResultExt.h b/src/consumer/PullResultExt.h index 644d4cdf8..5a3c61426 100644 --- a/src/consumer/PullResultExt.h +++ b/src/consumer/PullResultExt.h @@ -15,48 +15,39 @@ * limitations under the License. */ #include "PullResult.h" + +#include "DataBlock.h" #include "UtilAll.h" -#include "dataBlock.h" namespace rocketmq { + /** * use internal only */ -//(messageBinary)) {} - - PullResultExt(PullStatus pullStatus, - int64 nextBeginOffset, - int64 minOffset, - int64 maxOffset, - int suggestWhichBrokerId) - : PullResult(pullStatus, nextBeginOffset, minOffset, maxOffset), suggestWhichBrokerId(suggestWhichBrokerId) {} + msgMemBlock(messageBinary) {} - virtual ~PullResultExt() {} + ~PullResultExt() override = default; public: int suggestWhichBrokerId; - MemoryBlock msgMemBlock; + MemoryBlockPtr2 msgMemBlock; }; } // namespace rocketmq diff --git a/src/consumer/Rebalance.cpp b/src/consumer/Rebalance.cpp deleted file mode 100644 index 5546b6125..000000000 --- a/src/consumer/Rebalance.cpp +++ /dev/null @@ -1,657 +0,0 @@ -/* - * 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 "DefaultMQPushConsumer.h" -#include "LockBatchBody.h" -#include "Logging.h" -#include "MQClientAPIImpl.h" -#include "MQClientFactory.h" -#include "OffsetStore.h" - -namespace rocketmq { -//::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::iterator it = m_subscriptionData.begin(); - for (; it != m_subscriptionData.end(); ++it) { - string topic = (it->first); - LOG_DEBUG("current topic is:%s", topic.c_str()); - // mqs - vector 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); - } - } - - //getMessageModel()) { - case BROADCASTING: { - bool changed = updateRequestTableInRebalance(topic, mqAll); - if (changed) { - messageQueueChanged(topic, mqAll, mqAll); - } - break; - } - case CLUSTERING: { - vector 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()); - } - // 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(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()); - } - - //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::size_type i = 0; i < allocateResult.size(); ++i) { - ss << allocateResult[i].toString() << "\n"; - } - // Log allocation result. - LOG_INFO(ss.str().c_str()); - messageQueueChanged(topic, mqAll, allocateResult); - break; - } - } - default: - break; - } - } - } catch (MQException& e) { - LOG_ERROR(e.what()); - } -} - -void Rebalance::persistConsumerOffset() { - DefaultMQPushConsumer* pConsumer = static_cast(m_pConsumer); - OffsetStore* pOffsetStore = pConsumer->getOffsetStore(); - vector mqs; - { - boost::lock_guard 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::iterator it2 = mqs.begin(); - for (; it2 != mqs.end(); ++it2) { - pOffsetStore->persist(*it2, m_pConsumer->getSessionCredentials()); - } - } -} - -void Rebalance::persistConsumerOffsetByResetOffset() { - DefaultMQPushConsumer* pConsumer = static_cast(m_pConsumer); - OffsetStore* pOffsetStore = pConsumer->getOffsetStore(); - vector mqs; - { - boost::lock_guard 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::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& 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& mqs) { - if (m_subscriptionData.find(topic) != m_subscriptionData.end()) { - { - boost::lock_guard lock(m_topicSubscribeInfoTableMutex); - if (m_topicSubscribeInfoTable.find(topic) != m_topicSubscribeInfoTable.end()) - m_topicSubscribeInfoTable.erase(topic); - m_topicSubscribeInfoTable[topic] = mqs; - } - // log - vector::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& mqs) { - boost::lock_guard 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 pPullRequest) { - boost::lock_guard lock(m_requestTableMutex); - m_requestQueueTable[mq] = pPullRequest; -} - -void Rebalance::removePullRequest(MQMessageQueue mq) { - boost::lock_guard lock(m_requestTableMutex); - if (m_requestQueueTable.find(mq) != m_requestQueueTable.end()) { - m_requestQueueTable.erase(mq); - } -} -bool Rebalance::isPullRequestExist(MQMessageQueue mq) { - boost::lock_guard lock(m_requestTableMutex); - if (m_requestQueueTable.find(mq) != m_requestQueueTable.end()) { - return true; - } - return false; -} -boost::weak_ptr Rebalance::getPullRequest(MQMessageQueue mq) { - boost::lock_guard lock(m_requestTableMutex); - if (m_requestQueueTable.find(mq) != m_requestQueueTable.end()) { - return m_requestQueueTable[mq]; - } - return boost::weak_ptr(); -} - -map> Rebalance::getPullRequestTable() { - boost::lock_guard lock(m_requestTableMutex); - return m_requestQueueTable; -} - -void Rebalance::unlockAll(bool oneWay) { - map*> 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* mqs = new vector; - 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*>::iterator itb = brokerMqs.begin(); itb != brokerMqs.end(); ++itb) { - unique_ptr 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 unlockBatchRequest(new UnlockBatchRequestBody()); - vector 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 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 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 unlockBatchRequest(new UnlockBatchRequestBody()); - vector 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 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*> 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* mqs = new vector; - 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*>::iterator itb = brokerMqs.begin(); itb != brokerMqs.end(); ++itb) { - string brokerName = (*(itb->second))[0].getBrokerName(); - unique_ptr pFindBrokerResult( - m_pClientFactory->findBrokerAddressInSubscribe(brokerName, MASTER_ID, true)); - if (!pFindBrokerResult) { - LOG_ERROR("lockAll findBrokerAddressInSubscribe ret null for broker:%s", brokerName.data()); - continue; - } - unique_ptr 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 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 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 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 lockBatchRequest(new LockBatchRequestBody()); - lockBatchRequest->setClientId(m_pConsumer->getMQClientId()); - lockBatchRequest->setConsumerGroup(m_pConsumer->getGroupName()); - vector in_mqSet; - in_mqSet.push_back(mq); - lockBatchRequest->setMqSet(in_mqSet); - bool lockResult = false; - - try { - vector 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 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; - } -} - -//& mqsSelf) { - return false; -} - -int64 RebalancePull::computePullFromWhere(const MQMessageQueue& mq) { - return 0; -} - -void RebalancePull::messageQueueChanged(const string& topic, - vector& mqAll, - vector& mqDivided) {} - -void RebalancePull::removeUnnecessaryMessageQueue(const MQMessageQueue& mq) {} - -//& 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; - - //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; - } - } - } - - //> pullRequestsToAdd; - vector::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 = boost::make_shared(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>::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; - DefaultMQPushConsumer* pConsumer = dynamic_cast(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& mqAll, - vector& mqDivided) {} - -void RebalancePush::removeUnnecessaryMessageQueue(const MQMessageQueue& mq) { - // DefaultMQPushConsumer *pConsumer = static_cast(m_pConsumer); - DefaultMQPushConsumer* pConsumer = dynamic_cast(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); - } -} - -// -#include - -namespace rocketmq { -class MQClientFactory; - -//& mqAll, - vector& mqDivided) = 0; - - virtual void removeUnnecessaryMessageQueue(const MQMessageQueue& mq) = 0; - - virtual int64 computePullFromWhere(const MQMessageQueue& mq) = 0; - - virtual bool updateRequestTableInRebalance(const string& topic, vector& mqsSelf) = 0; - - public: - void doRebalance(); - - void persistConsumerOffset(); - - void persistConsumerOffsetByResetOffset(); - - //& getSubscriptionInner(); - - //& mqs); - - bool getTopicSubscribeInfo(const string& topic, vector& mqs); - - void addPullRequest(MQMessageQueue mq, boost::shared_ptr pPullRequest); - void removePullRequest(MQMessageQueue mq); - bool isPullRequestExist(MQMessageQueue mq); - boost::weak_ptr getPullRequest(MQMessageQueue mq); - - map> getPullRequestTable(); - - void lockAll(); - - bool lock(MQMessageQueue mq); - - void unlockAll(bool oneWay = false); - - void unlock(MQMessageQueue mq); - - protected: - map m_subscriptionData; - - boost::mutex m_topicSubscribeInfoTableMutex; - map> m_topicSubscribeInfoTable; - typedef map> MQ2PULLREQ; - MQ2PULLREQ m_requestQueueTable; - boost::mutex m_requestTableMutex; - - AllocateMQStrategy* m_pAllocateMQStrategy; - MQConsumer* m_pConsumer; - MQClientFactory* m_pClientFactory; -}; - -//& mqAll, - vector& mqDivided); - - virtual void removeUnnecessaryMessageQueue(const MQMessageQueue& mq); - - virtual int64 computePullFromWhere(const MQMessageQueue& mq); - - virtual bool updateRequestTableInRebalance(const string& topic, vector& mqsSelf); -}; - -//& mqAll, - vector& mqDivided); - - virtual void removeUnnecessaryMessageQueue(const MQMessageQueue& mq); - - virtual int64 computePullFromWhere(const MQMessageQueue& mq); - - virtual bool updateRequestTableInRebalance(const string& topic, vector& mqsSelf); -}; - -// findBrokerResult( + m_clientInstance->findBrokerAddressInSubscribe(mq.getBrokerName(), MASTER_ID, true)); + if (findBrokerResult) { + std::unique_ptr unlockBatchRequest(new UnlockBatchRequestBody()); + unlockBatchRequest->setConsumerGroup(m_consumerGroup); + unlockBatchRequest->setClientId(m_clientInstance->getClientId()); + unlockBatchRequest->getMqSet().push_back(mq); + + try { + m_clientInstance->getMQClientAPIImpl()->unlockBatchMQ(findBrokerResult->brokerAddr, unlockBatchRequest.get(), + 1000); + + ProcessQueuePtr processQueue = getProcessQueue(mq); + if (processQueue) { + processQueue->setLocked(false); + LOG_INFO("the message queue unlock OK, mq:%s", mq.toString().c_str()); + } else { + LOG_ERROR("the message queue unlock Failed, mq:%s", mq.toString().c_str()); + } + } catch (MQException& e) { + LOG_ERROR("unlockBatchMQ exception, mq:%s", mq.toString().c_str()); + } + } else { + LOG_WARN("unlock findBrokerAddressInSubscribe ret null for broker:%s", mq.getBrokerName().data()); + } +} + +void RebalanceImpl::unlockAll(const bool oneway) { + auto brokerMqs = buildProcessQueueTableByBrokerName(); + LOG_INFO("unLockAll " SIZET_FMT " broker mqs", brokerMqs->size()); + + for (const auto& it : *brokerMqs) { + const std::string& brokerName = it.first; + const std::vector& mqs = it.second; + + if (mqs.size() == 0) { + continue; + } + + std::unique_ptr findBrokerResult( + m_clientInstance->findBrokerAddressInSubscribe(brokerName, MASTER_ID, true)); + if (findBrokerResult) { + std::unique_ptr unlockBatchRequest(new UnlockBatchRequestBody()); + unlockBatchRequest->setConsumerGroup(m_consumerGroup); + unlockBatchRequest->setClientId(m_clientInstance->getClientId()); + unlockBatchRequest->setMqSet(mqs); + + try { + m_clientInstance->getMQClientAPIImpl()->unlockBatchMQ(findBrokerResult->brokerAddr, unlockBatchRequest.get(), + 1000); + for (const auto& mq : mqs) { + ProcessQueuePtr processQueue = getProcessQueue(mq); + if (processQueue) { + processQueue->setLocked(false); + LOG_INFO("the message queue unlock OK, mq:%s", mq.toString().c_str()); + } else { + LOG_ERROR("the message queue unlock Failed, mq:%s", mq.toString().c_str()); + } + } + } catch (MQException& e) { + LOG_ERROR("unlockBatchMQ exception"); + } + } else { + LOG_ERROR("unlockAll findBrokerAddressInSubscribe ret null for broker:%s", brokerName.data()); + } + } +} + +std::shared_ptr RebalanceImpl::buildProcessQueueTableByBrokerName() { + std::shared_ptr brokerMqs = std::make_shared(); + MQ2PQ processQueueTable = getProcessQueueTable(); + for (const auto& it : processQueueTable) { + const auto& mq = it.first; + std::string brokerName = mq.getBrokerName(); + if (brokerMqs->find(brokerName) == brokerMqs->end()) { + brokerMqs->emplace(brokerName, std::vector()); + } + (*brokerMqs)[brokerName].push_back(mq); + } + return brokerMqs; +} + +bool RebalanceImpl::lock(MQMessageQueue mq) { + std::unique_ptr findBrokerResult( + m_clientInstance->findBrokerAddressInSubscribe(mq.getBrokerName(), MASTER_ID, true)); + if (findBrokerResult) { + std::unique_ptr lockBatchRequest(new LockBatchRequestBody()); + lockBatchRequest->setConsumerGroup(m_consumerGroup); + lockBatchRequest->setClientId(m_clientInstance->getClientId()); + lockBatchRequest->getMqSet().push_back(mq); + + try { + LOG_DEBUG("try to lock mq:%s", mq.toString().c_str()); + + std::vector lockedMq; + m_clientInstance->getMQClientAPIImpl()->lockBatchMQ(findBrokerResult->brokerAddr, lockBatchRequest.get(), + lockedMq, 1000); + + bool lockOK = false; + if (!lockedMq.empty()) { + for (const auto& mmqq : lockedMq) { + ProcessQueuePtr processQueue = getProcessQueue(mq); + if (processQueue) { + processQueue->setLocked(true); + processQueue->setLastLockTimestamp(UtilAll::currentTimeMillis()); + lockOK = true; + LOG_INFO("the message queue locked OK, mq:%s", mmqq.toString().c_str()); + } else { + LOG_WARN("the message queue locked OK, but it is released, mq:%s", mmqq.toString().c_str()); + } + } + + lockedMq.clear(); + } else { + LOG_ERROR("the message queue locked Failed, mq:%s", mq.toString().c_str()); + } + + return lockOK; + } catch (MQException& e) { + LOG_ERROR("lockBatchMQ exception, mq:%s", mq.toString().c_str()); + } + } else { + LOG_ERROR("lock findBrokerAddressInSubscribe ret null for broker:%s", mq.getBrokerName().data()); + } + + return false; +} + +void RebalanceImpl::lockAll() { + auto brokerMqs = buildProcessQueueTableByBrokerName(); + LOG_INFO("LockAll " SIZET_FMT " broker mqs", brokerMqs->size()); + + for (const auto& it : *brokerMqs) { + const std::string& brokerName = it.first; + const std::vector& mqs = it.second; + + if (mqs.size() == 0) { + continue; + } + + std::unique_ptr findBrokerResult( + m_clientInstance->findBrokerAddressInSubscribe(brokerName, MASTER_ID, true)); + if (findBrokerResult) { + std::unique_ptr lockBatchRequest(new LockBatchRequestBody()); + lockBatchRequest->setConsumerGroup(m_consumerGroup); + lockBatchRequest->setClientId(m_clientInstance->getClientId()); + lockBatchRequest->setMqSet(mqs); + + LOG_INFO("try to lock:" SIZET_FMT " mqs of broker:%s", mqs.size(), brokerName.c_str()); + try { + std::vector lockOKMQVec; + m_clientInstance->getMQClientAPIImpl()->lockBatchMQ(findBrokerResult->brokerAddr, lockBatchRequest.get(), + lockOKMQVec, 1000); + + std::set lockOKMQSet; + for (const auto& mq : lockOKMQVec) { + lockOKMQSet.insert(mq); + + ProcessQueuePtr processQueue = getProcessQueue(mq); + if (processQueue) { + processQueue->setLocked(true); + processQueue->setLastLockTimestamp(UtilAll::currentTimeMillis()); + LOG_INFO("the message queue locked OK, mq:%s", mq.toString().c_str()); + } else { + LOG_WARN("the message queue locked OK, but it is released, mq:%s", mq.toString().c_str()); + } + } + + for (const auto& mq : mqs) { + if (lockOKMQSet.find(mq) == lockOKMQSet.end()) { + ProcessQueuePtr processQueue = getProcessQueue(mq); + if (processQueue) { + LOG_WARN("the message queue locked Failed, mq:%s", mq.toString().c_str()); + processQueue->setLocked(false); + } + } + } + } catch (MQException& e) { + LOG_ERROR("lockBatchMQ fails"); + } + } else { + LOG_ERROR("lockAll findBrokerAddressInSubscribe ret null for broker:%s", brokerName.c_str()); + } + } +} + +void RebalanceImpl::doRebalance(const bool isOrder) throw(MQClientException) { + LOG_DEBUG("start doRebalance"); + for (const auto& it : m_subscriptionInner) { + const std::string& topic = it.first; + LOG_INFO("current topic is:%s", topic.c_str()); + try { + rebalanceByTopic(topic, isOrder); + } catch (MQException& e) { + LOG_ERROR(e.what()); + } + } + + truncateMessageQueueNotMyTopic(); +} + +void RebalanceImpl::rebalanceByTopic(const std::string& topic, const bool isOrder) { + // msg model + switch (m_messageModel) { + case BROADCASTING: { + std::vector mqSet; + if (!getTopicSubscribeInfo(topic, mqSet)) { + bool changed = updateProcessQueueTableInRebalance(topic, mqSet, isOrder); + if (changed) { + messageQueueChanged(topic, mqSet, mqSet); + } + } else { + LOG_WARN("doRebalance, %s, but the topic[%s] not exist.", m_consumerGroup.c_str(), topic.c_str()); + } + } break; + case CLUSTERING: { + std::vector mqAll; + if (!getTopicSubscribeInfo(topic, mqAll)) { + if (!UtilAll::isRetryTopic(topic)) { + LOG_WARN("doRebalance, %s, but the topic[%s] not exist.", m_consumerGroup.c_str(), topic.c_str()); + } + return; + } + + std::vector cidAll; + m_clientInstance->findConsumerIds(topic, m_consumerGroup, cidAll); + + if (cidAll.empty()) { + LOG_WARN("doRebalance, %s %s, get consumer id list failed", m_consumerGroup.c_str(), topic.c_str()); + return; + } + + // log + for (auto& cid : cidAll) { + LOG_INFO("client id:%s of topic:%s", cid.c_str(), topic.c_str()); + } + + // sort + sort(mqAll.begin(), mqAll.end()); + sort(cidAll.begin(), cidAll.end()); + + // allocate mqs + std::vector allocateResult; + try { + m_allocateMQStrategy->allocate(m_clientInstance->getClientId(), mqAll, cidAll, allocateResult); + } catch (MQException& e) { + LOG_ERROR("AllocateMessageQueueStrategy.allocate Exception: %s", e.what()); + return; + } + + // update local + bool changed = updateProcessQueueTableInRebalance(topic, allocateResult, isOrder); + if (changed) { + LOG_INFO("rebalanced result changed. group=%s, topic=%s, clientId=%s, mqAllSize=" SIZET_FMT + ", cidAllSize=" SIZET_FMT ", rebalanceResultSize=" SIZET_FMT ", rebalanceResultSet:", + m_consumerGroup.c_str(), topic.c_str(), m_clientInstance->getClientId().c_str(), mqAll.size(), + cidAll.size(), allocateResult.size()); + for (auto& mq : allocateResult) { + LOG_INFO("allocate mq:%s", mq.toString().c_str()); + } + messageQueueChanged(topic, mqAll, allocateResult); + } + } break; + default: + break; + } +} + +void RebalanceImpl::truncateMessageQueueNotMyTopic() { + auto& subTable = getSubscriptionInner(); + std::vector mqs = getAllocatedMQ(); + for (const auto& mq : mqs) { + if (subTable.find(mq.getTopic()) == subTable.end()) { + auto pq = removeProcessQueueDirectly(mq); + if (pq != nullptr) { + pq->setDropped(true); + LOG_INFO("doRebalance, %s, truncateMessageQueueNotMyTopic remove unnecessary mq, {}", m_consumerGroup.c_str(), + mq.toString().c_str()); + } + } + } +} + +bool RebalanceImpl::updateProcessQueueTableInRebalance(const std::string& topic, + std::vector& mqSet, + const bool isOrder) { + LOG_DEBUG("updateRequestTableInRebalance Enter"); + + bool changed = false; + + // remove + MQ2PQ processQueueTable(getProcessQueueTable()); // get copy of m_processQueueTable + for (const auto& it : processQueueTable) { + const auto& mq = it.first; + auto pq = it.second; + + if (mq.getTopic() == topic) { + if (mqSet.empty() || (find(mqSet.begin(), mqSet.end(), mq) == mqSet.end())) { + pq->setDropped(true); + if (removeUnnecessaryMessageQueue(mq, pq)) { + removeProcessQueueDirectly(mq); + changed = true; + LOG_INFO("doRebalance, %s, remove unnecessary mq, %s", m_consumerGroup.c_str(), mq.toString().c_str()); + } + } else if (pq->isPullExpired()) { + switch (consumeType()) { + case CONSUME_ACTIVELY: + break; + case CONSUME_PASSIVELY: + pq->setDropped(true); + if (removeUnnecessaryMessageQueue(mq, pq)) { + removeProcessQueueDirectly(mq); + changed = true; + LOG_ERROR("[BUG]doRebalance, %s, remove unnecessary mq, %s, because pull is pause, so try to fixed it", + m_consumerGroup.c_str(), mq.toString().c_str()); + } + break; + default: + break; + } + } + } + } + + // update + std::vector pullRequestList; + for (const auto& mq : mqSet) { + ProcessQueuePtr pq = getProcessQueue(mq); + if (nullptr == pq) { + if (isOrder && !lock(mq)) { + LOG_WARN("doRebalance, %s, add a new mq failed, %s, because lock failed", m_consumerGroup.c_str(), + mq.toString().c_str()); + continue; + } + + removeDirtyOffset(mq); + pq.reset(new ProcessQueue()); + int64_t nextOffset = computePullFromWhere(mq); + if (nextOffset >= 0) { + auto pre = putProcessQueueIfAbsent(mq, pq); + if (pre) { + LOG_INFO("doRebalance, %s, mq already exists, %s", m_consumerGroup.c_str(), mq.toString().c_str()); + } else { + LOG_INFO("doRebalance, %s, add a new mq, %s", m_consumerGroup.c_str(), mq.toString().c_str()); + PullRequestPtr pullRequest(new PullRequest()); + pullRequest->setConsumerGroup(m_consumerGroup); + pullRequest->setNextOffset(nextOffset); + pullRequest->setMessageQueue(mq); + pullRequest->setProcessQueue(pq); + pullRequestList.push_back(std::move(pullRequest)); + changed = true; + } + } else { + LOG_WARN("doRebalance, %s, add new mq failed, %s", m_consumerGroup.c_str(), mq.toString().c_str()); + } + } + } + + dispatchPullRequest(pullRequestList); + + LOG_DEBUG("updateRequestTableInRebalance exit"); + return changed; +} + +void RebalanceImpl::removeProcessQueue(const MQMessageQueue& mq) { + std::lock_guard lock(m_processQueueTableMutex); + auto it = m_processQueueTable.find(mq); + if (it != m_processQueueTable.end()) { + ProcessQueuePtr prev = it->second; + m_processQueueTable.erase(it); + + bool dropped = prev->isDropped(); + prev->setDropped(true); + removeUnnecessaryMessageQueue(mq, prev); + LOG_INFO("Fix Offset, {}, remove unnecessary mq, {} Dropped: {}", m_consumerGroup, mq.toString(), + UtilAll::to_string(dropped)); + } +} + +ProcessQueuePtr RebalanceImpl::removeProcessQueueDirectly(const MQMessageQueue& mq) { + std::lock_guard lock(m_processQueueTableMutex); + auto it = m_processQueueTable.find(mq); + if (it != m_processQueueTable.end()) { + ProcessQueuePtr old = it->second; + m_processQueueTable.erase(it); + return old; + } + return ProcessQueuePtr(); +} + +ProcessQueuePtr RebalanceImpl::putProcessQueueIfAbsent(const MQMessageQueue& mq, ProcessQueuePtr pq) { + std::lock_guard lock(m_processQueueTableMutex); + auto it = m_processQueueTable.find(mq); + if (it != m_processQueueTable.end()) { + return it->second; + } else { + m_processQueueTable[mq] = pq; + return ProcessQueuePtr(); + } +} + +ProcessQueuePtr RebalanceImpl::getProcessQueue(const MQMessageQueue& mq) { + std::lock_guard lock(m_processQueueTableMutex); + if (m_processQueueTable.find(mq) != m_processQueueTable.end()) { + return m_processQueueTable[mq]; + } else { + ProcessQueuePtr ptr; + return ptr; + } +} + +MQ2PQ RebalanceImpl::getProcessQueueTable() { + std::lock_guard lock(m_processQueueTableMutex); + return m_processQueueTable; +} + +std::vector RebalanceImpl::getAllocatedMQ() { + std::vector mqs; + std::lock_guard lock(m_processQueueTableMutex); + for (const auto& it : m_processQueueTable) { + mqs.push_back(it.first); + } + return mqs; +} + +void RebalanceImpl::destroy() { + std::lock_guard lock(m_processQueueTableMutex); + for (const auto& it : m_processQueueTable) { + it.second->setDropped(true); + } + + m_processQueueTable.clear(); +} + +TOPIC2SD& RebalanceImpl::getSubscriptionInner() { + return m_subscriptionInner; +} + +SubscriptionDataPtr RebalanceImpl::getSubscriptionData(const std::string& topic) { + auto it = m_subscriptionInner.find(topic); + if (it != m_subscriptionInner.end()) { + return it->second; + } + return nullptr; +} + +void RebalanceImpl::setSubscriptionData(const std::string& topic, SubscriptionDataPtr subscriptionData) noexcept { + if (subscriptionData != nullptr) { + auto it = m_subscriptionInner.find(topic); + if (it != m_subscriptionInner.end()) { + deleteAndZero(it->second); + } + m_subscriptionInner[topic] = subscriptionData; + } +} + +bool RebalanceImpl::getTopicSubscribeInfo(const std::string& topic, std::vector& mqs) { + std::lock_guard lock(m_topicSubscribeInfoTableMutex); + if (m_topicSubscribeInfoTable.find(topic) != m_topicSubscribeInfoTable.end()) { + mqs = m_topicSubscribeInfoTable[topic]; + return true; + } + return false; +} + +void RebalanceImpl::setTopicSubscribeInfo(const std::string& topic, std::vector& mqs) { + if (m_subscriptionInner.find(topic) == m_subscriptionInner.end()) { + return; + } + + { + std::lock_guard lock(m_topicSubscribeInfoTableMutex); + if (m_topicSubscribeInfoTable.find(topic) != m_topicSubscribeInfoTable.end()) + m_topicSubscribeInfoTable.erase(topic); + m_topicSubscribeInfoTable[topic] = mqs; + } + + // log + for (const auto& mq : mqs) { + LOG_DEBUG("topic [%s] has :%s", topic.c_str(), mq.toString().c_str()); + } +} + +} // namespace rocketmq diff --git a/src/consumer/RebalanceImpl.h b/src/consumer/RebalanceImpl.h new file mode 100755 index 000000000..69d2b3d42 --- /dev/null +++ b/src/consumer/RebalanceImpl.h @@ -0,0 +1,113 @@ +/* + * 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 __REBALANCE_IMPL_H__ +#define __REBALANCE_IMPL_H__ + +#include + +#include "AllocateMQStrategy.h" +#include "ConsumeType.h" +#include "MQClientException.h" +#include "MQClientInstance.h" +#include "MQMessageQueue.h" +#include "ProcessQueue.h" +#include "PullRequest.h" +#include "SubscriptionData.h" + +namespace rocketmq { + +typedef std::map MQ2PQ; +typedef std::map> TOPIC2MQS; +typedef std::map TOPIC2SD; +typedef std::map> BROKER2MQS; + +class RebalanceImpl { + public: + RebalanceImpl(const std::string& consumerGroup, + MessageModel messageModel, + AllocateMQStrategy* allocateMqStrategy, + MQClientInstance* mqClientFactory); + virtual ~RebalanceImpl(); + + void unlock(MQMessageQueue mq, const bool oneway = false); + void unlockAll(const bool oneway = false); + + bool lock(MQMessageQueue mq); + void lockAll(); + + void doRebalance(const bool isOrder = false) throw(MQClientException); + + void destroy(); + + public: // RebalanceImpl Interface + virtual ConsumeType consumeType() = 0; + virtual bool removeUnnecessaryMessageQueue(const MQMessageQueue& mq, ProcessQueuePtr pq) = 0; + virtual void removeDirtyOffset(const MQMessageQueue& mq) = 0; + virtual int64_t computePullFromWhere(const MQMessageQueue& mq) = 0; + virtual void dispatchPullRequest(const std::vector& pullRequestList) = 0; + virtual void messageQueueChanged(const std::string& topic, + std::vector& mqAll, + std::vector& mqDivided) = 0; + + private: + std::shared_ptr buildProcessQueueTableByBrokerName(); + + void rebalanceByTopic(const std::string& topic, const bool isOrder); + void truncateMessageQueueNotMyTopic(); + bool updateProcessQueueTableInRebalance(const std::string& topic, + std::vector& mqSet, + const bool isOrder); + + public: + TOPIC2SD& getSubscriptionInner(); + SubscriptionDataPtr getSubscriptionData(const std::string& topic); + void setSubscriptionData(const std::string& topic, SubscriptionDataPtr sd) noexcept; + + bool getTopicSubscribeInfo(const std::string& topic, std::vector& mqs); + void setTopicSubscribeInfo(const std::string& topic, std::vector& mqs); + + void removeProcessQueue(const MQMessageQueue& mq); + ProcessQueuePtr removeProcessQueueDirectly(const MQMessageQueue& mq); + ProcessQueuePtr putProcessQueueIfAbsent(const MQMessageQueue& mq, ProcessQueuePtr pq); + ProcessQueuePtr getProcessQueue(const MQMessageQueue& mq); + MQ2PQ getProcessQueueTable(); + std::vector getAllocatedMQ(); + + public: + void setConsumerGroup(const std::string& groupname) { m_consumerGroup = groupname; } + void setMessageModel(MessageModel messageModel) { m_messageModel = messageModel; } + void setAllocateMQStrategy(AllocateMQStrategy* allocateMqStrategy) { m_allocateMQStrategy = allocateMqStrategy; } + void setMQClientFactory(MQClientInstance* instance) { m_clientInstance = instance; } + + protected: + MQ2PQ m_processQueueTable; + std::mutex m_processQueueTableMutex; + + TOPIC2MQS m_topicSubscribeInfoTable; + std::mutex m_topicSubscribeInfoTableMutex; + + TOPIC2SD m_subscriptionInner; // don't modify m_subscriptionInner after consumer start. + + std::string m_consumerGroup; + MessageModel m_messageModel; + AllocateMQStrategy* m_allocateMQStrategy; + MQClientInstance* m_clientInstance; +}; + +} // namespace rocketmq + +#endif // __REBALANCE_IMPL_H__ diff --git a/src/consumer/RebalancePullImpl.cpp b/src/consumer/RebalancePullImpl.cpp new file mode 100644 index 000000000..15184eaa1 --- /dev/null +++ b/src/consumer/RebalancePullImpl.cpp @@ -0,0 +1,48 @@ +/* + * 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 "RebalancePullImpl.h" + +#include "OffsetStore.h" + +namespace rocketmq { + + +RebalancePullImpl::RebalancePullImpl(DefaultMQPullConsumer* consumer) + : RebalanceImpl("", CLUSTERING, nullptr, nullptr), m_defaultMQPullConsumer(consumer) {} + +bool RebalancePullImpl::removeUnnecessaryMessageQueue(const MQMessageQueue& mq, ProcessQueuePtr pq) { + // m_defaultMQPullConsumer->getOffsetStore()->persist(mq); + // m_defaultMQPullConsumer->getOffsetStore()->removeOffset(mq); + // return true; + return false; +} + +void RebalancePullImpl::removeDirtyOffset(const MQMessageQueue& mq) { + // m_defaultMQPullConsumer->removeConsumeOffset(mq); +} + +int64_t RebalancePullImpl::computePullFromWhere(const MQMessageQueue& mq) { + return 0; +} + +void RebalancePullImpl::dispatchPullRequest(const std::vector& pullRequestList) {} + +void RebalancePullImpl::messageQueueChanged(const std::string& topic, + std::vector& mqAll, + std::vector& mqDivided) {} + +} // namespace rocketmq diff --git a/src/consumer/RebalancePullImpl.h b/src/consumer/RebalancePullImpl.h new file mode 100755 index 000000000..447ce6040 --- /dev/null +++ b/src/consumer/RebalancePullImpl.h @@ -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 __REBALANCE_PULL_IMPL_H__ +#define __REBALANCE_PULL_IMPL_H__ + +#include "DefaultMQPullConsumer.h" +#include "RebalanceImpl.h" + +namespace rocketmq { + +typedef std::map MQ2PQ; +typedef std::map> TOPIC2MQS; +typedef std::map TOPIC2SD; +typedef std::map> BROKER2MQS; + +class RebalancePullImpl : public RebalanceImpl { + public: + RebalancePullImpl(DefaultMQPullConsumer* consumer); + + ConsumeType consumeType() override final { return CONSUME_ACTIVELY; } + + bool removeUnnecessaryMessageQueue(const MQMessageQueue& mq, ProcessQueuePtr pq) override; + + void removeDirtyOffset(const MQMessageQueue& mq) override; + + int64_t computePullFromWhere(const MQMessageQueue& mq) override; + + void dispatchPullRequest(const std::vector& pullRequestList) override; + + void messageQueueChanged(const std::string& topic, + std::vector& mqAll, + std::vector& mqDivided) override; + + private: + DefaultMQPullConsumer* m_defaultMQPullConsumer; +}; + +} // namespace rocketmq + +#endif // __REBALANCE_PULL_IMPL_H__ diff --git a/src/consumer/RebalancePushImpl.cpp b/src/consumer/RebalancePushImpl.cpp new file mode 100644 index 000000000..ef8c1b8c1 --- /dev/null +++ b/src/consumer/RebalancePushImpl.cpp @@ -0,0 +1,152 @@ +/* + * 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 "RebalancePushImpl.h" + +#include "OffsetStore.h" +#include "UtilAll.h" + +namespace rocketmq { + +RebalancePushImpl::RebalancePushImpl(DefaultMQPushConsumerImpl* consumer) + : RebalanceImpl("", CLUSTERING, nullptr, nullptr), m_defaultMQPushConsumer(consumer) {} + +bool RebalancePushImpl::removeUnnecessaryMessageQueue(const MQMessageQueue& mq, ProcessQueuePtr pq) { + auto* pOffsetStore = m_defaultMQPushConsumer->getOffsetStore(); + + pOffsetStore->persist(mq); + pOffsetStore->removeOffset(mq); + + if (m_defaultMQPushConsumer->getMessageListenerType() == messageListenerOrderly && + CLUSTERING == m_defaultMQPushConsumer->messageModel()) { + try { + if (UtilAll::try_lock_for(pq->getLockConsume(), 1000)) { + std::lock_guard lock(pq->getLockConsume(), std::adopt_lock); + // TODO: unlockDelay + unlock(mq); + return true; + } else { + LOG_WARN("[WRONG]mq is consuming, so can not unlock it, %s. maybe hanged for a while, %ld", + mq.toString().c_str(), pq->getTryUnlockTimes()); + + pq->incTryUnlockTimes(); + } + } catch (const std::exception& e) { + LOG_ERROR("removeUnnecessaryMessageQueue Exception: %s", e.what()); + } + + return false; + } + + return true; +} + +void RebalancePushImpl::removeDirtyOffset(const MQMessageQueue& mq) { + m_defaultMQPushConsumer->getOffsetStore()->removeOffset(mq); +} + +int64_t RebalancePushImpl::computePullFromWhere(const MQMessageQueue& mq) { + int64_t result = -1; + ConsumeFromWhere consumeFromWhere = m_defaultMQPushConsumer->getDefaultMQPushConsumerConfig()->getConsumeFromWhere(); + OffsetStore* offsetStore = m_defaultMQPushConsumer->getOffsetStore(); + switch (consumeFromWhere) { + case CONSUME_FROM_LAST_OFFSET: { + int64_t lastOffset = offsetStore->readOffset(mq, READ_FROM_STORE); + if (lastOffset >= 0) { + LOG_INFO_NEW("CONSUME_FROM_LAST_OFFSET, lastOffset of mq:{} is {}", mq.toString(), lastOffset); + result = lastOffset; + } else if (-1 == lastOffset) { + LOG_WARN_NEW("CONSUME_FROM_LAST_OFFSET, lastOffset of mq:%s is -1", mq.toString()); + if (UtilAll::isRetryTopic(mq.getTopic())) { + LOG_INFO_NEW("CONSUME_FROM_LAST_OFFSET, lastOffset of mq:%s is 0", mq.toString()); + result = 0; + } else { + try { + result = m_defaultMQPushConsumer->maxOffset(mq); + LOG_INFO_NEW("CONSUME_FROM_LAST_OFFSET, maxOffset of mq:{} is {}", mq.toString(), result); + } catch (MQException& e) { + LOG_ERROR_NEW("CONSUME_FROM_LAST_OFFSET error, lastOffset of mq:{} is -1", mq.toString()); + result = -1; + } + } + } else { + LOG_ERROR_NEW("CONSUME_FROM_LAST_OFFSET error, lastOffset of mq:{} is -1", mq.toString()); + result = -1; + } + } break; + case CONSUME_FROM_FIRST_OFFSET: { + int64_t lastOffset = offsetStore->readOffset(mq, READ_FROM_STORE); + if (lastOffset >= 0) { + LOG_INFO_NEW("CONSUME_FROM_FIRST_OFFSET, lastOffset of mq:{} is {}", mq.toString(), lastOffset); + result = lastOffset; + } else if (-1 == lastOffset) { + LOG_INFO_NEW("CONSUME_FROM_FIRST_OFFSET, lastOffset of mq:{}, return 0", mq.toString()); + result = 0; + } else { + LOG_INFO_NEW("CONSUME_FROM_FIRST_OFFSET, lastOffset of mq:{}, return -1", mq.toString()); + result = -1; + } + } break; + case CONSUME_FROM_TIMESTAMP: { + int64_t lastOffset = offsetStore->readOffset(mq, READ_FROM_STORE); + if (lastOffset >= 0) { + LOG_INFO_NEW("CONSUME_FROM_TIMESTAMP, lastOffset of mq:{} is {}", mq.toString().c_str(), lastOffset); + result = lastOffset; + } else if (-1 == lastOffset) { + if (UtilAll::isRetryTopic(mq.getTopic())) { + try { + result = m_defaultMQPushConsumer->maxOffset(mq); + LOG_INFO_NEW("CONSUME_FROM_TIMESTAMP, maxOffset of mq:{} is {}", mq.toString(), result); + } catch (MQException& e) { + LOG_ERROR_NEW("CONSUME_FROM_TIMESTAMP error, maxOffset of mq:{} is -1", mq.toString()); + result = -1; + } + } else { + try { + // TODO: parseDate by YYYYMMDDHHMMSS + auto timestamp = + std::stoull(m_defaultMQPushConsumer->getDefaultMQPushConsumerConfig()->getConsumeTimestamp()); + result = m_defaultMQPushConsumer->searchOffset(mq, timestamp); + } catch (MQException& e) { + LOG_ERROR_NEW("CONSUME_FROM_TIMESTAMP error, searchOffset of mq:{}, return 0", mq.toString()); + result = -1; + } + } + } else { + LOG_ERROR_NEW("CONSUME_FROM_TIMESTAMP error, lastOffset of mq:{}, return -1", mq.toString()); + result = -1; + } + } break; + default: + break; + } + return result; +} + +void RebalancePushImpl::dispatchPullRequest(const std::vector& pullRequestList) { + for (const auto& pullRequest : pullRequestList) { + m_defaultMQPushConsumer->executePullRequestImmediately(pullRequest); + LOG_INFO("doRebalance, %s, add a new pull request %s", m_consumerGroup.c_str(), pullRequest->toString().c_str()); + } +} + +void RebalancePushImpl::messageQueueChanged(const std::string& topic, + std::vector& mqAll, + std::vector& mqDivided) { + // TODO: update subscription's version +} + +} // namespace rocketmq diff --git a/src/consumer/RebalancePushImpl.h b/src/consumer/RebalancePushImpl.h new file mode 100644 index 000000000..fdba5a279 --- /dev/null +++ b/src/consumer/RebalancePushImpl.h @@ -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 __REBALANCE_PUSH_IMPL_H__ +#define __REBALANCE_PUSH_IMPL_H__ + +#include "DefaultMQPushConsumerImpl.h" +#include "RebalanceImpl.h" + +namespace rocketmq { + +class RebalancePushImpl : public RebalanceImpl { + public: + RebalancePushImpl(DefaultMQPushConsumerImpl* consumer); + + ConsumeType consumeType() override final { return CONSUME_PASSIVELY; } + + bool removeUnnecessaryMessageQueue(const MQMessageQueue& mq, ProcessQueuePtr pq) override; + + void removeDirtyOffset(const MQMessageQueue& mq) override; + + int64_t computePullFromWhere(const MQMessageQueue& mq) override; + + void dispatchPullRequest(const std::vector& pullRequestList) override; + + void messageQueueChanged(const std::string& topic, + std::vector& mqAll, + std::vector& mqDivided) override; + + private: + DefaultMQPushConsumerImpl* m_defaultMQPushConsumer; +}; + +} // namespace rocketmq + +#endif // __REBALANCE_PUSH_IMPL_H__ diff --git a/src/consumer/RebalanceService.h b/src/consumer/RebalanceService.h new file mode 100644 index 000000000..696335104 --- /dev/null +++ b/src/consumer/RebalanceService.h @@ -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 __REBALANCE_SERVICE_H__ +#define __REBALANCE_SERVICE_H__ + +#include "Logging.h" +#include "MQClientInstance.h" +#include "ServiceThread.h" + +namespace rocketmq { + +class RebalanceService : public ServiceThread { + public: + RebalanceService(MQClientInstance* instance) : m_clientInstance(instance) {} + + void run() override { + LOG_INFO_NEW("{} service started", getServiceName()); + + while (!isStopped()) { + waitForRunning(20000); + m_clientInstance->doRebalance(); + } + + LOG_INFO_NEW("{} service end", getServiceName()); + } + + std::string getServiceName() override { return "RebalanceService"; } + + private: + MQClientInstance* m_clientInstance; +}; + +} // namespace rocketmq + +#endif // __REBALANCE_SERVICE_H__ diff --git a/src/consumer/SubscriptionData.cpp b/src/consumer/SubscriptionData.cpp index 433fce163..455b1cb9a 100644 --- a/src/consumer/SubscriptionData.cpp +++ b/src/consumer/SubscriptionData.cpp @@ -15,18 +15,21 @@ * limitations under the License. */ #include "SubscriptionData.h" + #include #include #include + #include "Logging.h" #include "UtilAll.h" + namespace rocketmq { -//& SubscriptionData::getTagsSet() { +std::vector& SubscriptionData::getTagsSet() { return m_tagSet; } +void SubscriptionData::putCodeSet(const int32 code) { + m_codeSet.push_back(code); +} + bool SubscriptionData::operator==(const SubscriptionData& other) const { + if (!m_topic.compare(other.m_topic)) { + return false; + } if (!m_subString.compare(other.m_subString)) { return false; } @@ -77,54 +87,33 @@ bool SubscriptionData::operator==(const SubscriptionData& other) const { 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; - } + if (ret == 0) { + return m_subString.compare(other.m_subString) < 0; } else { - return false; + return ret < 0; } } -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["topic"] = m_topic; outJson["subString"] = m_subString; outJson["subVersion"] = UtilAll::to_string(m_subVersion); - outJson["topic"] = m_topic; - { - vector::const_iterator it = m_tagSet.begin(); - for (; it != m_tagSet.end(); it++) { - outJson["tagsSet"].append(*it); - } + for (const auto& tag : m_tagSet) { + outJson["tagsSet"].append(tag); } - { - vector::const_iterator it = m_codeSet.begin(); - for (; it != m_codeSet.end(); it++) { - outJson["codeSet"].append(*it); - } + for (const auto& code : m_codeSet) { + outJson["codeSet"].append(code); } + return outJson; } -// -#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* msgs = new vector(); + vector* msgs = new vector(); return (CBatchMessage*)msgs; } @@ -43,17 +36,17 @@ int AddMessage(CBatchMessage* batchMsg, CMessage* msg) { return NULL_POINTER; } MQMessage* message = (MQMessage*)msg; - ((vector*)batchMsg)->push_back(*message); + ((vector*)batchMsg)->push_back(message); return OK; } + int DestroyBatchMessage(CBatchMessage* batchMsg) { if (batchMsg == NULL) { return NULL_POINTER; } - delete (vector*)batchMsg; + for (auto* msg : *(vector*)batchMsg) { + delete msg; + } + delete (vector*)batchMsg; return OK; } - -#ifdef __cplusplus -}; -#endif diff --git a/src/extern/CErrorMessage.cpp b/src/extern/CErrorMessage.cpp index 420fbe261..bb156c9c4 100644 --- a/src/extern/CErrorMessage.cpp +++ b/src/extern/CErrorMessage.cpp @@ -14,14 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "c/CErrorMessage.h" -#include "CErrorMessage.h" -#include "CCommon.h" #include "MQClientErrorContainer.h" #ifdef __cplusplus extern "C" { #endif + using namespace rocketmq; const char* GetLatestErrorMessage() { @@ -29,5 +29,5 @@ const char* GetLatestErrorMessage() { } #ifdef __cplusplus -}; -#endif \ No newline at end of file +} +#endif diff --git a/src/extern/CMessage.cpp b/src/extern/CMessage.cpp index ea3e4f61c..4a28260e9 100644 --- a/src/extern/CMessage.cpp +++ b/src/extern/CMessage.cpp @@ -14,15 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "c/CMessage.h" -#include "CMessage.h" -#include "CCommon.h" #include "MQMessage.h" -#ifdef __cplusplus -extern "C" { -#endif - using namespace rocketmq; CMessage* CreateMessage(const char* topic) { @@ -32,6 +27,7 @@ CMessage* CreateMessage(const char* topic) { } return (CMessage*)mqMessage; } + int DestroyMessage(CMessage* msg) { if (msg == NULL) { return NULL_POINTER; @@ -39,6 +35,7 @@ int DestroyMessage(CMessage* msg) { delete (MQMessage*)msg; return OK; } + int SetMessageTopic(CMessage* msg, const char* topic) { if (msg == NULL) { return NULL_POINTER; @@ -46,6 +43,7 @@ int SetMessageTopic(CMessage* msg, const char* topic) { ((MQMessage*)msg)->setTopic(topic); return OK; } + int SetMessageTags(CMessage* msg, const char* tags) { if (msg == NULL) { return NULL_POINTER; @@ -53,6 +51,7 @@ int SetMessageTags(CMessage* msg, const char* tags) { ((MQMessage*)msg)->setTags(tags); return OK; } + int SetMessageKeys(CMessage* msg, const char* keys) { if (msg == NULL) { return NULL_POINTER; @@ -60,6 +59,7 @@ int SetMessageKeys(CMessage* msg, const char* keys) { ((MQMessage*)msg)->setKeys(keys); return OK; } + int SetMessageBody(CMessage* msg, const char* body) { if (msg == NULL) { return NULL_POINTER; @@ -67,6 +67,7 @@ int SetMessageBody(CMessage* msg, const char* body) { ((MQMessage*)msg)->setBody(body); return OK; } + int SetByteMessageBody(CMessage* msg, const char* body, int len) { if (msg == NULL) { return NULL_POINTER; @@ -74,13 +75,15 @@ int SetByteMessageBody(CMessage* msg, const char* body, int len) { ((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); + ((MQMessage*)msg)->putProperty(key, value); return OK; } + int SetDelayTimeLevel(CMessage* msg, int level) { if (msg == NULL) { return NULL_POINTER; @@ -88,42 +91,3 @@ int SetDelayTimeLevel(CMessage* msg, int level) { ((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 diff --git a/src/extern/CMessageExt.cpp b/src/extern/CMessageExt.cpp index 03a5e2dcd..35dc2812d 100644 --- a/src/extern/CMessageExt.cpp +++ b/src/extern/CMessageExt.cpp @@ -14,45 +14,47 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "c/CMessageExt.h" #include "MQMessageExt.h" -#include "CMessageExt.h" -#include "CCommon.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; @@ -122,6 +124,3 @@ long long GetMessagePreparedTransactionOffset(CMessageExt* msg) { } return ((MQMessageExt*)msg)->getPreparedTransactionOffset(); } -#ifdef __cplusplus -}; -#endif diff --git a/src/extern/CProducer.cpp b/src/extern/CProducer.cpp index 397d77235..3a4029f40 100644 --- a/src/extern/CProducer.cpp +++ b/src/extern/CProducer.cpp @@ -14,98 +14,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "c/CProducer.h" -#include "CProducer.h" -#include +#include #include #include -#include -#include "AsyncCallback.h" -#include "CBatchMessage.h" -#include "CCommon.h" -#include "CMQException.h" -#include "CMessage.h" -#include "CSendResult.h" + +#include "ClientRPCHook.h" #include "DefaultMQProducer.h" +#include "Logging.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 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; - } - CMessage* msg = (CMessage*)(&message); - CTransactionStatus status = m_ExcutorCallback(m_producer, msg, arg); - 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; - CLocalTransactionExecutorCallback m_ExcutorCallback; - - CProducer* m_producer; - void* m_data; - - public: - void setM_m_ExcutorCallback(CLocalTransactionExecutorCallback excutorcallback) { - m_ExcutorCallback = excutorcallback; - } -}; class SelectMessageQueueInner : public MessageQueueSelector { public: MQMessageQueue select(const std::vector& mqs, const MQMessage& msg, void* arg) { int index = 0; - std::string shardingKey = rocketmq::UtilAll::to_string((char*)arg); + std::string shardingKey = UtilAll::to_string((char*)arg); index = std::hash{}(shardingKey) % mqs.size(); return mqs[index % mqs.size()]; @@ -126,7 +53,8 @@ class SelectMessageQueue : public MessageQueueSelector { private: QueueSelectorCallback m_pCallback; }; -class COnSendCallback : public AutoDeleteSendCallBack { + +class COnSendCallback : public AutoDeleteSendCallback { public: COnSendCallback(COnSendSuccessCallback cSendSuccessCallback, COnSendExceptionCallback cSendExceptionCallback, @@ -138,9 +66,9 @@ class COnSendCallback : public AutoDeleteSendCallBack { m_userData = userData; } - virtual ~COnSendCallback() {} + virtual ~COnSendCallback() = default; - virtual void onSuccess(SendResult& sendResult) { + void onSuccess(SendResult& sendResult) override { CSendResult result; result.sendStatus = CSendStatus((int)sendResult.getSendStatus()); result.offset = sendResult.getQueueOffset(); @@ -149,7 +77,7 @@ class COnSendCallback : public AutoDeleteSendCallBack { m_cSendSuccessCallback(result, (CMessage*)m_message, m_userData); } - virtual void onException(MQException& e) { + void onException(MQException& e) noexcept override { CMQException exception; exception.error = e.GetError(); exception.line = e.GetLine(); @@ -165,16 +93,16 @@ class COnSendCallback : public AutoDeleteSendCallBack { void* m_userData; }; -class CSendCallback : public AutoDeleteSendCallBack { +class CSendCallback : public AutoDeleteSendCallback { public: CSendCallback(CSendSuccessCallback cSendSuccessCallback, CSendExceptionCallback cSendExceptionCallback) { m_cSendSuccessCallback = cSendSuccessCallback; m_cSendExceptionCallback = cSendExceptionCallback; } - virtual ~CSendCallback() {} + virtual ~CSendCallback() = default; - virtual void onSuccess(SendResult& sendResult) { + void onSuccess(SendResult& sendResult) override { CSendResult result; result.sendStatus = CSendStatus((int)sendResult.getSendStatus()); result.offset = sendResult.getQueueOffset(); @@ -183,7 +111,7 @@ class CSendCallback : public AutoDeleteSendCallBack { m_cSendSuccessCallback(result); } - virtual void onException(MQException& e) { + void onException(MQException& e) noexcept override { CMQException exception; exception.error = e.GetError(); exception.line = e.GetLine(); @@ -196,160 +124,74 @@ class CSendCallback : public AutoDeleteSendCallBack { 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; -} 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->innerTransactionProducer = NULL; - defaultMQProducer->listenerInner = NULL; + auto* defaultMQProducer = new DefaultMQProducer(groupId); 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->innerTransactionProducer = NULL; - defaultMQProducer->listenerInner = NULL; - return (CProducer*)defaultMQProducer; + return CreateProducer(groupId); } -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); - return (CProducer*)defaultMQProducer; -} -int DestroyProducer(CProducer* pProducer) { - if (pProducer == NULL) { +int DestroyProducer(CProducer* producer) { + if (producer == nullptr) { return NULL_POINTER; } - DefaultProducer* defaultMQProducer = (DefaultProducer*)pProducer; - if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) { - if (defaultMQProducer->innerTransactionProducer != NULL) { - delete defaultMQProducer->innerTransactionProducer; - defaultMQProducer->innerTransactionProducer = NULL; - } - if (defaultMQProducer->listenerInner != NULL) { - delete defaultMQProducer->listenerInner; - defaultMQProducer->listenerInner = NULL; - } - } else { - if (defaultMQProducer->innerProducer != NULL) { - delete defaultMQProducer->innerProducer; - defaultMQProducer->innerProducer = NULL; - } - } - delete reinterpret_cast(pProducer); + delete reinterpret_cast(producer); 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())); + reinterpret_cast(producer)->start(); + } catch (std::exception& e) { + MQClientErrorContainer::setErr(std::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; - } + reinterpret_cast(producer)->shutdown(); return OK; } + 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; - } + reinterpret_cast(producer)->setNamesrvAddr(namesrv); return OK; } + +// Deprecated 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; - } + // reinterpret_cast(producer)->setNamesrvDomain(domain); 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; + DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)producer; MQMessage* message = (MQMessage*)msg; - SendResult sendResult = defaultMQProducer->innerProducer->send(*message); + SendResult sendResult = defaultMQProducer->send(message); switch (sendResult.getSendStatus()) { case SEND_OK: result->sendStatus = E_SEND_OK; @@ -370,8 +212,8 @@ int SendMessageSync(CProducer* producer, CMessage* msg, CSendResult* result) { 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())); + } catch (std::exception& e) { + MQClientErrorContainer::setErr(std::string(e.what())); return PRODUCER_SEND_SYNC_FAILED; } return OK; @@ -383,9 +225,9 @@ int SendBatchMessage(CProducer* producer, CBatchMessage* batcMsg, CSendResult* r return NULL_POINTER; } try { - DefaultProducer* defaultMQProducer = (DefaultProducer*)producer; - vector* message = (vector*)batcMsg; - SendResult sendResult = defaultMQProducer->innerProducer->send(*message); + DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)producer; + std::vector* message = (std::vector*)batcMsg; + SendResult sendResult = defaultMQProducer->send(*message); switch (sendResult.getSendStatus()) { case SEND_OK: result->sendStatus = E_SEND_OK; @@ -406,7 +248,7 @@ int SendBatchMessage(CProducer* producer, CBatchMessage* batcMsg, CSendResult* r 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) { + } catch (std::exception& e) { return PRODUCER_SEND_SYNC_FAILED; } return OK; @@ -419,24 +261,10 @@ int SendMessageAsync(CProducer* producer, if (producer == NULL || msg == NULL || cSendSuccessCallback == NULL || cSendExceptionCallback == NULL) { return NULL_POINTER; } - DefaultProducer* defaultMQProducer = (DefaultProducer*)producer; + DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)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; - } + defaultMQProducer->send(message, cSendCallback); return OK; } @@ -448,24 +276,10 @@ int SendAsync(CProducer* producer, if (producer == NULL || msg == NULL || onSuccess == NULL || onException == NULL) { return NULL_POINTER; } - DefaultProducer* defaultMQProducer = (DefaultProducer*)producer; + DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)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; - } + defaultMQProducer->send(message, cSendCallback); return OK; } @@ -473,11 +287,11 @@ int SendMessageOneway(CProducer* producer, CMessage* msg) { if (producer == NULL || msg == NULL) { return NULL_POINTER; } - DefaultProducer* defaultMQProducer = (DefaultProducer*)producer; + DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)producer; MQMessage* message = (MQMessage*)msg; try { - defaultMQProducer->innerProducer->sendOneway(*message); - } catch (exception& e) { + defaultMQProducer->sendOneway(message); + } catch (std::exception& e) { return PRODUCER_SEND_ONEWAY_FAILED; } return OK; @@ -487,13 +301,13 @@ int SendMessageOnewayOrderly(CProducer* producer, CMessage* msg, QueueSelectorCa if (producer == NULL || msg == NULL) { return NULL_POINTER; } - DefaultProducer* defaultMQProducer = (DefaultProducer*)producer; + DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)producer; MQMessage* message = (MQMessage*)msg; try { SelectMessageQueue selectMessageQueue(selector); - defaultMQProducer->innerProducer->sendOneway(*message, &selectMessageQueue, arg); - } catch (exception& e) { - MQClientErrorContainer::setErr(string(e.what())); + defaultMQProducer->sendOneway(message, &selectMessageQueue, arg); + } catch (std::exception& e) { + MQClientErrorContainer::setErr(std::string(e.what())); return PRODUCER_SEND_ONEWAY_FAILED; } return OK; @@ -509,20 +323,12 @@ int SendMessageOrderlyAsync(CProducer* producer, cSendExceptionCallback == NULL) { return NULL_POINTER; } - DefaultProducer* defaultMQProducer = (DefaultProducer*)producer; + DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)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<send(message, &selectMessageQueue, arg, cSendCallback); return OK; } @@ -535,104 +341,63 @@ int SendMessageOrderly(CProducer* producer, if (producer == NULL || msg == NULL || callback == NULL || arg == NULL || result == NULL) { return NULL_POINTER; } - DefaultProducer* defaultMQProducer = (DefaultProducer*)producer; + DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)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); + SendResult sendResult = defaultMQProducer->send(message, &selectMessageQueue, arg); // 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())); + } catch (std::exception& e) { + MQClientErrorContainer::setErr(std::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; + DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)producer; MQMessage* message = (MQMessage*)msg; try { // Constructing SelectMessageQueue objects through function pointer callback int retryTimes = 3; SelectMessageQueueInner selectMessageQueue; - SendResult sendResult = - defaultMQProducer->innerProducer->send(*message, &selectMessageQueue, (void*)shardingKey, retryTimes); + SendResult sendResult = defaultMQProducer->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())); + } catch (std::exception& e) { + MQClientErrorContainer::setErr(std::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; - defaultMQProducer->listenerInner->setM_m_ExcutorCallback(callback); - SendResult sendResult = defaultMQProducer->innerTransactionProducer->sendMessageInTransaction(*message, userData); - 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; - } + reinterpret_cast(producer)->setGroupName(groupName); 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; - } + reinterpret_cast(producer)->setInstanceName(instanceName); return OK; } + int SetProducerSessionCredentials(CProducer* producer, const char* accessKey, const char* secretKey, @@ -640,23 +405,17 @@ int SetProducerSessionCredentials(CProducer* producer, 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; - } + auto rpcHook = std::make_shared(SessionCredentials(accessKey, secretKey, onsChannel)); + reinterpret_cast(producer)->setRPCHook(rpcHook); return OK; } + int SetProducerLogPath(CProducer* producer, const char* logPath) { if (producer == NULL) { return NULL_POINTER; } + // Todo, This api should be implemented by core api. + // reinterpret_cast(producer)->setLogFileSizeAndNum(3, 102400000); return OK; } @@ -664,17 +423,7 @@ 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; - } + ALOG_ADAPTER->setLogFileNumAndSize(fileNum, fileSize); return OK; } @@ -682,17 +431,7 @@ 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; - } + ALOG_ADAPTER->setLogLevel((elogLevel)level); return OK; } @@ -700,17 +439,7 @@ 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; - } + reinterpret_cast(producer)->setSendMsgTimeout(timeout); return OK; } @@ -718,17 +447,7 @@ 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; - } + reinterpret_cast(producer)->setCompressMsgBodyOverHowmuch(howmuch); return OK; } @@ -736,17 +455,7 @@ 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; - } + reinterpret_cast(producer)->setCompressLevel(level); return OK; } @@ -754,19 +463,6 @@ 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; - } + reinterpret_cast(producer)->setMaxMessageSize(size); return OK; } -#ifdef __cplusplus -}; -#endif diff --git a/src/extern/CPullConsumer.cpp b/src/extern/CPullConsumer.cpp index f84a4bcbf..497b8960b 100644 --- a/src/extern/CPullConsumer.cpp +++ b/src/extern/CPullConsumer.cpp @@ -14,19 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "c/CPullConsumer.h" -#include "CPullConsumer.h" -#include "CCommon.h" -#include "CMessageExt.h" +#include + +#include "ClientRPCHook.h" #include "DefaultMQPullConsumer.h" +#include "Logging.h" #include "MQClientErrorContainer.h" using namespace rocketmq; -using namespace std; - -#ifdef __cplusplus -extern "C" { -#endif CPullConsumer* CreatePullConsumer(const char* groupId) { if (groupId == NULL) { @@ -35,6 +32,7 @@ CPullConsumer* CreatePullConsumer(const char* groupId) { DefaultMQPullConsumer* defaultMQPullConsumer = new DefaultMQPullConsumer(groupId); return (CPullConsumer*)defaultMQPullConsumer; } + int DestroyPullConsumer(CPullConsumer* consumer) { if (consumer == NULL) { return NULL_POINTER; @@ -42,52 +40,59 @@ int DestroyPullConsumer(CPullConsumer* consumer) { delete reinterpret_cast(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())); + reinterpret_cast(consumer)->start(); + } catch (std::exception& e) { + MQClientErrorContainer::setErr(std::string(e.what())); return PULLCONSUMER_START_FAILED; } return OK; } + int ShutdownPullConsumer(CPullConsumer* consumer) { if (consumer == NULL) { return NULL_POINTER; } - ((DefaultMQPullConsumer*)consumer)->shutdown(); + reinterpret_cast(consumer)->shutdown(); return OK; } + int SetPullConsumerGroupID(CPullConsumer* consumer, const char* groupId) { if (consumer == NULL || groupId == NULL) { return NULL_POINTER; } - ((DefaultMQPullConsumer*)consumer)->setGroupName(groupId); + reinterpret_cast(consumer)->setGroupName(groupId); return OK; } + const char* GetPullConsumerGroupID(CPullConsumer* consumer) { if (consumer == NULL) { return NULL; } - return ((DefaultMQPullConsumer*)consumer)->getGroupName().c_str(); + return reinterpret_cast(consumer)->getGroupName().c_str(); } + int SetPullConsumerNameServerAddress(CPullConsumer* consumer, const char* namesrv) { if (consumer == NULL) { return NULL_POINTER; } - ((DefaultMQPullConsumer*)consumer)->setNamesrvAddr(namesrv); + reinterpret_cast(consumer)->setNamesrvAddr(namesrv); return OK; } + +// Deprecated int SetPullConsumerNameServerDomain(CPullConsumer* consumer, const char* domain) { if (consumer == NULL) { return NULL_POINTER; } - ((DefaultMQPullConsumer*)consumer)->setNamesrvDomain(domain); - return OK; + return NOT_SUPPORT_NOW; } + int SetPullConsumerSessionCredentials(CPullConsumer* consumer, const char* accessKey, const char* secretKey, @@ -95,7 +100,8 @@ int SetPullConsumerSessionCredentials(CPullConsumer* consumer, if (consumer == NULL) { return NULL_POINTER; } - ((DefaultMQPullConsumer*)consumer)->setSessionCredentials(accessKey, secretKey, channel); + auto rpcHook = std::make_shared(SessionCredentials(accessKey, secretKey, channel)); + reinterpret_cast(consumer)->setRPCHook(rpcHook); return OK; } @@ -112,7 +118,7 @@ int SetPullConsumerLogFileNumAndSize(CPullConsumer* consumer, int fileNum, long if (consumer == NULL) { return NULL_POINTER; } - ((DefaultMQPullConsumer*)consumer)->setLogFileSizeAndNum(fileNum, fileSize); + ALOG_ADAPTER->setLogFileNumAndSize(fileNum, fileSize); return OK; } @@ -120,7 +126,7 @@ int SetPullConsumerLogLevel(CPullConsumer* consumer, CLogLevel level) { if (consumer == NULL) { return NULL_POINTER; } - ((DefaultMQPullConsumer*)consumer)->setLogLevel((elogLevel)level); + ALOG_ADAPTER->setLogLevel((elogLevel)level); return OK; } @@ -132,7 +138,7 @@ int FetchSubscriptionMessageQueues(CPullConsumer* consumer, const char* topic, C CMessageQueue* temMQ = NULL; std::vector fullMQ; try { - ((DefaultMQPullConsumer*)consumer)->fetchSubscribeMessageQueues(topic, fullMQ); + reinterpret_cast(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. @@ -152,11 +158,12 @@ int FetchSubscriptionMessageQueues(CPullConsumer* consumer, const char* topic, C } catch (MQException& e) { *size = 0; *mqs = NULL; - MQClientErrorContainer::setErr(string(e.what())); + MQClientErrorContainer::setErr(std::string(e.what())); return PULLCONSUMER_FETCH_MQ_FAILED; } return OK; } + int ReleaseSubscriptionMessageQueue(CMessageQueue* mqs) { if (mqs == NULL) { return NULL_POINTER; @@ -165,6 +172,7 @@ int ReleaseSubscriptionMessageQueue(CMessageQueue* mqs) { mqs = NULL; return OK; } + CPullResult Pull(CPullConsumer* consumer, const CMessageQueue* mq, const char* subExpression, @@ -172,16 +180,13 @@ CPullResult Pull(CPullConsumer* consumer, 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 = + reinterpret_cast(consumer)->pull(messageQueue, subExpression, offset, maxNums); + } catch (std::exception& e) { + MQClientErrorContainer::setErr(std::string(e.what())); cppPullResult.pullStatus = BROKER_TIMEOUT; } @@ -201,7 +206,7 @@ CPullResult Pull(CPullConsumer* consumer, // 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(&tmpPullResult->msgFoundList[i]); + MQMessageExt* msg = tmpPullResult->msgFoundList[i].get(); pullResult.msgFoundList[i] = (CMessageExt*)(msg); } break; @@ -228,6 +233,7 @@ CPullResult Pull(CPullConsumer* consumer, } return pullResult; } + int ReleasePullResult(CPullResult pullResult) { if (pullResult.size == 0 || pullResult.msgFoundList == NULL || pullResult.pData == NULL) { return NULL_POINTER; @@ -235,8 +241,8 @@ int ReleasePullResult(CPullResult pullResult) { if (pullResult.pData != NULL) { try { delete ((PullResult*)pullResult.pData); - } catch (exception& e) { - MQClientErrorContainer::setErr(string(e.what())); + } catch (std::exception& e) { + MQClientErrorContainer::setErr(std::string(e.what())); return NULL_POINTER; } } @@ -244,7 +250,3 @@ int ReleasePullResult(CPullResult pullResult) { pullResult.msgFoundList = NULL; return OK; } - -#ifdef __cplusplus -}; -#endif diff --git a/src/extern/CPushConsumer.cpp b/src/extern/CPushConsumer.cpp index 66ef93757..add5ef323 100644 --- a/src/extern/CPushConsumer.cpp +++ b/src/extern/CPushConsumer.cpp @@ -14,16 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "c/CPushConsumer.h" -#include "CPushConsumer.h" #include -#include "CCommon.h" -#include "CMessageExt.h" + +#include "ClientRPCHook.h" #include "DefaultMQPushConsumer.h" +#include "Logging.h" #include "MQClientErrorContainer.h" using namespace rocketmq; -using namespace std; class MessageListenerInner : public MessageListenerConcurrently { public: @@ -36,16 +36,16 @@ class MessageListenerInner : public MessageListenerConcurrently { ~MessageListenerInner() {} - ConsumeStatus consumeMessage(const std::vector& msgs) { + ConsumeStatus consumeMessage(const std::vector& msgs) { // to do user call back - if (m_pMsgReceiveCallback == NULL) { + if (m_pMsgReceiveCallback == nullptr) { return RECONSUME_LATER; } for (size_t i = 0; i < msgs.size(); ++i) { - MQMessageExt* msg = const_cast(&msgs[i]); - CMessageExt* message = (CMessageExt*)(msg); - if (m_pMsgReceiveCallback(m_pconsumer, message) != E_CONSUME_SUCCESS) + CMessageExt* message = (CMessageExt*)msgs[i]; + if (m_pMsgReceiveCallback(m_pconsumer, message) != E_CONSUME_SUCCESS) { return RECONSUME_LATER; + } } return CONSUME_SUCCESS; } @@ -62,15 +62,15 @@ class MessageListenerOrderlyInner : public MessageListenerOrderly { m_pMsgReceiveCallback = pCallback; } - ConsumeStatus consumeMessage(const std::vector& msgs) { - if (m_pMsgReceiveCallback == NULL) { + ConsumeStatus consumeMessage(const std::vector& msgs) { + if (m_pMsgReceiveCallback == nullptr) { return RECONSUME_LATER; } for (size_t i = 0; i < msgs.size(); ++i) { - MQMessageExt* msg = const_cast(&msgs[i]); - CMessageExt* message = (CMessageExt*)(msg); - if (m_pMsgReceiveCallback(m_pconsumer, message) != E_CONSUME_SUCCESS) + CMessageExt* message = (CMessageExt*)msgs[i]; + if (m_pMsgReceiveCallback(m_pconsumer, message) != E_CONSUME_SUCCESS) { return RECONSUME_LATER; + } } return CONSUME_SUCCESS; } @@ -80,20 +80,18 @@ class MessageListenerOrderlyInner : public MessageListenerOrderly { CPushConsumer* m_pconsumer; }; -map g_ListenerMap; -map g_OrderListenerMap; -#ifdef __cplusplus -extern "C" { -#endif +std::map g_ListenerMap; +std::map g_OrderListenerMap; CPushConsumer* CreatePushConsumer(const char* groupId) { if (groupId == NULL) { return NULL; } - DefaultMQPushConsumer* defaultMQPushConsumer = new DefaultMQPushConsumer(groupId); + auto* defaultMQPushConsumer = new DefaultMQPushConsumer(groupId); defaultMQPushConsumer->setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET); - return (CPushConsumer*)defaultMQPushConsumer; + return reinterpret_cast(defaultMQPushConsumer); } + int DestroyPushConsumer(CPushConsumer* consumer) { if (consumer == NULL) { return NULL_POINTER; @@ -101,57 +99,64 @@ int DestroyPushConsumer(CPushConsumer* consumer) { delete reinterpret_cast(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())); + reinterpret_cast(consumer)->start(); + } catch (std::exception& e) { + MQClientErrorContainer::setErr(std::string(e.what())); return PUSHCONSUMER_START_FAILED; } return OK; } + int ShutdownPushConsumer(CPushConsumer* consumer) { if (consumer == NULL) { return NULL_POINTER; } - ((DefaultMQPushConsumer*)consumer)->shutdown(); + reinterpret_cast(consumer)->shutdown(); return OK; } + int SetPushConsumerGroupID(CPushConsumer* consumer, const char* groupId) { if (consumer == NULL || groupId == NULL) { return NULL_POINTER; } - ((DefaultMQPushConsumer*)consumer)->setGroupName(groupId); + reinterpret_cast(consumer)->setGroupName(groupId); return OK; } + const char* GetPushConsumerGroupID(CPushConsumer* consumer) { if (consumer == NULL) { return NULL; } - return ((DefaultMQPushConsumer*)consumer)->getGroupName().c_str(); + return reinterpret_cast(consumer)->getGroupName().c_str(); } + int SetPushConsumerNameServerAddress(CPushConsumer* consumer, const char* namesrv) { if (consumer == NULL) { return NULL_POINTER; } - ((DefaultMQPushConsumer*)consumer)->setNamesrvAddr(namesrv); + reinterpret_cast(consumer)->setNamesrvAddr(namesrv); return OK; } + +// Deprecated int SetPushConsumerNameServerDomain(CPushConsumer* consumer, const char* domain) { if (consumer == NULL) { return NULL_POINTER; } - ((DefaultMQPushConsumer*)consumer)->setNamesrvDomain(domain); - return OK; + return NOT_SUPPORT_NOW; } + int Subscribe(CPushConsumer* consumer, const char* topic, const char* expression) { if (consumer == NULL) { return NULL_POINTER; } - ((DefaultMQPushConsumer*)consumer)->subscribe(topic, expression); + reinterpret_cast(consumer)->subscribe(topic, expression); return OK; } @@ -160,7 +165,7 @@ int RegisterMessageCallback(CPushConsumer* consumer, MessageCallBack pCallback) return NULL_POINTER; } MessageListenerInner* listenerInner = new MessageListenerInner(consumer, pCallback); - ((DefaultMQPushConsumer*)consumer)->registerMessageListener(listenerInner); + reinterpret_cast(consumer)->registerMessageListener(listenerInner); g_ListenerMap[consumer] = listenerInner; return OK; } @@ -170,7 +175,7 @@ int RegisterMessageCallbackOrderly(CPushConsumer* consumer, MessageCallBack pCal return NULL_POINTER; } MessageListenerOrderlyInner* messageListenerOrderlyInner = new MessageListenerOrderlyInner(consumer, pCallback); - ((DefaultMQPushConsumer*)consumer)->registerMessageListener(messageListenerOrderlyInner); + reinterpret_cast(consumer)->registerMessageListener(messageListenerOrderlyInner); g_OrderListenerMap[consumer] = messageListenerOrderlyInner; return OK; } @@ -179,7 +184,7 @@ int UnregisterMessageCallbackOrderly(CPushConsumer* consumer) { if (consumer == NULL) { return NULL_POINTER; } - map::iterator iter; + std::map::iterator iter; iter = g_OrderListenerMap.find(consumer); if (iter != g_OrderListenerMap.end()) { MessageListenerOrderlyInner* listenerInner = iter->second; @@ -195,7 +200,7 @@ int UnregisterMessageCallback(CPushConsumer* consumer) { if (consumer == NULL) { return NULL_POINTER; } - map::iterator iter; + std::map::iterator iter; iter = g_ListenerMap.find(consumer); if (iter != g_ListenerMap.end()) { @@ -212,28 +217,31 @@ int SetPushConsumerMessageModel(CPushConsumer* consumer, CMessageModel messageMo if (consumer == NULL) { return NULL_POINTER; } - ((DefaultMQPushConsumer*)consumer)->setMessageModel(MessageModel((int)messageModel)); + reinterpret_cast(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); + reinterpret_cast(consumer)->setConsumeThreadNum(threadCount); return OK; } + int SetPushConsumerMessageBatchMaxSize(CPushConsumer* consumer, int batchSize) { if (consumer == NULL || batchSize == 0) { return NULL_POINTER; } - ((DefaultMQPushConsumer*)consumer)->setConsumeMessageBatchMaxSize(batchSize); + reinterpret_cast(consumer)->setConsumeMessageBatchMaxSize(batchSize); return OK; } + int SetPushConsumerMaxCacheMessageSize(CPushConsumer* consumer, int maxCacheSize) { if (consumer == NULL || maxCacheSize <= 0) { return NULL_POINTER; } - ((DefaultMQPushConsumer*)consumer)->setMaxCacheMsgSizePerQueue(maxCacheSize); + reinterpret_cast(consumer)->setMaxCacheMsgSizePerQueue(maxCacheSize); return OK; } @@ -241,13 +249,13 @@ int SetPushConsumerMaxCacheMessageSizeInMb(CPushConsumer* consumer, int maxCache if (consumer == NULL || maxCacheSizeInMb <= 0) { return NULL_POINTER; } - return Not_Support; + return NOT_SUPPORT_NOW; } int SetPushConsumerInstanceName(CPushConsumer* consumer, const char* instanceName) { if (consumer == NULL) { return NULL_POINTER; } - ((DefaultMQPushConsumer*)consumer)->setInstanceName(instanceName); + reinterpret_cast(consumer)->setInstanceName(instanceName); return OK; } @@ -258,7 +266,8 @@ int SetPushConsumerSessionCredentials(CPushConsumer* consumer, if (consumer == NULL) { return NULL_POINTER; } - ((DefaultMQPushConsumer*)consumer)->setSessionCredentials(accessKey, secretKey, channel); + auto rpcHook = std::make_shared(SessionCredentials(accessKey, secretKey, channel)); + reinterpret_cast(consumer)->setRPCHook(rpcHook); return OK; } @@ -267,7 +276,7 @@ int SetPushConsumerLogPath(CPushConsumer* consumer, const char* logPath) { return NULL_POINTER; } // Todo, This api should be implemented by core api. - //((DefaultMQPushConsumer *) consumer)->setInstanceName(instanceName); + // reinterpret_cast(consumer)->setInstanceName(instanceName); return OK; } @@ -275,7 +284,7 @@ int SetPushConsumerLogFileNumAndSize(CPushConsumer* consumer, int fileNum, long if (consumer == NULL) { return NULL_POINTER; } - ((DefaultMQPushConsumer*)consumer)->setLogFileSizeAndNum(fileNum, fileSize); + ALOG_ADAPTER->setLogFileNumAndSize(fileNum, fileSize); return OK; } @@ -283,10 +292,6 @@ int SetPushConsumerLogLevel(CPushConsumer* consumer, CLogLevel level) { if (consumer == NULL) { return NULL_POINTER; } - ((DefaultMQPushConsumer*)consumer)->setLogLevel((elogLevel)level); + ALOG_ADAPTER->setLogLevel((elogLevel)level); return OK; } - -#ifdef __cplusplus -}; -#endif diff --git a/src/extern/CSendResult.cpp b/src/extern/CSendResult.cpp index c43464a95..2a1b76954 100644 --- a/src/extern/CSendResult.cpp +++ b/src/extern/CSendResult.cpp @@ -14,13 +14,4 @@ * 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 +#include "c/CSendResult.h" diff --git a/src/common/MQClientErrorContainer.cpp b/src/extern/MQClientErrorContainer.cpp similarity index 100% rename from src/common/MQClientErrorContainer.cpp rename to src/extern/MQClientErrorContainer.cpp diff --git a/src/common/MQClientErrorContainer.h b/src/extern/MQClientErrorContainer.h similarity index 98% rename from src/common/MQClientErrorContainer.h rename to src/extern/MQClientErrorContainer.h index 3e09f0a71..1b3ff6ce4 100644 --- a/src/common/MQClientErrorContainer.h +++ b/src/extern/MQClientErrorContainer.h @@ -17,7 +17,6 @@ #ifndef __MQ_CLIENT_ERROR_CONTAINER_H__ #define __MQ_CLIENT_ERROR_CONTAINER_H__ -#include #include namespace rocketmq { diff --git a/src/log/Logging.cpp b/src/log/Logging.cpp index 9ecd1d86c..b7bd051cf 100644 --- a/src/log/Logging.cpp +++ b/src/log/Logging.cpp @@ -15,81 +15,108 @@ * limitations under the License. */ #include "Logging.h" -#include + +#include + +#if SPDLOG_VER_MAJOR >= 1 +#include +#include +#else +#include +#endif + #include "UtilAll.h" -#define BOOST_DATE_TIME_SOURCE namespace rocketmq { -logAdapter* logAdapter::alogInstance; -boost::mutex logAdapter::m_imtx; logAdapter::~logAdapter() { - logging::core::get()->remove_all_sinks(); + spdlog::drop("default"); } logAdapter* logAdapter::getLogInstance() { - if (alogInstance == NULL) { - boost::mutex::scoped_lock guard(m_imtx); - if (alogInstance == NULL) { - alogInstance = new logAdapter(); - } - } - return alogInstance; + static logAdapter singleton_; + return &singleton_; } logAdapter::logAdapter() : m_logLevel(eLOG_LEVEL_INFO) { - string homeDir(UtilAll::getHomeDirectory()); - homeDir.append("/logs/rocketmq-cpp/"); - m_logFile += homeDir; - std::string fileName = UtilAll::to_string(getpid()) + "_" + "rocketmq-cpp.log.%N"; - m_logFile += fileName; - - // boost::log::expressions::attr< - // boost::log::attributes::current_thread_id::value_type>("ThreadID"); - boost::log::register_simple_formatter_factory("Severity"); - m_logSink = logging::add_file_log(keywords::file_name = m_logFile, keywords::rotation_size = 100 * 1024 * 1024, - keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0), - keywords::format = "[%TimeStamp%](%Severity%):%Message%", - keywords::min_free_space = 300 * 1024 * 1024, keywords::target = homeDir, - keywords::max_size = 200 * 1024 * 1024, // max keep 3 log file defaultly - keywords::auto_flush = true); - // logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::info); - setLogLevelInner(m_logLevel); + std::string logDir; + const char* dir = std::getenv(ROCKETMQ_CPP_LOG_DIR_ENV.c_str()); + if (dir != nullptr && dir[0] != '\0') { + // FIXME: replace '~' by home directory. + logDir = dir; + } else { + logDir = UtilAll::getHomeDirectory(); + logDir.append("/logs/rocketmq-cpp/"); + } + if (logDir[logDir.size() - 1] != '/') { + logDir.append("/"); + } + + if (!UtilAll::existDirectory(logDir)) { + UtilAll::createDirectory(logDir); + } + if (!UtilAll::existDirectory(logDir)) { + std::cerr << "create log dir error, will exit" << std::endl; + exit(1); + } + + std::string fileName = UtilAll::to_string(UtilAll::getProcessId()) + "_" + "rocketmq-cpp.log"; + m_logFile = logDir + fileName; + +#if SPDLOG_VER_MAJOR >= 1 + spdlog::init_thread_pool(8192, 1); + + auto rotating_sink = std::make_shared(m_logFile, 1024 * 1024 * 100, 3); + rotating_sink->set_level(spdlog::level::debug); + rotating_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [thread@%t] - %v"); + m_logSinks.push_back(rotating_sink); + + m_logger = std::make_shared("default", m_logSinks.begin(), m_logSinks.end(), + spdlog::thread_pool(), spdlog::async_overflow_policy::block); - logging::add_common_attributes(); + // register it if you need to access it globally + spdlog::register_logger(m_logger); + + // when an error occurred, flush disk immediately + m_logger->flush_on(spdlog::level::err); + + spdlog::flush_every(std::chrono::seconds(3)); +#else + size_t q_size = 4096; + spdlog::set_async_mode(q_size); + m_logger = spdlog::rotating_logger_mt("default", m_logFile, 1024 * 1024 * 100, 3); + m_logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [thread@%t] - %v"); +#endif + + setLogLevelInner(m_logLevel); } void logAdapter::setLogLevelInner(elogLevel logLevel) { switch (logLevel) { case eLOG_LEVEL_FATAL: - logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::fatal); + m_logger->set_level(spdlog::level::critical); break; case eLOG_LEVEL_ERROR: - logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::error); - + m_logger->set_level(spdlog::level::err); break; case eLOG_LEVEL_WARN: - logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::warning); - + m_logger->set_level(spdlog::level::warn); break; case eLOG_LEVEL_INFO: - logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::info); - + m_logger->set_level(spdlog::level::info); break; case eLOG_LEVEL_DEBUG: - logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::debug); - + m_logger->set_level(spdlog::level::debug); break; case eLOG_LEVEL_TRACE: - logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::trace); - + m_logger->set_level(spdlog::level::trace); break; default: - logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::info); - + m_logger->set_level(spdlog::level::info); break; } } + void logAdapter::setLogLevel(elogLevel logLevel) { m_logLevel = logLevel; setLogLevelInner(logLevel); @@ -99,10 +126,6 @@ elogLevel logAdapter::getLogLevel() { return m_logLevel; } -void logAdapter::setLogFileNumAndSize(int logNum, int sizeOfPerFile) { - string homeDir(UtilAll::getHomeDirectory()); - homeDir.append("/logs/rocketmq-cpp/"); - m_logSink->locked_backend()->set_file_collector(sinks::file::make_collector( - keywords::target = homeDir, keywords::max_size = logNum * sizeOfPerFile * 1024 * 1024)); -} +void logAdapter::setLogFileNumAndSize(int logNum, int sizeOfPerFile) {} + } // namespace rocketmq diff --git a/src/log/Logging.h b/src/log/Logging.h index dfede3480..e60e3061f 100644 --- a/src/log/Logging.h +++ b/src/log/Logging.h @@ -14,93 +14,83 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef __ROCKETMQ_LOGGING_H__ +#define __ROCKETMQ_LOGGING_H__ + +#include +#include + +// clang-format off +#include +#include +// clang-format on -#ifndef _ALOG_ADAPTER_H_ -#define _ALOG_ADAPTER_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "MQClient.h" - -namespace logging = boost::log; -namespace src = boost::log::sources; -namespace sinks = boost::log::sinks; -namespace expr = boost::log::expressions; -namespace keywords = boost::log::keywords; -using namespace boost::log::trivial; namespace rocketmq { +enum elogLevel { + eLOG_LEVEL_FATAL = 1, + eLOG_LEVEL_ERROR = 2, + eLOG_LEVEL_WARN = 3, + eLOG_LEVEL_INFO = 4, + eLOG_LEVEL_DEBUG = 5, + eLOG_LEVEL_TRACE = 6, + eLOG_LEVEL_LEVEL_NUM = 7 +}; + class logAdapter { public: ~logAdapter(); + static logAdapter* getLogInstance(); + void setLogLevel(elogLevel logLevel); elogLevel getLogLevel(); + void setLogFileNumAndSize(int logNum, int sizeOfPerFile); - src::severity_logger& getSeverityLogger() { return m_severityLogger; } + + spdlog::logger* getSeverityLogger() { return m_logger.get(); } private: logAdapter(); void setLogLevelInner(elogLevel logLevel); + elogLevel m_logLevel; std::string m_logFile; - src::severity_logger m_severityLogger; - typedef sinks::synchronous_sink logSink_t; - boost::shared_ptr m_logSink; - static logAdapter* alogInstance; - static boost::mutex m_imtx; + + std::shared_ptr m_logger; +#if SPDLOG_VER_MAJOR >= 1 + std::vector m_logSinks; +#endif }; #define ALOG_ADAPTER logAdapter::getLogInstance() - #define AGENT_LOGGER ALOG_ADAPTER->getSeverityLogger() -class LogUtil { - public: - static void LogMessage(boost::log::trivial::severity_level level, int line, const char* format, ...) { - va_list arg_ptr; - va_start(arg_ptr, format); - boost::scoped_array formattedString(new char[1024]); - vsnprintf(formattedString.get(), 1024, format, arg_ptr); - BOOST_LOG_SEV(AGENT_LOGGER, level) << formattedString.get(); - va_end(arg_ptr); - } - static void LogMessageFull(boost::log::trivial::severity_level level, - const char* file, - const char* func, - int line, - const char* format, - ...) { - va_list arg_ptr; - va_start(arg_ptr, format); - boost::scoped_array formattedString(new char[1024]); - vsnprintf(formattedString.get(), 1024, format, arg_ptr); - // BOOST_LOG_SEV(AGENT_LOGGER, level) << formattedString.get() << "[" << file << ":" << func << ":"<< line << "]"; - BOOST_LOG_SEV(AGENT_LOGGER, level) << formattedString.get() << "[" << func << ":" << line << "]"; - va_end(arg_ptr); - } -}; +#define SPDLOG_PRINTF(logger, level, format, ...) \ + do { \ + if (logger->should_log(level)) { \ + std::string message = fmt::sprintf(format, ##__VA_ARGS__); \ + logger->log(level, "{} [{}:{}]", message, __FUNCTION__, __LINE__); \ + } \ + } while (0) + +#define LOG_FATAL(...) SPDLOG_PRINTF(AGENT_LOGGER, spdlog::level::critical, __VA_ARGS__) +#define LOG_ERROR(...) SPDLOG_PRINTF(AGENT_LOGGER, spdlog::level::err, __VA_ARGS__) +#define LOG_WARN(...) SPDLOG_PRINTF(AGENT_LOGGER, spdlog::level::warn, __VA_ARGS__) +#define LOG_INFO(...) SPDLOG_PRINTF(AGENT_LOGGER, spdlog::level::info, __VA_ARGS__) +#define LOG_DEBUG(...) SPDLOG_PRINTF(AGENT_LOGGER, spdlog::level::debug, __VA_ARGS__) + +#define SPDLOG_EXT(logger, level, format, ...) \ + do { \ + logger->log(level, format " [{}:{}]", ##__VA_ARGS__, __FUNCTION__, __LINE__); \ + } while (0) + +#define LOG_FATAL_NEW(...) SPDLOG_EXT(AGENT_LOGGER, spdlog::level::critical, __VA_ARGS__) +#define LOG_ERROR_NEW(...) SPDLOG_EXT(AGENT_LOGGER, spdlog::level::err, __VA_ARGS__) +#define LOG_WARN_NEW(...) SPDLOG_EXT(AGENT_LOGGER, spdlog::level::warn, __VA_ARGS__) +#define LOG_INFO_NEW(...) SPDLOG_EXT(AGENT_LOGGER, spdlog::level::info, __VA_ARGS__) +#define LOG_DEBUG_NEW(...) SPDLOG_EXT(AGENT_LOGGER, spdlog::level::debug, __VA_ARGS__) -#define LOG_FATAL(...) \ - LogUtil::LogMessageFull(boost::log::trivial::fatal, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) -#define LOG_ERROR(...) \ - LogUtil::LogMessageFull(boost::log::trivial::error, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) -#define LOG_WARN(...) \ - LogUtil::LogMessageFull(boost::log::trivial::warning, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) -//#define LOG_INFO(...) LogUtil::LogMessage(boost::log::trivial::info, __LINE__, __VA_ARGS__) -#define LOG_INFO(...) LogUtil::LogMessageFull(boost::log::trivial::info, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) -#define LOG_DEBUG(...) \ - LogUtil::LogMessageFull(boost::log::trivial::debug, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) } // namespace rocketmq -#endif + +#endif // __ROCKETMQ_LOGGING_H__ diff --git a/src/message/BatchMessage.cpp b/src/message/BatchMessage.cpp deleted file mode 100644 index 3a2481bd3..000000000 --- a/src/message/BatchMessage.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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 "BatchMessage.h" - -#include "MQDecoder.h" -#include "StringIdMaker.h" - -namespace rocketmq { - -std::string BatchMessage::encode(std::vector& msgs) { - std::string encodedBody; - for (auto message : msgs) { - std::string unique_id = StringIdMaker::getInstance().createUniqID(); - message.setProperty(MQMessage::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX, unique_id); - encodedBody.append(encode(message)); - } - return encodedBody; -} - -std::string BatchMessage::encode(MQMessage& message) { - string encodeMsg; - const string& body = message.getBody(); - int bodyLen = body.length(); - string properties = MQDecoder::messageProperties2String(message.getProperties()); - short propertiesLength = (short)properties.length(); - int storeSize = 20 + bodyLen + 2 + propertiesLength; - // TOTALSIZE|MAGICCOD|BODYCRC|FLAG|BODYLen|Body|propertiesLength|properties - int magicCode = 0; - int bodyCrc = 0; - int flag = message.getFlag(); - int storeSize_net = htonl(storeSize); - int magicCode_net = htonl(magicCode); - int bodyCrc_net = htonl(bodyCrc); - int flag_net = htonl(flag); - int bodyLen_net = htonl(bodyLen); - int propertiesLength_net = htons(propertiesLength); - encodeMsg.append((char*)&storeSize_net, sizeof(int)); - encodeMsg.append((char*)&magicCode_net, sizeof(int)); - encodeMsg.append((char*)&bodyCrc_net, sizeof(int)); - encodeMsg.append((char*)&flag_net, sizeof(int)); - encodeMsg.append((char*)&bodyLen_net, sizeof(int)); - encodeMsg.append(body.c_str(), body.length()); - encodeMsg.append((char*)&propertiesLength_net, sizeof(short)); - encodeMsg.append(properties.c_str(), propertiesLength); - return encodeMsg; -} - -} // namespace rocketmq diff --git a/src/message/MQDecoder.cpp b/src/message/MQDecoder.cpp index 1ba8a951f..931057497 100644 --- a/src/message/MQDecoder.cpp +++ b/src/message/MQDecoder.cpp @@ -1,250 +1,328 @@ -/* - * 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 "MQDecoder.h" -#include -#include -#include -#include -#include "Logging.h" -#include "MemoryOutputStream.h" -#include "MessageSysFlag.h" -#include "UtilAll.h" - -namespace rocketmq { - -//(outputmen.getData()); - int len = outputmen.getDataSize(); - - return UtilAll::bytes2string(bytes, len); -} - -MQMessageId MQDecoder::decodeMessageId(const string& msgId) { - string ipStr = msgId.substr(0, 8); - string portStr = msgId.substr(8, 8); - string offsetStr = msgId.substr(16, 16); - - int num = strspn(offsetStr.c_str(), "F"); - offsetStr = offsetStr.substr(num, 16 - num); - - char* end; - int ipInt = strtoul(ipStr.c_str(), &end, 16); - int portInt = strtoul(portStr.c_str(), &end, 16); - uint64 offset = strtoul(offsetStr.c_str(), &end, 16); - // int64 offset = UtilAll::hexstr2ull(offsetStr.c_str()); - - struct sockaddr_in sa; - sa.sin_family = AF_INET; - sa.sin_port = htons(portInt); - sa.sin_addr.s_addr = htonl(ipInt); - sockaddr addr; - memcpy(&addr, &sa, sizeof(sockaddr)); - - MQMessageId id(addr, offset); - return id; -} - -MQMessageExt* MQDecoder::decode(MemoryInputStream& byteBuffer) { - return decode(byteBuffer, true); -} - -MQMessageExt* MQDecoder::decode(MemoryInputStream& byteBuffer, bool readBody) { - MQMessageExt* msgExt = new MQMessageExt(); - - // 1 TOTALSIZE - int storeSize = byteBuffer.readIntBigEndian(); - msgExt->setStoreSize(storeSize); - - // 2 MAGICCODE sizeof(int) - byteBuffer.skipNextBytes(sizeof(int)); - - // 3 BODYCRC - int bodyCRC = byteBuffer.readIntBigEndian(); - msgExt->setBodyCRC(bodyCRC); - - // 4 QUEUEID - int queueId = byteBuffer.readIntBigEndian(); - msgExt->setQueueId(queueId); - - // 5 FLAG - int flag = byteBuffer.readIntBigEndian(); - msgExt->setFlag(flag); - - // 6 QUEUEOFFSET - int64 queueOffset = byteBuffer.readInt64BigEndian(); - msgExt->setQueueOffset(queueOffset); - - // 7 PHYSICALOFFSET - int64 physicOffset = byteBuffer.readInt64BigEndian(); - msgExt->setCommitLogOffset(physicOffset); - - // 8 SYSFLAG - int sysFlag = byteBuffer.readIntBigEndian(); - msgExt->setSysFlag(sysFlag); - - // 9 BORNTIMESTAMP - int64 bornTimeStamp = byteBuffer.readInt64BigEndian(); - msgExt->setBornTimestamp(bornTimeStamp); - - // 10 BORNHOST - int bornHost = byteBuffer.readIntBigEndian(); - int port = byteBuffer.readIntBigEndian(); - sockaddr bornAddr = IPPort2socketAddress(bornHost, port); - msgExt->setBornHost(bornAddr); - - // 11 STORETIMESTAMP - int64 storeTimestamp = byteBuffer.readInt64BigEndian(); - msgExt->setStoreTimestamp(storeTimestamp); - - // // 12 STOREHOST - int storeHost = byteBuffer.readIntBigEndian(); - port = byteBuffer.readIntBigEndian(); - sockaddr storeAddr = IPPort2socketAddress(storeHost, port); - msgExt->setStoreHost(storeAddr); - - // 13 RECONSUMETIMES - int reconsumeTimes = byteBuffer.readIntBigEndian(); - msgExt->setReconsumeTimes(reconsumeTimes); - - // 14 Prepared Transaction Offset - int64 preparedTransactionOffset = byteBuffer.readInt64BigEndian(); - msgExt->setPreparedTransactionOffset(preparedTransactionOffset); - - // 15 BODY - int bodyLen = byteBuffer.readIntBigEndian(); - if (bodyLen > 0) { - if (readBody) { - MemoryBlock block; - byteBuffer.readIntoMemoryBlock(block, bodyLen); - - const char* const pBody = static_cast(block.getData()); - int len = block.getSize(); - string msgbody(pBody, len); - - // decompress body - if ((sysFlag & MessageSysFlag::CompressedFlag) == MessageSysFlag::CompressedFlag) { - string outbody; - if (UtilAll::inflate(msgbody, outbody)) { - msgExt->setBody(outbody); - } - } else { - msgExt->setBody(msgbody); - } - } else { - byteBuffer.skipNextBytes(bodyLen); - } - } - - // 16 TOPIC - int topicLen = (int)byteBuffer.readByte(); - MemoryBlock block; - byteBuffer.readIntoMemoryBlock(block, topicLen); - const char* const pTopic = static_cast(block.getData()); - topicLen = block.getSize(); - msgExt->setTopic(pTopic, topicLen); - - // 17 properties - short propertiesLen = byteBuffer.readShortBigEndian(); - if (propertiesLen > 0) { - MemoryBlock block; - byteBuffer.readIntoMemoryBlock(block, propertiesLen); - const char* const pProperty = static_cast(block.getData()); - int len = block.getSize(); - string propertiesString(pProperty, len); - - map propertiesMap; - string2messageProperties(propertiesString, propertiesMap); - msgExt->setPropertiesInternal(propertiesMap); - propertiesMap.clear(); - } - - // 18 msg ID - string offsetMsgId = createMessageId(msgExt->getStoreHost(), (int64)msgExt->getCommitLogOffset()); - msgExt->setOffsetMsgId(offsetMsgId); - - string msgId = msgExt->getProperty(MQMessage::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX); - if (msgId.empty()) { - msgId = offsetMsgId; - } - msgExt->setMsgId(msgId); - - // LOG_INFO("get msgExt from remote server, its contents are:%s", msgExt->toString().c_str()); - return msgExt; -} - -void MQDecoder::decodes(const MemoryBlock* mem, vector& mqvec) { - mqvec.clear(); - decodes(mem, mqvec, true); -} - -void MQDecoder::decodes(const MemoryBlock* mem, vector& mqvec, bool readBody) { - MemoryInputStream rawInput(*mem, true); - - while (rawInput.getNumBytesRemaining() > 0) { - unique_ptr msg(decode(rawInput, readBody)); - mqvec.push_back(*msg); - } -} - -string MQDecoder::messageProperties2String(const map& properties) { - string os; - - for (const auto& it : properties) { - // os << it->first << NAME_VALUE_SEPARATOR << it->second << PROPERTY_SEPARATOR; - os.append(it.first); - os += NAME_VALUE_SEPARATOR; - os.append(it.second); - os += PROPERTY_SEPARATOR; - } - - return os; -} - -void MQDecoder::string2messageProperties(const string& propertiesString, map& properties) { - vector out; - UtilAll::Split(out, propertiesString, PROPERTY_SEPARATOR); - - for (size_t i = 0; i < out.size(); i++) { - vector outValue; - UtilAll::Split(outValue, out[i], NAME_VALUE_SEPARATOR); - - if (outValue.size() == 2) { - properties[outValue[0]] = outValue[1]; - } - } -} -} // namespace rocketmq +/* + * 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 "MQDecoder.h" + +#include + +#ifndef WIN32 +#include +#endif + +#include "ByteOrder.h" +#include "Logging.h" +#include "MemoryOutputStream.h" +#include "MessageAccessor.h" +#include "MessageSysFlag.h" +#include "UtilAll.h" + +namespace rocketmq { + +const int MQDecoder::MSG_ID_LENGTH = 8 + 8; + +const char MQDecoder::NAME_VALUE_SEPARATOR = 1; +const char MQDecoder::PROPERTY_SEPARATOR = 2; + +int MQDecoder::MessageMagicCodePostion = 4; +int MQDecoder::MessageFlagPostion = 16; +int MQDecoder::MessagePhysicOffsetPostion = 28; +int MQDecoder::MessageStoreTimestampPostion = 56; + +std::string MQDecoder::createMessageId(sockaddr addr, int64_t offset) { + struct sockaddr_in* sa = (struct sockaddr_in*)&addr; + + MemoryOutputStream outputmen(MSG_ID_LENGTH); + outputmen.writeIntBigEndian(sa->sin_addr.s_addr); + outputmen.writeRepeatedByte(0, 2); + outputmen.write(&(sa->sin_port), 2); + outputmen.writeInt64BigEndian(offset); + + const char* bytes = static_cast(outputmen.getData()); + int len = outputmen.getDataSize(); + + return UtilAll::bytes2string(bytes, len); +} + +MQMessageId MQDecoder::decodeMessageId(const std::string& msgId) { + std::string ipStr = msgId.substr(0, 8); + std::string portStr = msgId.substr(8, 8); + std::string offsetStr = msgId.substr(16); + + size_t pos; + int ipInt = std::stoul(ipStr, &pos, 16); + int portInt = std::stoul(portStr, &pos, 16); + + uint64_t offset = UtilAll::hexstr2ull(offsetStr.c_str()); + + struct sockaddr_in sa; + sa.sin_family = AF_INET; + sa.sin_port = htons(portInt); + sa.sin_addr.s_addr = htonl(ipInt); + + return MQMessageId(*((sockaddr*)&sa), offset); +} + +MQMessageExtPtr MQDecoder::clientDecode(MemoryInputStream& byteBuffer, bool readBody) { + return decode(byteBuffer, readBody, true, true); +} + +MQMessageExtPtr MQDecoder::decode(MemoryInputStream& byteBuffer, bool readBody) { + return decode(byteBuffer, readBody, true, false); +} + +MQMessageExtPtr MQDecoder::decode(MemoryInputStream& byteBuffer, bool readBody, bool deCompressBody, bool isClient) { + MQMessageExtPtr msgExt; + + if (isClient) { + msgExt = new MQMessageClientExt(); + } else { + msgExt = new MQMessageExt(); + } + + // 1 TOTALSIZE + int32_t storeSize = byteBuffer.readIntBigEndian(); + msgExt->setStoreSize(storeSize); + + // 2 MAGICCODE sizeof(int) + byteBuffer.skipNextBytes(sizeof(int)); + + // 3 BODYCRC + int32_t bodyCRC = byteBuffer.readIntBigEndian(); + msgExt->setBodyCRC(bodyCRC); + + // 4 QUEUEID + int32_t queueId = byteBuffer.readIntBigEndian(); + msgExt->setQueueId(queueId); + + // 5 FLAG + int32_t flag = byteBuffer.readIntBigEndian(); + msgExt->setFlag(flag); + + // 6 QUEUEOFFSET + int64_t queueOffset = byteBuffer.readInt64BigEndian(); + msgExt->setQueueOffset(queueOffset); + + // 7 PHYSICALOFFSET + int64_t physicOffset = byteBuffer.readInt64BigEndian(); + msgExt->setCommitLogOffset(physicOffset); + + // 8 SYSFLAG + int32_t sysFlag = byteBuffer.readIntBigEndian(); + msgExt->setSysFlag(sysFlag); + + // 9 BORNTIMESTAMP + int64_t bornTimeStamp = byteBuffer.readInt64BigEndian(); + msgExt->setBornTimestamp(bornTimeStamp); + + // 10 BORNHOST + int32_t bornHost = byteBuffer.readIntBigEndian(); + int32_t bornPort = byteBuffer.readIntBigEndian(); + sockaddr bornAddr = IPPort2socketAddress(bornHost, bornPort); + msgExt->setBornHost(bornAddr); + + // 11 STORETIMESTAMP + int64_t storeTimestamp = byteBuffer.readInt64BigEndian(); + msgExt->setStoreTimestamp(storeTimestamp); + + // // 12 STOREHOST + int32_t storeHost = byteBuffer.readIntBigEndian(); + int32_t storePort = byteBuffer.readIntBigEndian(); + sockaddr storeAddr = IPPort2socketAddress(storeHost, storePort); + msgExt->setStoreHost(storeAddr); + + // 13 RECONSUMETIMES + int32_t reconsumeTimes = byteBuffer.readIntBigEndian(); + msgExt->setReconsumeTimes(reconsumeTimes); + + // 14 Prepared Transaction Offset + int64_t preparedTransactionOffset = byteBuffer.readInt64BigEndian(); + msgExt->setPreparedTransactionOffset(preparedTransactionOffset); + + // 15 BODY + int uncompress_failed = false; + int32_t bodyLen = byteBuffer.readIntBigEndian(); + if (bodyLen > 0) { + if (readBody) { + MemoryPool block; + byteBuffer.readIntoMemoryBlock(block, bodyLen); + + // decompress body + if (deCompressBody && (sysFlag & MessageSysFlag::CompressedFlag) == MessageSysFlag::CompressedFlag) { + std::string outbody; + if (UtilAll::inflate(block.getData(), block.getSize(), outbody)) { + msgExt->setBody(std::move(outbody)); + } else { + uncompress_failed = true; + } + } else { + msgExt->setBody(block.getData(), block.getSize()); + } + } else { + byteBuffer.skipNextBytes(bodyLen); + } + } + + // 16 TOPIC + int8_t topicLen = byteBuffer.readByte(); + MemoryPool block; + byteBuffer.readIntoMemoryBlock(block, topicLen); + const char* const pTopic = static_cast(block.getData()); + topicLen = block.getSize(); + msgExt->setTopic(pTopic, topicLen); + + // 17 properties + int16_t propertiesLen = byteBuffer.readShortBigEndian(); + if (propertiesLen > 0) { + MemoryPool block; + byteBuffer.readIntoMemoryBlock(block, propertiesLen); + std::string propertiesString(block.getData(), block.getSize()); + + std::map propertiesMap = string2messageProperties(propertiesString); + MessageAccessor::setProperties(*msgExt, std::move(propertiesMap)); + } + + // 18 msg ID + std::string msgId = createMessageId(msgExt->getStoreHost(), (int64_t)msgExt->getCommitLogOffset()); + msgExt->MQMessageExt::setMsgId(msgId); + + if (uncompress_failed) { + LOG_WARN_NEW("can not uncompress message, id:{}", msgExt->getMsgId()); + } + + return msgExt; +} + +MQMessageExtPtr2 MQDecoder::decode(MemoryBlock& mem) { + return decode(mem, true); +} + +MQMessageExtPtr2 MQDecoder::decode(MemoryBlock& mem, bool readBody) { + MemoryInputStream rawInput(mem, true); + MQMessageExtPtr2 message(decode(rawInput, readBody)); + return message; +} + +std::vector MQDecoder::decodes(MemoryBlock& mem) { + return decodes(mem, true); +} + +std::vector MQDecoder::decodes(MemoryBlock& mem, bool readBody) { + std::vector msgExts; + MemoryInputStream rawInput(mem, true); + while (rawInput.getNumBytesRemaining() > 0) { + auto* msgExt = clientDecode(rawInput, readBody); + if (msgExt != nullptr) { + msgExts.emplace_back(msgExt); + } else { + break; + } + } + return msgExts; +} + +std::string MQDecoder::messageProperties2String(const std::map& properties) { + std::string os; + + for (const auto& it : properties) { + const auto& name = it.first; + const auto& value = it.second; + + // skip compressed flag + if (MQMessageConst::PROPERTY_ALREADY_COMPRESSED_FLAG == name) { + continue; + } + + os.append(name); + os += NAME_VALUE_SEPARATOR; + os.append(value); + os += PROPERTY_SEPARATOR; + } + + return os; +} + +std::map MQDecoder::string2messageProperties(const std::string& properties) { + std::vector out; + UtilAll::Split(out, properties, PROPERTY_SEPARATOR); + + std::map map; + for (size_t i = 0; i < out.size(); i++) { + std::vector outValue; + UtilAll::Split(outValue, out[i], NAME_VALUE_SEPARATOR); + + if (outValue.size() == 2) { + map[outValue[0]] = outValue[1]; + } + } + return map; +} + +std::string MQDecoder::encodeMessage(MQMessage& message) { + const std::string& body = message.getBody(); + uint32_t bodyLen = body.length(); + std::string properties = MQDecoder::messageProperties2String(message.getProperties()); + uint16_t propertiesLength = (int16_t)properties.length(); + uint32_t storeSize = 4 // 1 TOTALSIZE + + 4 // 2 MAGICCODE + + 4 // 3 BODYCRC + + 4 // 4 FLAG + + 4 + bodyLen // 5 BODY + + 2 + propertiesLength; // 6 PROPERTIES + + // TOTALSIZE|MAGICCODE|BODYCRC|FLAG|BodyLen|Body|propertiesLength|properties + std::string encodeMsg; + + // 1 TOTALSIZE + uint32_t storeSize_net = ByteOrder::swapIfLittleEndian(storeSize); + encodeMsg.append((char*)&storeSize_net, sizeof(uint32_t)); + + // 2 MAGICCODE + uint32_t magicCode = 0; + uint32_t magicCode_net = ByteOrder::swapIfLittleEndian(magicCode); + encodeMsg.append((char*)&magicCode_net, sizeof(uint32_t)); + + // 3 BODYCRC + uint32_t bodyCrc = 0; + uint32_t bodyCrc_net = ByteOrder::swapIfLittleEndian(bodyCrc); + encodeMsg.append((char*)&bodyCrc_net, sizeof(uint32_t)); + + // 4 FLAG + uint32_t flag = message.getFlag(); + uint32_t flag_net = ByteOrder::swapIfLittleEndian(flag); + encodeMsg.append((char*)&flag_net, sizeof(uint32_t)); + + // 5 BODY + uint32_t bodyLen_net = ByteOrder::swapIfLittleEndian(bodyLen); + encodeMsg.append((char*)&bodyLen_net, sizeof(uint32_t)); + encodeMsg.append(body); + + // 6 properties + uint16_t propertiesLength_net = ByteOrder::swapIfLittleEndian(propertiesLength); + encodeMsg.append((char*)&propertiesLength_net, sizeof(uint16_t)); + encodeMsg.append(std::move(properties)); + + return encodeMsg; +} + +std::string MQDecoder::encodeMessages(std::vector& msgs) { + std::string encodedBody; + for (auto* message : msgs) { + encodedBody.append(encodeMessage(*message)); + } + return encodedBody; +} + +} // namespace rocketmq diff --git a/src/message/MQDecoder.h b/src/message/MQDecoder.h index d9c94ad48..01b6f84c4 100644 --- a/src/message/MQDecoder.h +++ b/src/message/MQDecoder.h @@ -14,8 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MESSAGEDECODER_H__ -#define __MESSAGEDECODER_H__ +#ifndef __MESSAGE_DECODER_H__ +#define __MESSAGE_DECODER_H__ + +#include +#include +#include #include "MQClientException.h" #include "MQMessageExt.h" @@ -24,22 +28,28 @@ #include "SocketUtil.h" namespace rocketmq { -//& mqvec); + static MQMessageExtPtr2 decode(MemoryBlock& mem); + static MQMessageExtPtr2 decode(MemoryBlock& mem, bool readBody); - static void decodes(const MemoryBlock* mem, vector& mqvec, bool readBody); + static std::vector decodes(MemoryBlock& mem); + static std::vector decodes(MemoryBlock& mem, bool readBody); - static string messageProperties2String(const map& properties); - static void string2messageProperties(const string& propertiesString, map& properties); + static std::string messageProperties2String(const std::map& properties); + static std::map string2messageProperties(const std::string& properties); + + static std::string encodeMessage(MQMessage& message); + static std::string encodeMessages(std::vector& msgs); private: - static MQMessageExt* decode(MemoryInputStream& byteBuffer); - static MQMessageExt* decode(MemoryInputStream& byteBuffer, bool readBody); + static MQMessageExtPtr clientDecode(MemoryInputStream& byteBuffer, bool readBody); + static MQMessageExtPtr decode(MemoryInputStream& byteBuffer, bool readBody); + static MQMessageExtPtr decode(MemoryInputStream& byteBuffer, bool readBody, bool deCompressBody, bool isClient); public: static const char NAME_VALUE_SEPARATOR; @@ -50,6 +60,7 @@ class MQDecoder { static int MessagePhysicOffsetPostion; static int MessageStoreTimestampPostion; }; -} // 0) { + setTags(tags); + } + + if (keys.length() > 0) { + setKeys(keys); + } -MQMessage::~MQMessage() { - m_properties.clear(); + setWaitStoreMsgOK(waitStoreMsgOK); } MQMessage::MQMessage(const MQMessage& other) { - m_body = other.m_body; m_topic = other.m_topic; m_flag = other.m_flag; - m_sysFlag = other.m_sysFlag; m_properties = other.m_properties; + m_body = other.m_body; } MQMessage& MQMessage::operator=(const MQMessage& other) { if (this != &other) { - m_body = other.m_body; m_topic = other.m_topic; m_flag = other.m_flag; - m_sysFlag = other.m_sysFlag; m_properties = other.m_properties; + m_body = other.m_body; } return *this; } -void MQMessage::setProperty(const string& name, const string& value) { - if (PROPERTY_TRANSACTION_PREPARED == name) { - if (!value.empty() && value == "true") { - m_sysFlag |= MessageSysFlag::TransactionPreparedType; - } else { - m_sysFlag &= ~MessageSysFlag::TransactionPreparedType; - } +MQMessage::~MQMessage() = default; + +const std::string& MQMessage::getProperty(const std::string& name) const { + const auto it = m_properties.find(name); + if (it != m_properties.end()) { + return it->second; } - m_properties[name] = value; + return EMPTY_STRING; } -void MQMessage::setPropertyInternal(const string& name, const string& value) { +void MQMessage::putProperty(const std::string& name, const std::string& value) { m_properties[name] = value; } -const string& MQMessage::getProperty(const string& name) const { - map::const_iterator it = m_properties.find(name); - if (it == m_properties.end()) { - return EMPTY_STRING; - } else { - return it->second; - } +void MQMessage::clearProperty(const std::string& name) { + m_properties.erase(name); } -const string& MQMessage::getTopic() const { +const std::string& MQMessage::getTopic() const { return m_topic; } -void MQMessage::setTopic(const string& topic) { +void MQMessage::setTopic(const std::string& topic) { m_topic = topic; } @@ -137,34 +133,34 @@ void MQMessage::setTopic(const char* body, int len) { m_topic.append(body, len); } -const string& MQMessage::getTags() const { - return getProperty(PROPERTY_TAGS); +const std::string& MQMessage::getTags() const { + return getProperty(MQMessageConst::PROPERTY_TAGS); } -void MQMessage::setTags(const string& tags) { - setPropertyInternal(PROPERTY_TAGS, tags); +void MQMessage::setTags(const std::string& tags) { + putProperty(MQMessageConst::PROPERTY_TAGS, tags); } -const string& MQMessage::getKeys() const { - return getProperty(PROPERTY_KEYS); +const std::string& MQMessage::getKeys() const { + return getProperty(MQMessageConst::PROPERTY_KEYS); } -void MQMessage::setKeys(const string& keys) { - setPropertyInternal(PROPERTY_KEYS, keys); +void MQMessage::setKeys(const std::string& keys) { + putProperty(MQMessageConst::PROPERTY_KEYS, keys); } -void MQMessage::setKeys(const vector& keys) { +void MQMessage::setKeys(const std::vector& keys) { if (keys.empty()) { return; } - vector::const_iterator it = keys.begin(); - string str; + std::vector::const_iterator it = keys.begin(); + std::string str; str += *it; it++; for (; it != keys.end(); it++) { - str += KEY_SEPARATOR; + str += MQMessageConst::KEY_SEPARATOR; str += *it; } @@ -172,7 +168,7 @@ void MQMessage::setKeys(const vector& keys) { } int MQMessage::getDelayTimeLevel() const { - string tmp = getProperty(PROPERTY_DELAY_TIME_LEVEL); + std::string tmp = getProperty(MQMessageConst::PROPERTY_DELAY_TIME_LEVEL); if (!tmp.empty()) { return atoi(tmp.c_str()); } @@ -180,27 +176,16 @@ int MQMessage::getDelayTimeLevel() const { } void MQMessage::setDelayTimeLevel(int level) { - char tmp[16]; - sprintf(tmp, "%d", level); - - setPropertyInternal(PROPERTY_DELAY_TIME_LEVEL, tmp); + putProperty(MQMessageConst::PROPERTY_DELAY_TIME_LEVEL, UtilAll::to_string(level)); } bool MQMessage::isWaitStoreMsgOK() const { - string tmp = getProperty(PROPERTY_WAIT_STORE_MSG_OK); - if (tmp.empty()) { - return true; - } else { - return (tmp == "true") ? true : false; - } + std::string tmp = getProperty(MQMessageConst::PROPERTY_WAIT_STORE_MSG_OK); + return tmp.empty() || UtilAll::stob(tmp); } void MQMessage::setWaitStoreMsgOK(bool waitStoreMsgOK) { - if (waitStoreMsgOK) { - setPropertyInternal(PROPERTY_WAIT_STORE_MSG_OK, "true"); - } else { - setPropertyInternal(PROPERTY_WAIT_STORE_MSG_OK, "false"); - } + putProperty(MQMessageConst::PROPERTY_WAIT_STORE_MSG_OK, UtilAll::to_string(waitStoreMsgOK)); } int MQMessage::getFlag() const { @@ -211,15 +196,8 @@ void MQMessage::setFlag(int flag) { m_flag = flag; } -int MQMessage::getSysFlag() const { - return m_sysFlag; -} - -void MQMessage::setSysFlag(int sysFlag) { - m_sysFlag = sysFlag; -} - -const string& MQMessage::getBody() const { +const std::string& MQMessage::getBody() const { + // TODO: return MemoryBlockPtr2 return m_body; } @@ -228,52 +206,32 @@ void MQMessage::setBody(const char* body, int len) { m_body.append(body, len); } -void MQMessage::setBody(const string& body) { - m_body.clear(); - m_body.append(body); +void MQMessage::setBody(const std::string& body) { + m_body = body; } -map MQMessage::getProperties() const { - return m_properties; +void MQMessage::setBody(std::string&& body) { + m_body = std::forward(body); } -void MQMessage::setProperties(map& properties) { - m_properties = properties; - - map::const_iterator it = m_properties.find(PROPERTY_TRANSACTION_PREPARED); - if (it != m_properties.end()) { - string tranMsg = it->second; - if (!tranMsg.empty() && tranMsg == "true") { - m_sysFlag |= MessageSysFlag::TransactionPreparedType; - } else { - m_sysFlag &= ~MessageSysFlag::TransactionPreparedType; - } - } +const std::string& MQMessage::getTransactionId() const { + return m_transactionId; } -void MQMessage::setPropertiesInternal(map& properties) { - m_properties = properties; +void MQMessage::setTransactionId(const std::string& transactionId) { + m_transactionId = transactionId; } -void MQMessage::Init(const string& topic, - const string& tags, - const string& keys, - const int flag, - const string& body, - bool waitStoreMsgOK) { - m_topic = topic; - m_flag = flag; - m_sysFlag = 0; - m_body = body; - - if (tags.length() > 0) { - setTags(tags); - } +const std::map& MQMessage::getProperties() const { + return m_properties; +} - if (keys.length() > 0) { - setKeys(keys); - } +void MQMessage::setProperties(const std::map& properties) { + m_properties = properties; +} - setWaitStoreMsgOK(waitStoreMsgOK); +void MQMessage::setProperties(std::map&& properties) { + m_properties = std::forward>(properties); } -} // + +#include "MessageClientIDSetter.h" #include "MessageSysFlag.h" #include "SocketUtil.h" #include "TopicFilterType.h" namespace rocketmq { -//&& properties) { + msg.setProperties(std::forward>(properties)); + } + + static inline void putProperty(MQMessage& msg, const std::string& name, const std::string& value) { + msg.putProperty(name, value); + } + + static inline const std::string& getReconsumeTime(MQMessage& msg) { + return msg.getProperty(MQMessageConst::PROPERTY_RECONSUME_TIME); + } + + static inline const std::string& getMaxReconsumeTimes(MQMessage& msg) { + return msg.getProperty(MQMessageConst::PROPERTY_MAX_RECONSUME_TIMES); + } + + static inline void setConsumeStartTimeStamp(MQMessage& msg, const std::string& propertyConsumeStartTimeStamp) { + putProperty(msg, MQMessageConst::PROPERTY_CONSUME_START_TIMESTAMP, propertyConsumeStartTimeStamp); + } +}; + +} // namespace rocketmq + +#endif // __MESSAGE_ACCESSOR_H__ diff --git a/src/message/MessageBatch.cpp b/src/message/MessageBatch.cpp new file mode 100644 index 000000000..40ecee32e --- /dev/null +++ b/src/message/MessageBatch.cpp @@ -0,0 +1,63 @@ +/* + * 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 "MessageBatch.h" + +#include + +#include "MQDecoder.h" +#include "MessageClientIDSetter.h" + +namespace rocketmq { + +std::string MessageBatch::encode() { + return MQDecoder::encodeMessages(m_messages); +} + +MessageBatch* MessageBatch::generateFromList(std::vector& messages) { + bool isFirst = true; + std::string topic; + bool waitStoreMsgOK = false; + + for (auto& message : messages) { + if (message->getDelayTimeLevel() > 0) { + THROW_MQEXCEPTION(MQClientException, "TimeDelayLevel in not supported for batching", -1); + } + if (isFirst) { + isFirst = false; + topic = message->getTopic(); + waitStoreMsgOK = message->isWaitStoreMsgOK(); + + if (UtilAll::isRetryTopic(topic)) { + THROW_MQEXCEPTION(MQClientException, "Retry Group is not supported for batching", -1); + } + } else { + if (message->getTopic() != topic) { + THROW_MQEXCEPTION(MQClientException, "The topic of the messages in one batch should be the same", -1); + } + if (message->isWaitStoreMsgOK() != waitStoreMsgOK) { + THROW_MQEXCEPTION(MQClientException, "The waitStoreMsgOK of the messages in one batch should the same", -2); + } + } + } + + MessageBatch* batchMessage = new MessageBatch(messages); + batchMessage->setTopic(topic); + batchMessage->setWaitStoreMsgOK(waitStoreMsgOK); + return batchMessage; +} + +} // namespace rocketmq diff --git a/src/common/MessageAccessor.h b/src/message/MessageBatch.h similarity index 62% rename from src/common/MessageAccessor.h rename to src/message/MessageBatch.h index af42021e3..644d28726 100644 --- a/src/common/MessageAccessor.h +++ b/src/message/MessageBatch.h @@ -14,22 +14,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MESSAGE_ACCESSOR_H__ -#define __MESSAGE_ACCESSOR_H__ +#ifndef __MESSAGE_BATCH_H__ +#define __MESSAGE_BATCH_H__ +#include #include -#include + #include "MQMessage.h" -#include "MQMessageExt.h" + namespace rocketmq { -//& messages); + public: - static void withNameSpace(MQMessage& msg, const std::string nameSpace); - static void withoutNameSpaceSingle(MQMessageExt& msg, const std::string nameSpace); - static void withoutNameSpace(std::vector& msgs, const std::string nameSpace); + MessageBatch(std::vector& messages) : m_messages(messages) {} + + std::string encode(); + + const std::vector& getMessages() const { return m_messages; } + + bool isBatch() override final { return true; } + + protected: + std::vector m_messages; }; -// #include #include #include +#ifndef WIN32 +#include +#endif + #include "ByteOrder.h" #include "UtilAll.h" namespace rocketmq { -const char StringIdMaker::sHexAlphabet[16] = {'0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - -StringIdMaker::StringIdMaker() { +MessageClientIDSetter::MessageClientIDSetter() { std::srand((uint32_t)std::time(NULL)); - uint32_t pid = ByteOrder::swapIfLittleEndian(static_cast(getpid())); - uint32_t ip = ByteOrder::swapIfLittleEndian(getIP()); + uint32_t pid = ByteOrder::swapIfLittleEndian(static_cast(UtilAll::getProcessId())); + uint32_t ip = ByteOrder::swapIfLittleEndian(UtilAll::getIP()); uint32_t random_num = ByteOrder::swapIfLittleEndian(static_cast(std::rand())); - unsigned char bin_buf[10]; + char bin_buf[10]; std::memcpy(bin_buf + 2, &pid, 4); std::memcpy(bin_buf, &ip, 4); std::memcpy(bin_buf + 6, &random_num, 4); - hexdump(bin_buf, kFixString, 10); - kFixString[20] = '\0'; + kFixString = UtilAll::bytes2string(bin_buf, 10); setStartTime(UtilAll::currentTimeMillis()); mCounter = 0; } -StringIdMaker::~StringIdMaker() {} - -uint32_t StringIdMaker::getIP() { - std::string ip = UtilAll::getLocalAddress(); - if (ip.empty()) { - return 0; - } - - char* ip_str = new char[ip.length() + 1]; - std::strncpy(ip_str, ip.c_str(), ip.length()); - ip_str[ip.length()] = '\0'; - - int i = 3; - uint32_t nResult = 0; - for (char* token = std::strtok(ip_str, "."); token != nullptr && i >= 0; token = std::strtok(nullptr, ".")) { - uint32_t n = std::atoi(token); - nResult |= n << (8 * i--); - } - - delete[] ip_str; - - return nResult; -} +MessageClientIDSetter::~MessageClientIDSetter() = default; -void StringIdMaker::setStartTime(uint64_t millis) { +void MessageClientIDSetter::setStartTime(uint64_t millis) { // std::time_t // Although not defined, this is almost always an integral value holding the number of seconds // (not counting leap seconds) since 00:00, Jan 1 1970 UTC, corresponding to POSIX time. @@ -105,7 +83,7 @@ void StringIdMaker::setStartTime(uint64_t millis) { mNextStartTime = std::mktime(&nextMonthBegin) * 1000; } -std::string StringIdMaker::createUniqID() { +std::string MessageClientIDSetter::createUniqueID() { uint64_t current = UtilAll::currentTimeMillis(); if (current >= mNextStartTime) { setStartTime(current); @@ -115,22 +93,11 @@ std::string StringIdMaker::createUniqID() { uint32_t period = ByteOrder::swapIfLittleEndian(static_cast(current - mStartTime)); uint16_t seqid = ByteOrder::swapIfLittleEndian(mCounter++); - unsigned char bin_buf[6]; + char bin_buf[6]; std::memcpy(bin_buf, &period, 4); std::memcpy(bin_buf + 4, &seqid, 2); - char hex_buf[12]; - hexdump(bin_buf, hex_buf, 6); - - return std::string(kFixString, 20) + std::string(hex_buf, 12); -} - -void StringIdMaker::hexdump(unsigned char* in, char* out, std::size_t len) { - for (std::size_t i = 0; i < len; i++) { - unsigned char v = in[i]; - out[i * 2] = sHexAlphabet[v >> 4]; - out[i * 2 + 1] = sHexAlphabet[v & 0x0FU]; - } + return kFixString + UtilAll::bytes2string(bin_buf, 6); } } // namespace rocketmq diff --git a/src/producer/StringIdMaker.h b/src/message/MessageClientIDSetter.h similarity index 58% rename from src/producer/StringIdMaker.h rename to src/message/MessageClientIDSetter.h index 872bf05ba..9af959e89 100644 --- a/src/producer/StringIdMaker.h +++ b/src/message/MessageClientIDSetter.h @@ -14,24 +14,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __STRINGID_MAKER_H__ -#define __STRINGID_MAKER_H__ +#ifndef __MESSAGE_CLIENT_ID_SETTER_H__ +#define __MESSAGE_CLIENT_ID_SETTER_H__ #include #include #include -namespace rocketmq { +#include "MQMessage.h" +#include "MessageAccessor.h" -class StringIdMaker { - private: - StringIdMaker(); - ~StringIdMaker(); +namespace rocketmq { +class MessageClientIDSetter { public: - static StringIdMaker& getInstance() { + static MessageClientIDSetter& getInstance() { // After c++11, the initialization occurs exactly once - static StringIdMaker singleton_; + static MessageClientIDSetter singleton_; return singleton_; } @@ -42,23 +41,35 @@ class StringIdMaker { * time: 4 bytes * auto num: 2 bytes */ - std::string createUniqID(); + static std::string createUniqID() { return getInstance().createUniqueID(); } + + static void setUniqID(MQMessage& msg) { + if (msg.getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX).empty()) { + MessageAccessor::putProperty(msg, MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX, createUniqID()); + } + } + + static const std::string& getUniqID(const MQMessage& msg) { + return msg.getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX); + } + + public: + virtual ~MessageClientIDSetter(); private: - void setStartTime(uint64_t millis); + MessageClientIDSetter(); - static uint32_t getIP(); - static void hexdump(unsigned char* buffer, char* out_buff, unsigned long index); + void setStartTime(uint64_t millis); + std::string createUniqueID(); private: uint64_t mStartTime; uint64_t mNextStartTime; std::atomic mCounter; - char kFixString[21]; - - static const char sHexAlphabet[16]; + std::string kFixString; }; } // namespace rocketmq -#endif + +#endif // __MESSAGE_CLIENT_ID_SETTER_H__ diff --git a/src/producer/DefaultMQProducer.cpp b/src/producer/DefaultMQProducer.cpp index ee81a7b8d..a7f11ee41 100644 --- a/src/producer/DefaultMQProducer.cpp +++ b/src/producer/DefaultMQProducer.cpp @@ -14,622 +14,147 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "DefaultMQProducer.h" -#include -#include - -#include "BatchMessage.h" -#include "CommandHeader.h" -#include "CommunicationMode.h" -#include "Logging.h" -#include "MQClientAPIImpl.h" -#include "MQClientException.h" -#include "MQClientFactory.h" -#include "MQClientManager.h" -#include "MQDecoder.h" -#include "MQProtos.h" -#include "MessageAccessor.h" -#include "NameSpaceUtil.h" -#include "StringIdMaker.h" -#include "TopicPublishInfo.h" -#include "Validators.h" +#include "DefaultMQProducerImpl.h" +#include "UtilAll.h" namespace rocketmq { -//registerProducer(this); - if (!registerOK) { - m_serviceState = CREATE_JUST; - THROW_MQEXCEPTION( - MQClientException, - "The producer group[" + getGroupName() + "] has been created before, specify another name please.", -1); - } - - getFactory()->start(); - getFactory()->sendHeartbeatToAllBroker(); - m_serviceState = RUNNING; - break; - } - case RUNNING: - case START_FAILED: - case SHUTDOWN_ALREADY: - break; - default: - break; +DefaultMQProducer::DefaultMQProducer(const std::string& groupname, std::shared_ptr rpcHook) + : m_producerDelegate(nullptr) { + // set default group name + if (groupname.empty()) { + setGroupName(DEFAULT_PRODUCER_GROUP); + } else { + setGroupName(groupname); } -} -void DefaultMQProducer::shutdown() { - switch (m_serviceState) { - case RUNNING: { - LOG_INFO("DefaultMQProducer shutdown"); - getFactory()->unregisterProducer(this); - getFactory()->shutdown(); - m_serviceState = SHUTDOWN_ALREADY; - break; - } - case SHUTDOWN_ALREADY: - case CREATE_JUST: - break; - default: - break; - } + m_producerDelegate = DefaultMQProducerImpl::create(this, rpcHook); } -SendResult DefaultMQProducer::send(MQMessage& msg, bool bSelectActiveBroker) { - Validators::checkMessage(msg, getMaxMessageSize()); - if (!NameSpaceUtil::hasNameSpace(msg.getTopic(), getNameSpace())) { - MessageAccessor::withNameSpace(msg, getNameSpace()); - } - try { - return sendDefaultImpl(msg, ComMode_SYNC, NULL, bSelectActiveBroker); - } catch (MQException& e) { - LOG_ERROR(e.what()); - throw e; - } - return SendResult(); -} +DefaultMQProducer::~DefaultMQProducer() = default; -void DefaultMQProducer::send(MQMessage& msg, SendCallback* pSendCallback, bool bSelectActiveBroker) { - Validators::checkMessage(msg, getMaxMessageSize()); - if (!NameSpaceUtil::hasNameSpace(msg.getTopic(), getNameSpace())) { - MessageAccessor::withNameSpace(msg, getNameSpace()); - } - try { - sendDefaultImpl(msg, ComMode_ASYNC, pSendCallback, bSelectActiveBroker); - } catch (MQException& e) { - LOG_ERROR(e.what()); - throw e; - } +void DefaultMQProducer::start() { + m_producerDelegate->start(); } -SendResult DefaultMQProducer::send(std::vector& msgs) { - SendResult result; - try { - BatchMessage batchMessage = buildBatchMessage(msgs); - result = sendDefaultImpl(batchMessage, ComMode_SYNC, NULL); - } catch (MQException& e) { - LOG_ERROR(e.what()); - throw e; - } - return result; +void DefaultMQProducer::shutdown() { + m_producerDelegate->shutdown(); } -SendResult DefaultMQProducer::send(std::vector& msgs, const MQMessageQueue& mq) { - SendResult result; - try { - BatchMessage batchMessage = buildBatchMessage(msgs); - result = sendKernelImpl(batchMessage, mq, ComMode_SYNC, NULL); - } catch (MQException& e) { - LOG_ERROR(e.what()); - throw e; - } - return result; +SendResult DefaultMQProducer::send(MQMessagePtr msg) { + return m_producerDelegate->send(msg); } -BatchMessage DefaultMQProducer::buildBatchMessage(std::vector& msgs) { - if (msgs.size() < 1) { - THROW_MQEXCEPTION(MQClientException, "msgs need one message at least", -1); - } - BatchMessage batchMessage; - bool firstFlag = true; - string topic; - bool waitStoreMsgOK = false; - for (auto& msg : msgs) { - Validators::checkMessage(msg, getMaxMessageSize()); - if (!NameSpaceUtil::hasNameSpace(msg.getTopic(), getNameSpace())) { - MessageAccessor::withNameSpace(msg, getNameSpace()); - } - if (firstFlag) { - topic = msg.getTopic(); - waitStoreMsgOK = msg.isWaitStoreMsgOK(); - firstFlag = false; - - if (UtilAll::startsWith_retry(topic)) { - THROW_MQEXCEPTION(MQClientException, "Retry Group is not supported for batching", -1); - } - } else { - if (msg.getDelayTimeLevel() > 0) { - THROW_MQEXCEPTION(MQClientException, "TimeDelayLevel in not supported for batching", -1); - } - if (msg.getTopic() != topic) { - THROW_MQEXCEPTION(MQClientException, "msgs need one message at least", -1); - } - if (msg.isWaitStoreMsgOK() != waitStoreMsgOK) { - THROW_MQEXCEPTION(MQClientException, "msgs need one message at least", -2); - } - } - } - batchMessage.setBody(BatchMessage::encode(msgs)); - batchMessage.setTopic(topic); - batchMessage.setWaitStoreMsgOK(waitStoreMsgOK); - return batchMessage; +SendResult DefaultMQProducer::send(MQMessagePtr msg, long timeout) { + return m_producerDelegate->send(msg, timeout); } -SendResult DefaultMQProducer::send(MQMessage& msg, const MQMessageQueue& mq) { - Validators::checkMessage(msg, getMaxMessageSize()); - if (!NameSpaceUtil::hasNameSpace(msg.getTopic(), getNameSpace())) { - MessageAccessor::withNameSpace(msg, getNameSpace()); - } - if (msg.getTopic() != mq.getTopic()) { - LOG_WARN("message's topic not equal mq's topic"); - } - try { - return sendKernelImpl(msg, mq, ComMode_SYNC, NULL); - } catch (MQException& e) { - LOG_ERROR(e.what()); - throw e; - } - return SendResult(); +SendResult DefaultMQProducer::send(MQMessagePtr msg, const MQMessageQueue& mq) { + return m_producerDelegate->send(msg, mq); } -void DefaultMQProducer::send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* pSendCallback) { - Validators::checkMessage(msg, getMaxMessageSize()); - if (!NameSpaceUtil::hasNameSpace(msg.getTopic(), getNameSpace())) { - MessageAccessor::withNameSpace(msg, getNameSpace()); - } - if (msg.getTopic() != mq.getTopic()) { - LOG_WARN("message's topic not equal mq's topic"); - } - try { - sendKernelImpl(msg, mq, ComMode_ASYNC, pSendCallback); - } catch (MQException& e) { - LOG_ERROR(e.what()); - throw e; - } +SendResult DefaultMQProducer::send(MQMessagePtr msg, const MQMessageQueue& mq, long timeout) { + return m_producerDelegate->send(msg, mq, timeout); } -void DefaultMQProducer::sendOneway(MQMessage& msg, bool bSelectActiveBroker) { - Validators::checkMessage(msg, getMaxMessageSize()); - if (!NameSpaceUtil::hasNameSpace(msg.getTopic(), getNameSpace())) { - MessageAccessor::withNameSpace(msg, getNameSpace()); - } - try { - sendDefaultImpl(msg, ComMode_ONEWAY, NULL, bSelectActiveBroker); - } catch (MQException& e) { - LOG_ERROR(e.what()); - throw e; - } +void DefaultMQProducer::send(MQMessagePtr msg, SendCallback* sendCallback) noexcept { + m_producerDelegate->send(msg, sendCallback, getSendMsgTimeout()); } -void DefaultMQProducer::sendOneway(MQMessage& msg, const MQMessageQueue& mq) { - Validators::checkMessage(msg, getMaxMessageSize()); - if (!NameSpaceUtil::hasNameSpace(msg.getTopic(), getNameSpace())) { - MessageAccessor::withNameSpace(msg, getNameSpace()); - } - if (msg.getTopic() != mq.getTopic()) { - LOG_WARN("message's topic not equal mq's topic"); - } - try { - sendKernelImpl(msg, mq, ComMode_ONEWAY, NULL); - } catch (MQException& e) { - LOG_ERROR(e.what()); - throw e; - } +void DefaultMQProducer::send(MQMessagePtr msg, SendCallback* sendCallback, long timeout) noexcept { + m_producerDelegate->send(msg, sendCallback, timeout); } -SendResult DefaultMQProducer::send(MQMessage& msg, MessageQueueSelector* pSelector, void* arg) { - try { - if (!NameSpaceUtil::hasNameSpace(msg.getTopic(), getNameSpace())) { - MessageAccessor::withNameSpace(msg, getNameSpace()); - } - return sendSelectImpl(msg, pSelector, arg, ComMode_SYNC, NULL); - } catch (MQException& e) { - LOG_ERROR(e.what()); - throw e; - } - return SendResult(); +void DefaultMQProducer::send(MQMessagePtr msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept { + return m_producerDelegate->send(msg, mq, sendCallback); } -SendResult DefaultMQProducer::send(MQMessage& msg, - MessageQueueSelector* pSelector, - void* arg, - int autoRetryTimes, - bool bActiveBroker) { - try { - if (!NameSpaceUtil::hasNameSpace(msg.getTopic(), getNameSpace())) { - MessageAccessor::withNameSpace(msg, getNameSpace()); - } - return sendAutoRetrySelectImpl(msg, pSelector, arg, ComMode_SYNC, NULL, autoRetryTimes, bActiveBroker); - } catch (MQException& e) { - LOG_ERROR(e.what()); - throw e; - } - return SendResult(); +void DefaultMQProducer::send(MQMessagePtr msg, + const MQMessageQueue& mq, + SendCallback* sendCallback, + long timeout) noexcept { + m_producerDelegate->send(msg, mq, sendCallback, timeout); } -void DefaultMQProducer::send(MQMessage& msg, MessageQueueSelector* pSelector, void* arg, SendCallback* pSendCallback) { - try { - if (!NameSpaceUtil::hasNameSpace(msg.getTopic(), getNameSpace())) { - MessageAccessor::withNameSpace(msg, getNameSpace()); - } - sendSelectImpl(msg, pSelector, arg, ComMode_ASYNC, pSendCallback); - } catch (MQException& e) { - LOG_ERROR(e.what()); - throw e; - } +void DefaultMQProducer::sendOneway(MQMessagePtr msg) { + m_producerDelegate->sendOneway(msg); } -void DefaultMQProducer::sendOneway(MQMessage& msg, MessageQueueSelector* pSelector, void* arg) { - try { - if (!NameSpaceUtil::hasNameSpace(msg.getTopic(), getNameSpace())) { - MessageAccessor::withNameSpace(msg, getNameSpace()); - } - sendSelectImpl(msg, pSelector, arg, ComMode_ONEWAY, NULL); - } catch (MQException& e) { - LOG_ERROR(e.what()); - throw e; - } -} - -int DefaultMQProducer::getSendMsgTimeout() const { - return m_sendMsgTimeout; -} - -void DefaultMQProducer::setSendMsgTimeout(int sendMsgTimeout) { - m_sendMsgTimeout = sendMsgTimeout; -} - -int DefaultMQProducer::getCompressMsgBodyOverHowmuch() const { - return m_compressMsgBodyOverHowmuch; +void DefaultMQProducer::sendOneway(MQMessagePtr msg, const MQMessageQueue& mq) { + m_producerDelegate->sendOneway(msg, mq); } -void DefaultMQProducer::setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch) { - m_compressMsgBodyOverHowmuch = compressMsgBodyOverHowmuch; +SendResult DefaultMQProducer::send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) { + return m_producerDelegate->send(msg, selector, arg); } -int DefaultMQProducer::getMaxMessageSize() const { - return m_maxMessageSize; +SendResult DefaultMQProducer::send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg, long timeout) { + return m_producerDelegate->send(msg, selector, arg, timeout); } -void DefaultMQProducer::setMaxMessageSize(int maxMessageSize) { - m_maxMessageSize = maxMessageSize; +void DefaultMQProducer::send(MQMessagePtr msg, + MessageQueueSelector* selector, + void* arg, + SendCallback* sendCallback) noexcept { + return m_producerDelegate->send(msg, selector, arg, sendCallback); } -int DefaultMQProducer::getCompressLevel() const { - return m_compressLevel; +void DefaultMQProducer::send(MQMessagePtr msg, + MessageQueueSelector* selector, + void* arg, + SendCallback* sendCallback, + long timeout) noexcept { + m_producerDelegate->send(msg, selector, arg, sendCallback, timeout); } -void DefaultMQProducer::setCompressLevel(int compressLevel) { - assert((compressLevel >= 0 && compressLevel <= 9) || compressLevel == -1); - - m_compressLevel = compressLevel; +void DefaultMQProducer::sendOneway(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) { + m_producerDelegate->sendOneway(msg, selector, arg); } -// weak_topicPublishInfo( - getFactory()->tryToFindTopicPublishInfo(msg.getTopic(), getSessionCredentials())); - boost::shared_ptr topicPublishInfo(weak_topicPublishInfo.lock()); - if (topicPublishInfo) { - if (times == 1) { - mq_index = topicPublishInfo->getWhichQueue(); - } else { - mq_index++; - } - - SendResult sendResult; - MQMessageQueue mq; - if (bActiveMQ) - mq = topicPublishInfo->selectOneActiveMessageQueue(lastmq, mq_index); - else - mq = topicPublishInfo->selectOneMessageQueue(lastmq, mq_index); - - lastmq = mq; - if (mq.getQueueId() == -1) { - // THROW_MQEXCEPTION(MQClientException, "the MQMessageQueue is - // invalide", -1); - continue; - } - - try { - LOG_DEBUG("send to mq:%s", mq.toString().data()); - sendResult = sendKernelImpl(msg, mq, communicationMode, pSendCallback); - switch (communicationMode) { - case ComMode_ASYNC: - return sendResult; - case ComMode_ONEWAY: - return sendResult; - case ComMode_SYNC: - if (sendResult.getSendStatus() != SEND_OK) { - if (bActiveMQ) { - topicPublishInfo->updateNonServiceMessageQueue(mq, getSendMsgTimeout()); - } - continue; - } - return sendResult; - default: - break; - } - } catch (...) { - LOG_ERROR("send failed of times:%d,brokerName:%s", times, mq.getBrokerName().c_str()); - if (bActiveMQ) { - topicPublishInfo->updateNonServiceMessageQueue(mq, getSendMsgTimeout()); - } - continue; - } - } // end of for - LOG_WARN("Retry many times, still failed"); - } - string info = "No route info of this topic: " + msg.getTopic(); - THROW_MQEXCEPTION(MQClientException, info, -1); -} - -SendResult DefaultMQProducer::sendKernelImpl(MQMessage& msg, - const MQMessageQueue& mq, - int communicationMode, - SendCallback* sendCallback) { - string brokerAddr = getFactory()->findBrokerAddressInPublish(mq.getBrokerName()); - - if (brokerAddr.empty()) { - getFactory()->tryToFindTopicPublishInfo(mq.getTopic(), getSessionCredentials()); - brokerAddr = getFactory()->findBrokerAddressInPublish(mq.getBrokerName()); - } - - if (!brokerAddr.empty()) { - try { - bool isBatchMsg = std::type_index(typeid(msg)) == std::type_index(typeid(BatchMessage)); - // msgId is produced by client, offsetMsgId produced by broker. (same with java sdk) - if (!isBatchMsg) { - string unique_id = StringIdMaker::getInstance().createUniqID(); - msg.setProperty(MQMessage::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX, unique_id); - - // batch does not support compressing right now, - tryToCompressMessage(msg); - } - - LOG_DEBUG("produce before:%s to %s", msg.toString().c_str(), mq.toString().c_str()); - - SendMessageRequestHeader* requestHeader = new SendMessageRequestHeader(); - requestHeader->producerGroup = getGroupName(); - requestHeader->topic = (msg.getTopic()); - requestHeader->defaultTopic = DEFAULT_TOPIC; - requestHeader->defaultTopicQueueNums = 4; - requestHeader->queueId = (mq.getQueueId()); - requestHeader->sysFlag = (msg.getSysFlag()); - requestHeader->bornTimestamp = UtilAll::currentTimeMillis(); - requestHeader->flag = (msg.getFlag()); - requestHeader->consumeRetryTimes = 16; - requestHeader->batch = isBatchMsg; - requestHeader->properties = (MQDecoder::messageProperties2String(msg.getProperties())); - - return getFactory()->getMQClientAPIImpl()->sendMessage(brokerAddr, mq.getBrokerName(), msg, requestHeader, - getSendMsgTimeout(), getRetryTimes4Async(), - communicationMode, sendCallback, getSessionCredentials()); - } catch (MQException& e) { - throw e; - } - } - THROW_MQEXCEPTION(MQClientException, "The broker[" + mq.getBrokerName() + "] not exist", -1); +TransactionSendResult DefaultMQProducer::sendMessageInTransaction(MQMessagePtr msg, void* arg) { + THROW_MQEXCEPTION(MQClientException, "sendMessageInTransaction not implement, please use TransactionMQProducer class", + -1); } -SendResult DefaultMQProducer::sendSelectImpl(MQMessage& msg, - MessageQueueSelector* pSelector, - void* pArg, - int communicationMode, - SendCallback* sendCallback) { - Validators::checkMessage(msg, getMaxMessageSize()); - - boost::weak_ptr weak_topicPublishInfo( - getFactory()->tryToFindTopicPublishInfo(msg.getTopic(), getSessionCredentials())); - boost::shared_ptr topicPublishInfo(weak_topicPublishInfo.lock()); - if (topicPublishInfo) //&& topicPublishInfo->ok()) - { - MQMessageQueue mq = pSelector->select(topicPublishInfo->getMessageQueueList(), msg, pArg); - return sendKernelImpl(msg, mq, communicationMode, sendCallback); - } - THROW_MQEXCEPTION(MQClientException, "No route info for this topic", -1); +SendResult DefaultMQProducer::send(std::vector& msgs) { + return m_producerDelegate->send(msgs); } -SendResult DefaultMQProducer::sendAutoRetrySelectImpl(MQMessage& msg, - MessageQueueSelector* pSelector, - void* pArg, - int communicationMode, - SendCallback* pSendCallback, - int autoRetryTimes, - bool bActiveMQ) { - Validators::checkMessage(msg, getMaxMessageSize()); - - MQMessageQueue lastmq; - MQMessageQueue mq; - int mq_index = 0; - for (int times = 1; times <= autoRetryTimes + 1; times++) { - boost::weak_ptr weak_topicPublishInfo( - getFactory()->tryToFindTopicPublishInfo(msg.getTopic(), getSessionCredentials())); - boost::shared_ptr topicPublishInfo(weak_topicPublishInfo.lock()); - if (topicPublishInfo) { - SendResult sendResult; - if (times == 1) { - // always send to selected MQ firstly, evenif bActiveMQ was setted to true - mq = pSelector->select(topicPublishInfo->getMessageQueueList(), msg, pArg); - lastmq = mq; - } else { - LOG_INFO("sendAutoRetrySelectImpl with times:%d", times); - std::vector mqs(topicPublishInfo->getMessageQueueList()); - for (size_t i = 0; i < mqs.size(); i++) { - if (mqs[i] == lastmq) - mq_index = i; - } - if (bActiveMQ) - mq = topicPublishInfo->selectOneActiveMessageQueue(lastmq, mq_index); - else - mq = topicPublishInfo->selectOneMessageQueue(lastmq, mq_index); - lastmq = mq; - if (mq.getQueueId() == -1) { - // THROW_MQEXCEPTION(MQClientException, "the MQMessageQueue is - // invalide", -1); - continue; - } - } - - try { - LOG_DEBUG("send to broker:%s", mq.toString().c_str()); - sendResult = sendKernelImpl(msg, mq, communicationMode, pSendCallback); - switch (communicationMode) { - case ComMode_ASYNC: - return sendResult; - case ComMode_ONEWAY: - return sendResult; - case ComMode_SYNC: - if (sendResult.getSendStatus() != SEND_OK) { - if (bActiveMQ) { - topicPublishInfo->updateNonServiceMessageQueue(mq, getSendMsgTimeout()); - } - continue; - } - return sendResult; - default: - break; - } - } catch (...) { - LOG_ERROR("send failed of times:%d,mq:%s", times, mq.toString().c_str()); - if (bActiveMQ) { - topicPublishInfo->updateNonServiceMessageQueue(mq, getSendMsgTimeout()); - } - continue; - } - } // end of for - LOG_WARN("Retry many times, still failed"); - } - THROW_MQEXCEPTION(MQClientException, "No route info of this topic, ", -1); +SendResult DefaultMQProducer::send(std::vector& msgs, long timeout) { + return m_producerDelegate->send(msgs, timeout); } -bool DefaultMQProducer::tryToCompressMessage(MQMessage& msg) { - int sysFlag = msg.getSysFlag(); - if ((sysFlag & MessageSysFlag::CompressedFlag) == MessageSysFlag::CompressedFlag) { - return true; - } - - string body = msg.getBody(); - if ((int)body.length() >= getCompressMsgBodyOverHowmuch()) { - string outBody; - if (UtilAll::deflate(body, outBody, getCompressLevel())) { - msg.setBody(outBody); - msg.setSysFlag(sysFlag | MessageSysFlag::CompressedFlag); - return true; - } - } - - return false; +SendResult DefaultMQProducer::send(std::vector& msgs, const MQMessageQueue& mq) { + return m_producerDelegate->send(msgs, mq); } -int DefaultMQProducer::getRetryTimes() const { - return m_retryTimes; +SendResult DefaultMQProducer::send(std::vector& msgs, const MQMessageQueue& mq, long timeout) { + return m_producerDelegate->send(msgs, mq, timeout); } -void DefaultMQProducer::setRetryTimes(int times) { - if (times <= 0) { - LOG_WARN("set retry times illegal, use default value:5"); - return; - } - - if (times > 15) { - LOG_WARN("set retry times illegal, use max value:15"); - m_retryTimes = 15; - return; - } - LOG_WARN("set retry times to:%d", times); - m_retryTimes = times; +bool DefaultMQProducer::isSendLatencyFaultEnable() const { + return dynamic_cast(m_producerDelegate.get())->isSendLatencyFaultEnable(); } -int DefaultMQProducer::getRetryTimes4Async() const { - return m_retryTimes4Async; +void DefaultMQProducer::setSendLatencyFaultEnable(bool sendLatencyFaultEnable) { + dynamic_cast(m_producerDelegate.get())->setSendLatencyFaultEnable(sendLatencyFaultEnable); } -void DefaultMQProducer::setRetryTimes4Async(int times) { - if (times <= 0) { - LOG_WARN("set retry times illegal, use default value:1"); - m_retryTimes4Async = 1; - return; - } - - if (times > 15) { - LOG_WARN("set retry times illegal, use max value:15"); - m_retryTimes4Async = 15; - return; - } - LOG_INFO("set retry times to:%d", times); - m_retryTimes4Async = times; +void DefaultMQProducer::setRPCHook(std::shared_ptr rpcHook) { + dynamic_cast(m_producerDelegate.get())->setRPCHook(rpcHook); } -// we should deal with name space before producer start. -bool DefaultMQProducer::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); - } - return true; -} -// +#include + +#ifndef WIN32 +#include +#endif + +#include "CommandHeader.h" +#include "CommunicationMode.h" +#include "Logging.h" +#include "MQClientAPIImpl.h" +#include "MQClientException.h" +#include "MQClientInstance.h" +#include "MQClientManager.h" +#include "MQDecoder.h" +#include "MQFaultStrategy.h" +#include "MQProtos.h" +#include "MessageBatch.h" +#include "MessageClientIDSetter.h" +#include "MessageSysFlag.h" +#include "TopicPublishInfo.h" +#include "TransactionMQProducer.h" +#include "Validators.h" + +namespace rocketmq { + +DefaultMQProducerImpl::DefaultMQProducerImpl(DefaultMQProducerConfig* config) + : DefaultMQProducerImpl(config, nullptr) {} + +DefaultMQProducerImpl::DefaultMQProducerImpl(DefaultMQProducerConfig* config, std::shared_ptr rpcHook) + : MQClientImpl(config, rpcHook), + m_producerConfig(config), + m_mqFaultStrategy(new MQFaultStrategy()), + m_checkTransactionExecutor(nullptr) {} + +DefaultMQProducerImpl::~DefaultMQProducerImpl() = default; + +void DefaultMQProducerImpl::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 + + switch (m_serviceState) { + case CREATE_JUST: { + m_serviceState = START_FAILED; + + m_producerConfig->changeInstanceNameToPID(); + + LOG_INFO_NEW("DefaultMQProducerImpl:{} start", m_producerConfig->getGroupName()); + + MQClientImpl::start(); + + bool registerOK = m_clientInstance->registerProducer(m_producerConfig->getGroupName(), this); + if (!registerOK) { + m_serviceState = CREATE_JUST; + THROW_MQEXCEPTION(MQClientException, + "The producer group[" + m_producerConfig->getGroupName() + + "] has been created before, specify another name please.", + -1); + } + + m_clientInstance->start(); + LOG_INFO_NEW("the producer [{}] start OK.", m_producerConfig->getGroupName()); + m_serviceState = RUNNING; + break; + } + case RUNNING: + case START_FAILED: + case SHUTDOWN_ALREADY: + break; + default: + break; + } + + m_clientInstance->sendHeartbeatToAllBrokerWithLock(); +} + +void DefaultMQProducerImpl::shutdown() { + switch (m_serviceState) { + case RUNNING: { + LOG_INFO("DefaultMQProducerImpl shutdown"); + m_clientInstance->unregisterProducer(m_producerConfig->getGroupName()); + m_clientInstance->shutdown(); + + m_serviceState = SHUTDOWN_ALREADY; + break; + } + case SHUTDOWN_ALREADY: + case CREATE_JUST: + break; + default: + break; + } +} + +void DefaultMQProducerImpl::initTransactionEnv() { + if (nullptr == m_checkTransactionExecutor) { + m_checkTransactionExecutor.reset(new thread_pool_executor(1, false)); + } + m_checkTransactionExecutor->startup(); +} + +void DefaultMQProducerImpl::destroyTransactionEnv() { + m_checkTransactionExecutor->shutdown(); +} + +SendResult DefaultMQProducerImpl::send(MQMessagePtr msg) { + return send(msg, m_producerConfig->getSendMsgTimeout()); +} + +SendResult DefaultMQProducerImpl::send(MQMessagePtr msg, long timeout) { + try { + std::unique_ptr sendResult(sendDefaultImpl(msg, ComMode_SYNC, nullptr, timeout)); + return *sendResult; + } catch (MQException& e) { + LOG_ERROR(e.what()); + throw e; + } +} + +SendResult DefaultMQProducerImpl::send(MQMessagePtr msg, const MQMessageQueue& mq) { + return send(msg, mq, m_producerConfig->getSendMsgTimeout()); +} + +SendResult DefaultMQProducerImpl::send(MQMessagePtr msg, const MQMessageQueue& mq, long timeout) { + Validators::checkMessage(*msg, m_producerConfig->getMaxMessageSize()); + + if (msg->getTopic() != mq.getTopic()) { + THROW_MQEXCEPTION(MQClientException, "message's topic not equal mq's topic", -1); + } + + try { + std::unique_ptr sendResult(sendKernelImpl(msg, mq, ComMode_SYNC, nullptr, nullptr, timeout)); + return *sendResult; + } catch (MQException& e) { + LOG_ERROR(e.what()); + throw e; + } +} + +void DefaultMQProducerImpl::send(MQMessagePtr msg, SendCallback* sendCallback) noexcept { + return send(msg, sendCallback, m_producerConfig->getSendMsgTimeout()); +} + +void DefaultMQProducerImpl::send(MQMessagePtr msg, SendCallback* sendCallback, long timeout) noexcept { + try { + (void)sendDefaultImpl(msg, ComMode_ASYNC, sendCallback, timeout); + } catch (MQException& e) { + LOG_ERROR(e.what()); + sendCallback->onException(e); + if (sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_ATUO_DELETE) { + deleteAndZero(sendCallback); + } + } catch (std::exception& e) { + LOG_FATAL_NEW("[BUG] encounter unexcepted exception: {}", e.what()); + exit(-1); + } +} + +void DefaultMQProducerImpl::send(MQMessagePtr msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept { + return send(msg, mq, sendCallback, m_producerConfig->getSendMsgTimeout()); +} + +void DefaultMQProducerImpl::send(MQMessagePtr msg, + const MQMessageQueue& mq, + SendCallback* sendCallback, + long timeout) noexcept { + try { + Validators::checkMessage(*msg, m_producerConfig->getMaxMessageSize()); + + if (msg->getTopic() != mq.getTopic()) { + THROW_MQEXCEPTION(MQClientException, "message's topic not equal mq's topic", -1); + } + + try { + sendKernelImpl(msg, mq, ComMode_ASYNC, sendCallback, nullptr, timeout); + } catch (MQBrokerException& e) { + std::string info = std::string("unknown exception, ") + e.what(); + THROW_MQEXCEPTION(MQClientException, info, e.GetError()); + } + } catch (MQException& e) { + LOG_ERROR(e.what()); + sendCallback->onException(e); + if (sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_ATUO_DELETE) { + deleteAndZero(sendCallback); + } + } catch (std::exception& e) { + LOG_FATAL_NEW("[BUG] encounter unexcepted exception: {}", e.what()); + exit(-1); + } +} + +void DefaultMQProducerImpl::sendOneway(MQMessagePtr msg) { + try { + sendDefaultImpl(msg, ComMode_ONEWAY, nullptr, m_producerConfig->getSendMsgTimeout()); + } catch (MQBrokerException e) { + std::string info = std::string("unknown exception, ") + e.what(); + THROW_MQEXCEPTION(MQClientException, info, e.GetError()); + } +} + +void DefaultMQProducerImpl::sendOneway(MQMessagePtr msg, const MQMessageQueue& mq) { + Validators::checkMessage(*msg, m_producerConfig->getMaxMessageSize()); + + if (msg->getTopic() != mq.getTopic()) { + THROW_MQEXCEPTION(MQClientException, "message's topic not equal mq's topic", -1); + } + + try { + sendKernelImpl(msg, mq, ComMode_ONEWAY, nullptr, nullptr, m_producerConfig->getSendMsgTimeout()); + } catch (MQBrokerException e) { + std::string info = std::string("unknown exception, ") + e.what(); + THROW_MQEXCEPTION(MQClientException, info, e.GetError()); + } +} + +SendResult DefaultMQProducerImpl::send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) { + return send(msg, selector, arg, m_producerConfig->getSendMsgTimeout()); +} + +SendResult DefaultMQProducerImpl::send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg, long timeout) { + try { + std::unique_ptr result(sendSelectImpl(msg, selector, arg, ComMode_SYNC, nullptr, timeout)); + return *result.get(); + } catch (MQException& e) { + LOG_ERROR(e.what()); + throw e; + } +} + +void DefaultMQProducerImpl::send(MQMessagePtr msg, + MessageQueueSelector* selector, + void* arg, + SendCallback* sendCallback) noexcept { + return send(msg, selector, arg, sendCallback, m_producerConfig->getSendMsgTimeout()); +} + +void DefaultMQProducerImpl::send(MQMessagePtr msg, + MessageQueueSelector* selector, + void* arg, + SendCallback* sendCallback, + long timeout) noexcept { + try { + try { + sendSelectImpl(msg, selector, arg, ComMode_ASYNC, sendCallback, timeout); + } catch (MQBrokerException& e) { + std::string info = std::string("unknown exception, ") + e.what(); + THROW_MQEXCEPTION(MQClientException, info, e.GetError()); + } + } catch (MQException& e) { + LOG_ERROR(e.what()); + sendCallback->onException(e); + if (sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_ATUO_DELETE) { + deleteAndZero(sendCallback); + } + } catch (std::exception& e) { + LOG_FATAL_NEW("[BUG] encounter unexcepted exception: {}", e.what()); + exit(-1); + } +} + +void DefaultMQProducerImpl::sendOneway(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) { + try { + sendSelectImpl(msg, selector, arg, ComMode_ONEWAY, nullptr, m_producerConfig->getSendMsgTimeout()); + } catch (MQBrokerException e) { + std::string info = std::string("unknown exception, ") + e.what(); + THROW_MQEXCEPTION(MQClientException, info, e.GetError()); + } +} + +TransactionSendResult DefaultMQProducerImpl::sendMessageInTransaction(MQMessagePtr msg, void* arg) { + try { + std::unique_ptr sendResult( + sendMessageInTransactionImpl(msg, arg, m_producerConfig->getSendMsgTimeout())); + return *sendResult; + } catch (MQException& e) { + LOG_ERROR(e.what()); + throw e; + } +} + +SendResult DefaultMQProducerImpl::send(std::vector& msgs) { + std::unique_ptr batchMessage(batch(msgs)); + return send(batchMessage.get()); +} + +SendResult DefaultMQProducerImpl::send(std::vector& msgs, long timeout) { + std::unique_ptr batchMessage(batch(msgs)); + return send(batchMessage.get(), timeout); +} + +SendResult DefaultMQProducerImpl::send(std::vector& msgs, const MQMessageQueue& mq) { + std::unique_ptr batchMessage(batch(msgs)); + return send(batchMessage.get(), mq); +} + +SendResult DefaultMQProducerImpl::send(std::vector& msgs, const MQMessageQueue& mq, long timeout) { + std::unique_ptr batchMessage(batch(msgs)); + return send(batchMessage.get(), mq, timeout); +} + +MessageBatch* DefaultMQProducerImpl::batch(std::vector& msgs) { + if (msgs.size() < 1) { + THROW_MQEXCEPTION(MQClientException, "msgs need one message at least", -1); + } + + try { + MessageBatch* msgBatch = MessageBatch::generateFromList(msgs); + for (auto& message : msgBatch->getMessages()) { + Validators::checkMessage(*message, m_producerConfig->getMaxMessageSize()); + MessageClientIDSetter::setUniqID(*message); + } + msgBatch->setBody(msgBatch->encode()); + return msgBatch; + } catch (std::exception& e) { + THROW_MQEXCEPTION(MQClientException, "Failed to initiate the MessageBatch", -1); + } +} + +const MQMessageQueue& DefaultMQProducerImpl::selectOneMessageQueue(TopicPublishInfo* tpInfo, + const std::string& lastBrokerName) { + return m_mqFaultStrategy->selectOneMessageQueue(tpInfo, lastBrokerName); +} + +void DefaultMQProducerImpl::updateFaultItem(const std::string& brokerName, const long currentLatency, bool isolation) { + m_mqFaultStrategy->updateFaultItem(brokerName, currentLatency, isolation); +} + +SendResult* DefaultMQProducerImpl::sendDefaultImpl(MQMessagePtr msg, + CommunicationMode communicationMode, + SendCallback* sendCallback, + long timeout) { + Validators::checkMessage(*msg, m_producerConfig->getMaxMessageSize()); + + uint64_t beginTimestampFirst = UtilAll::currentTimeMillis(); + uint64_t beginTimestampPrev = beginTimestampFirst; + uint64_t endTimestamp = beginTimestampFirst; + TopicPublishInfoPtr topicPublishInfo = m_clientInstance->tryToFindTopicPublishInfo(msg->getTopic()); + if (topicPublishInfo != nullptr && topicPublishInfo->ok()) { + bool callTimeout = false; + std::unique_ptr sendResult; + int timesTotal = communicationMode == CommunicationMode::ComMode_SYNC ? 1 + m_producerConfig->getRetryTimes() : 1; + int times = 0; + std::string lastBrokerName; + for (; times < timesTotal; times++) { + const auto& mq = selectOneMessageQueue(topicPublishInfo.get(), lastBrokerName); + lastBrokerName = mq.getBrokerName(); + + try { + LOG_DEBUG("send to mq:%s", mq.toString().data()); + + beginTimestampPrev = UtilAll::currentTimeMillis(); + if (times > 0) { + // TODO: Reset topic with namespace during resend. + } + long costTime = beginTimestampPrev - beginTimestampFirst; + if (timeout < costTime) { + callTimeout = true; + break; + } + + sendResult.reset( + sendKernelImpl(msg, mq, communicationMode, sendCallback, topicPublishInfo, timeout - costTime)); + endTimestamp = UtilAll::currentTimeMillis(); + updateFaultItem(mq.getBrokerName(), endTimestamp - beginTimestampPrev, false); + switch (communicationMode) { + case ComMode_ASYNC: + return nullptr; + case ComMode_ONEWAY: + return nullptr; + case ComMode_SYNC: + if (sendResult->getSendStatus() != SEND_OK) { + if (m_producerConfig->isRetryAnotherBrokerWhenNotStoreOK()) { + continue; + } + } + + return sendResult.release(); + default: + break; + } + } catch (std::exception& e) { + // TODO: 区分异常类型 + endTimestamp = UtilAll::currentTimeMillis(); + updateFaultItem(mq.getBrokerName(), endTimestamp - beginTimestampPrev, true); + LOG_ERROR_NEW("send failed of times:{}, brokerName:{}. exception:{}", times, mq.getBrokerName(), e.what()); + continue; + } + + } // end of for + + if (sendResult != nullptr) { + return sendResult.release(); + } + + std::string info = "Send [" + UtilAll::to_string(times) + "] times, still failed, cost [" + + UtilAll::to_string(UtilAll::currentTimeMillis() - beginTimestampFirst) + + "]ms, Topic: " + msg->getTopic(); + THROW_MQEXCEPTION(MQClientException, info, -1); + } + + THROW_MQEXCEPTION(MQClientException, "No route info of this topic: " + msg->getTopic(), -1); +} + +SendResult* DefaultMQProducerImpl::sendKernelImpl(MQMessagePtr msg, + const MQMessageQueue& mq, + CommunicationMode communicationMode, + SendCallback* sendCallback, + TopicPublishInfoPtr topicPublishInfo, + long timeout) { + uint64_t beginStartTime = UtilAll::currentTimeMillis(); + std::string brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); + if (brokerAddr.empty()) { + m_clientInstance->tryToFindTopicPublishInfo(mq.getTopic()); + brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); + } + + if (!brokerAddr.empty()) { + try { + // for MessageBatch, ID has been set in the generating process + if (!msg->isBatch()) { + // msgId is produced by client, offsetMsgId produced by broker. (same with java sdk) + MessageClientIDSetter::setUniqID(*msg); + } + + int sysFlag = 0; + bool msgBodyCompressed = false; + if (tryToCompressMessage(*msg)) { + sysFlag |= MessageSysFlag::CompressedFlag; + msgBodyCompressed = true; + } + + const auto& tranMsg = msg->getProperty(MQMessageConst::PROPERTY_TRANSACTION_PREPARED); + if (UtilAll::stob(tranMsg)) { + sysFlag |= MessageSysFlag::TransactionPreparedType; + } + + // TOOD: send message hook + + std::unique_ptr requestHeader(new SendMessageRequestHeader()); + requestHeader->producerGroup = m_producerConfig->getGroupName(); + requestHeader->topic = msg->getTopic(); + requestHeader->defaultTopic = AUTO_CREATE_TOPIC_KEY_TOPIC; + requestHeader->defaultTopicQueueNums = 4; + requestHeader->queueId = mq.getQueueId(); + requestHeader->sysFlag = sysFlag; + requestHeader->bornTimestamp = UtilAll::currentTimeMillis(); + requestHeader->flag = msg->getFlag(); + requestHeader->properties = MQDecoder::messageProperties2String(msg->getProperties()); + requestHeader->reconsumeTimes = 0; + requestHeader->unitMode = false; + requestHeader->batch = msg->isBatch(); + + if (UtilAll::isRetryTopic(mq.getTopic())) { + const auto& reconsumeTimes = MessageAccessor::getReconsumeTime(*msg); + if (!reconsumeTimes.empty()) { + requestHeader->reconsumeTimes = std::stoi(reconsumeTimes); + MessageAccessor::clearProperty(*msg, MQMessageConst::PROPERTY_RECONSUME_TIME); + } + + const auto& maxReconsumeTimes = MessageAccessor::getMaxReconsumeTimes(*msg); + if (!maxReconsumeTimes.empty()) { + requestHeader->maxReconsumeTimes = std::stoi(maxReconsumeTimes); + MessageAccessor::clearProperty(*msg, MQMessageConst::PROPERTY_MAX_RECONSUME_TIMES); + } + } + + SendResult* sendResult = nullptr; + switch (communicationMode) { + case ComMode_ASYNC: { + long costTimeAsync = UtilAll::currentTimeMillis() - beginStartTime; + if (timeout < costTimeAsync) { + THROW_MQEXCEPTION(RemotingTooMuchRequestException, "sendKernelImpl call timeout", -1); + } + sendResult = m_clientInstance->getMQClientAPIImpl()->sendMessage( + brokerAddr, mq.getBrokerName(), msg, std::move(requestHeader), timeout, communicationMode, sendCallback, + topicPublishInfo, m_clientInstance, m_producerConfig->getRetryTimes4Async(), shared_from_this()); + } break; + case ComMode_ONEWAY: + case ComMode_SYNC: { + long costTimeSync = UtilAll::currentTimeMillis() - beginStartTime; + if (timeout < costTimeSync) { + THROW_MQEXCEPTION(RemotingTooMuchRequestException, "sendKernelImpl call timeout", -1); + } + sendResult = m_clientInstance->getMQClientAPIImpl()->sendMessage(brokerAddr, mq.getBrokerName(), msg, + std::move(requestHeader), timeout, + communicationMode, shared_from_this()); + } break; + default: + assert(false); + break; + } + + return sendResult; + } catch (MQException& e) { + throw e; + } + } + + THROW_MQEXCEPTION(MQClientException, "The broker[" + mq.getBrokerName() + "] not exist", -1); +} + +SendResult* DefaultMQProducerImpl::sendSelectImpl(MQMessagePtr msg, + MessageQueueSelector* selector, + void* arg, + CommunicationMode communicationMode, + SendCallback* sendCallback, + long timeout) { + auto beginStartTime = UtilAll::currentTimeMillis(); + Validators::checkMessage(*msg, m_producerConfig->getMaxMessageSize()); + + TopicPublishInfoPtr topicPublishInfo = m_clientInstance->tryToFindTopicPublishInfo(msg->getTopic()); + if (topicPublishInfo != nullptr && topicPublishInfo->ok()) { + MQMessageQueue mq = selector->select(topicPublishInfo->getMessageQueueList(), *msg, arg); + + auto costTime = UtilAll::currentTimeMillis() - beginStartTime; + if (timeout < costTime) { + THROW_MQEXCEPTION(RemotingTooMuchRequestException, "sendSelectImpl call timeout", -1); + } + + return sendKernelImpl(msg, mq, communicationMode, sendCallback, nullptr, timeout - costTime); + } + + std::string info = std::string("No route info for this topic, ") + msg->getTopic(); + THROW_MQEXCEPTION(MQClientException, info, -1); +} + +TransactionSendResult* DefaultMQProducerImpl::sendMessageInTransactionImpl(MQMessagePtr msg, void* arg, long timeout) { + auto* transactionListener = getCheckListener(); + if (nullptr == transactionListener) { + THROW_MQEXCEPTION(MQClientException, "transactionListener is null", -1); + } + + std::unique_ptr sendResult; + MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_TRANSACTION_PREPARED, "true"); + MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_PRODUCER_GROUP, m_producerConfig->getGroupName()); + try { + sendResult.reset(sendDefaultImpl(msg, ComMode_SYNC, nullptr, timeout)); + } catch (MQException& e) { + THROW_MQEXCEPTION(MQClientException, "send message Exception", -1); + } + + LocalTransactionState localTransactionState = LocalTransactionState::UNKNOWN; + std::exception_ptr localException; + switch (sendResult->getSendStatus()) { + case SendStatus::SEND_OK: + try { + if (!sendResult->getTransactionId().empty()) { + msg->putProperty("__transactionId__", sendResult->getTransactionId()); + } + const auto& transactionId = msg->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX); + if (!transactionId.empty()) { + msg->setTransactionId(transactionId); + } + localTransactionState = transactionListener->executeLocalTransaction(*msg, arg); + if (localTransactionState != LocalTransactionState::COMMIT_MESSAGE) { + LOG_INFO_NEW("executeLocalTransaction return not COMMIT_MESSAGE, msg:{}", msg->toString()); + } + } catch (MQException& e) { + LOG_INFO_NEW("executeLocalTransaction exception, msg:{}", msg->toString()); + localException = std::current_exception(); + } + break; + case SendStatus::SEND_FLUSH_DISK_TIMEOUT: + case SendStatus::SEND_FLUSH_SLAVE_TIMEOUT: + case SendStatus::SEND_SLAVE_NOT_AVAILABLE: + localTransactionState = LocalTransactionState::ROLLBACK_MESSAGE; + LOG_WARN_NEW("sendMessageInTransaction, send not ok, rollback, result:{}", sendResult->toString()); + break; + default: + break; + } + + try { + endTransaction(*sendResult, localTransactionState, localException); + } catch (MQException& e) { + LOG_WARN_NEW("local transaction execute {}, but end broker transaction failed: {}", localTransactionState, + e.what()); + } + + // FIXME: setTransactionId will cause OOM? + TransactionSendResult* transactionSendResult = new TransactionSendResult(*sendResult.get()); + transactionSendResult->setTransactionId(msg->getTransactionId()); + transactionSendResult->setLocalTransactionState(localTransactionState); + return transactionSendResult; +} + +TransactionListener* DefaultMQProducerImpl::getCheckListener() { + if (std::type_index(typeid(*m_producerConfig)) == std::type_index(typeid(TransactionMQProducer))) { + auto* producer = static_cast(m_producerConfig); + return producer->getTransactionListener(); + } + return nullptr; +}; + +void DefaultMQProducerImpl::checkTransactionState(const std::string& addr, + MQMessageExtPtr2 msg, + CheckTransactionStateRequestHeader* checkRequestHeader) { + long tranStateTableOffset = checkRequestHeader->tranStateTableOffset; + long commitLogOffset = checkRequestHeader->commitLogOffset; + std::string msgId = checkRequestHeader->msgId; + std::string transactionId = checkRequestHeader->transactionId; + std::string offsetMsgId = checkRequestHeader->offsetMsgId; + + m_checkTransactionExecutor->submit(std::bind(&DefaultMQProducerImpl::checkTransactionStateImpl, this, addr, msg, + tranStateTableOffset, commitLogOffset, msgId, transactionId, + offsetMsgId)); +} + +void DefaultMQProducerImpl::checkTransactionStateImpl(const std::string& addr, + MQMessageExtPtr2 message, + long tranStateTableOffset, + long commitLogOffset, + const std::string& msgId, + const std::string& transactionId, + const std::string& offsetMsgId) { + auto* transactionCheckListener = getCheckListener(); + if (nullptr == transactionCheckListener) { + LOG_WARN_NEW("CheckTransactionState, pick transactionCheckListener by group[{}] failed", + m_producerConfig->getGroupName()); + return; + } + + LocalTransactionState localTransactionState = UNKNOWN; + std::exception_ptr exception; + try { + localTransactionState = transactionCheckListener->checkLocalTransaction(*message); + } catch (MQException& e) { + LOG_ERROR_NEW("Broker call checkTransactionState, but checkLocalTransactionState exception, {}", e.what()); + exception = std::current_exception(); + } + + EndTransactionRequestHeader* endHeader = new EndTransactionRequestHeader(); + endHeader->commitLogOffset = commitLogOffset; + endHeader->producerGroup = m_producerConfig->getGroupName(); + endHeader->tranStateTableOffset = tranStateTableOffset; + endHeader->fromTransactionCheck = true; + + std::string uniqueKey = message->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX); + if (uniqueKey.empty()) { + uniqueKey = message->getMsgId(); + } + + endHeader->msgId = uniqueKey; + endHeader->transactionId = transactionId; + switch (localTransactionState) { + case COMMIT_MESSAGE: + endHeader->commitOrRollback = MessageSysFlag::TransactionCommitType; + break; + case ROLLBACK_MESSAGE: + endHeader->commitOrRollback = MessageSysFlag::TransactionRollbackType; + LOG_WARN_NEW("when broker check, client rollback this transaction, {}", endHeader->toString()); + break; + case UNKNOWN: + endHeader->commitOrRollback = MessageSysFlag::TransactionNotType; + LOG_WARN_NEW("when broker check, client does not know this transaction state, {}", endHeader->toString()); + break; + default: + break; + } + + std::string remark; + if (exception) { + remark = "checkLocalTransactionState Exception: " + UtilAll::to_string(exception); + } + + try { + m_clientInstance->getMQClientAPIImpl()->endTransactionOneway(addr, endHeader, remark); + } catch (std::exception& e) { + LOG_ERROR_NEW("endTransactionOneway exception: {}", e.what()); + } +} + +void DefaultMQProducerImpl::endTransaction(SendResult& sendResult, + LocalTransactionState localTransactionState, + std::exception_ptr& localException) { + MQMessageId id; + if (!sendResult.getOffsetMsgId().empty()) { + id = MQDecoder::decodeMessageId(sendResult.getOffsetMsgId()); + } else { + id = MQDecoder::decodeMessageId(sendResult.getMsgId()); + } + const auto& transactionId = sendResult.getTransactionId(); + std::string brokerAddr = m_clientInstance->findBrokerAddressInPublish(sendResult.getMessageQueue().getBrokerName()); + EndTransactionRequestHeader* requestHeader = new EndTransactionRequestHeader(); + requestHeader->transactionId = transactionId; + requestHeader->commitLogOffset = id.getOffset(); + switch (localTransactionState) { + case COMMIT_MESSAGE: + requestHeader->commitOrRollback = MessageSysFlag::TransactionCommitType; + break; + case ROLLBACK_MESSAGE: + requestHeader->commitOrRollback = MessageSysFlag::TransactionRollbackType; + break; + case UNKNOWN: + requestHeader->commitOrRollback = MessageSysFlag::TransactionNotType; + break; + default: + break; + } + + requestHeader->producerGroup = m_producerConfig->getGroupName(); + requestHeader->tranStateTableOffset = sendResult.getQueueOffset(); + requestHeader->msgId = sendResult.getMsgId(); + + std::string remark = + localException ? ("executeLocalTransactionBranch exception: " + UtilAll::to_string(localException)) : null; + + m_clientInstance->getMQClientAPIImpl()->endTransactionOneway(brokerAddr, requestHeader, remark); +} + +bool DefaultMQProducerImpl::tryToCompressMessage(MQMessage& msg) { + if (msg.isBatch()) { + // batch dose not support compressing right now + return false; + } + + // already compressed + if (UtilAll::stob(msg.getProperty(MQMessageConst::PROPERTY_ALREADY_COMPRESSED_FLAG))) { + return true; + } + + const auto& body = msg.getBody(); + if (body.length() >= m_producerConfig->getCompressMsgBodyOverHowmuch()) { + std::string outBody; + if (UtilAll::deflate(body, outBody, m_producerConfig->getCompressLevel())) { + msg.setBody(std::move(outBody)); + msg.putProperty(MQMessageConst::PROPERTY_ALREADY_COMPRESSED_FLAG, "true"); + return true; + } + } + + return false; +} + +bool DefaultMQProducerImpl::isSendLatencyFaultEnable() const { + return m_mqFaultStrategy->isSendLatencyFaultEnable(); +} + +void DefaultMQProducerImpl::setSendLatencyFaultEnable(bool sendLatencyFaultEnable) { + m_mqFaultStrategy->setSendLatencyFaultEnable(sendLatencyFaultEnable); +} + +} // namespace rocketmq diff --git a/src/producer/DefaultMQProducerImpl.h b/src/producer/DefaultMQProducerImpl.h new file mode 100644 index 000000000..990763aa3 --- /dev/null +++ b/src/producer/DefaultMQProducerImpl.h @@ -0,0 +1,155 @@ +/* + * 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 __DEFAULT_MQ_PRODUCER_IMPL_H__ +#define __DEFAULT_MQ_PRODUCER_IMPL_H__ + +#include "CommunicationMode.h" +#include "DefaultMQProducer.h" +#include "MQClientImpl.h" +#include "MQProducerInner.h" +#include "MessageBatch.h" + +namespace rocketmq { + +class TopicPublishInfo; +class MQFaultStrategy; +class thread_pool_executor; + +class DefaultMQProducerImpl; +typedef std::shared_ptr DefaultMQProducerImplPtr; + +class DefaultMQProducerImpl : public std::enable_shared_from_this, + public MQProducer, + public MQClientImpl, + public MQProducerInner { + public: + static DefaultMQProducerImplPtr create(DefaultMQProducerConfig* config, RPCHookPtr rpcHook = nullptr) { + if (nullptr == rpcHook) { + return DefaultMQProducerImplPtr(new DefaultMQProducerImpl(config)); + } else { + return DefaultMQProducerImplPtr(new DefaultMQProducerImpl(config, rpcHook)); + } + } + + private: + DefaultMQProducerImpl(DefaultMQProducerConfig* config); + DefaultMQProducerImpl(DefaultMQProducerConfig* config, RPCHookPtr rpcHook); + + public: + virtual ~DefaultMQProducerImpl(); + + public: // MQProducer + void start() override; + void shutdown() override; + + // Sync: caller will be responsible for the lifecycle of messages. + SendResult send(MQMessagePtr msg) override; + SendResult send(MQMessagePtr msg, long timeout) override; + SendResult send(MQMessagePtr msg, const MQMessageQueue& mq) override; + SendResult send(MQMessagePtr msg, const MQMessageQueue& mq, long timeout) override; + + // Async: don't delete msg object, until callback occur. + void send(MQMessagePtr msg, SendCallback* sendCallback) noexcept override; + void send(MQMessagePtr msg, SendCallback* sendCallback, long timeout) noexcept override; + void send(MQMessagePtr msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept override; + void send(MQMessagePtr msg, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) noexcept override; + + // Oneyway: same as sync send, but don't care its result. + void sendOneway(MQMessagePtr msg) override; + void sendOneway(MQMessagePtr msg, const MQMessageQueue& mq) override; + + // Select + SendResult send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) override; + SendResult send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg, long timeout) override; + void send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg, SendCallback* sendCallback) noexcept override; + void send(MQMessagePtr msg, + MessageQueueSelector* selector, + void* arg, + SendCallback* sendCallback, + long timeout) noexcept override; + void sendOneway(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) override; + + // Transaction + TransactionSendResult sendMessageInTransaction(MQMessagePtr msg, void* arg) override; + + // Batch: power by sync send, caller will be responsible for the lifecycle of messages. + SendResult send(std::vector& msgs) override; + SendResult send(std::vector& msgs, long timeout) override; + SendResult send(std::vector& msgs, const MQMessageQueue& mq) override; + SendResult send(std::vector& msgs, const MQMessageQueue& mq, long timeout) override; + + public: // MQProducerInner + TransactionListener* getCheckListener() override; + + void checkTransactionState(const std::string& addr, + MQMessageExtPtr2 msg, + CheckTransactionStateRequestHeader* checkRequestHeader) override; + + public: + void initTransactionEnv(); + void destroyTransactionEnv(); + + const MQMessageQueue& selectOneMessageQueue(TopicPublishInfo* tpInfo, const std::string& lastBrokerName); + void updateFaultItem(const std::string& brokerName, const long currentLatency, bool isolation); + + void endTransaction(SendResult& sendResult, + LocalTransactionState localTransactionState, + std::exception_ptr& localException); + + bool isSendLatencyFaultEnable() const; + void setSendLatencyFaultEnable(bool sendLatencyFaultEnable); + + protected: + SendResult* sendDefaultImpl(MQMessagePtr msg, + CommunicationMode communicationMode, + SendCallback* sendCallback, + long timeout); + SendResult* sendKernelImpl(MQMessagePtr msg, + const MQMessageQueue& mq, + CommunicationMode communicationMode, + SendCallback* sendCallback, + std::shared_ptr topicPublishInfo, + long timeout); + SendResult* sendSelectImpl(MQMessagePtr msg, + MessageQueueSelector* selector, + void* arg, + CommunicationMode communicationMode, + SendCallback* sendCallback, + long timeout); + + TransactionSendResult* sendMessageInTransactionImpl(MQMessagePtr msg, void* arg, long timeout); + void checkTransactionStateImpl(const std::string& addr, + MQMessageExtPtr2 message, + long tranStateTableOffset, + long commitLogOffset, + const std::string& msgId, + const std::string& transactionId, + const std::string& offsetMsgId); + + bool tryToCompressMessage(MQMessage& msg); + + MessageBatch* batch(std::vector& msgs); + + private: + DefaultMQProducerConfig* m_producerConfig; + std::unique_ptr m_mqFaultStrategy; + std::unique_ptr m_checkTransactionExecutor; +}; + +} // namespace rocketmq + +#endif // __DEFAULT_MQ_PRODUCER_IMPL_H__ diff --git a/src/producer/LatencyFaultTolerancyImpl.cpp b/src/producer/LatencyFaultTolerancyImpl.cpp new file mode 100644 index 000000000..1826b8a06 --- /dev/null +++ b/src/producer/LatencyFaultTolerancyImpl.cpp @@ -0,0 +1,94 @@ +/* + * 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 "LatencyFaultTolerancyImpl.h" + +#include + +#include "UtilAll.h" + +namespace rocketmq { + +void LatencyFaultTolerancyImpl::updateFaultItem(const std::string& name, + const long currentLatency, + const long notAvailableDuration) { + std::lock_guard lock(m_faultItemTableMutex); + auto it = m_faultItemTable.find(name); + if (it == m_faultItemTable.end()) { + auto pair = m_faultItemTable.emplace(name, name); + it = pair.first; + } + auto& faultItem = it->second; + faultItem.m_currentLatency = currentLatency; + faultItem.m_startTimestamp = UtilAll::currentTimeMillis() + notAvailableDuration; +} + +bool LatencyFaultTolerancyImpl::isAvailable(const std::string& name) { + std::lock_guard lock(m_faultItemTableMutex); + auto it = m_faultItemTable.find(name); + if (it != m_faultItemTable.end()) { + return it->second.isAvailable(); + } + return true; +} + +void LatencyFaultTolerancyImpl::remove(const std::string& name) { + std::lock_guard lock(m_faultItemTableMutex); + m_faultItemTable.erase(name); +} + +std::string LatencyFaultTolerancyImpl::pickOneAtLeast() { + std::lock_guard lock(m_faultItemTableMutex); + if (m_faultItemTable.empty()) { + return null; + } + + if (m_faultItemTable.size() == 1) { + return m_faultItemTable.begin()->second.m_name; + } + + std::vector tmpList; + tmpList.reserve(m_faultItemTable.size()); + for (const auto& it : m_faultItemTable) { + tmpList.push_back(ComparableFaultItem(it.second)); + } + + std::sort(tmpList.begin(), tmpList.end()); + + auto half = tmpList.size() / 2; + auto i = m_whichItemWorst.fetch_add(1) % half; + return tmpList[i].m_name; +} + +LatencyFaultTolerancyImpl::FaultItem::FaultItem(const std::string& name) : m_name(name) {} + +bool LatencyFaultTolerancyImpl::FaultItem::isAvailable() const { + return UtilAll::currentTimeMillis() - m_startTimestamp >= 0; +} + +bool LatencyFaultTolerancyImpl::ComparableFaultItem::operator<(const ComparableFaultItem& other) const { + if (m_isAvailable != other.m_isAvailable) { + return m_isAvailable; + } + + if (m_currentLatency != other.m_currentLatency) { + return m_currentLatency < other.m_currentLatency; + } + + return m_startTimestamp < other.m_startTimestamp; +} + +} // namespace rocketmq diff --git a/src/producer/LatencyFaultTolerancyImpl.h b/src/producer/LatencyFaultTolerancyImpl.h new file mode 100644 index 000000000..fe74a32ac --- /dev/null +++ b/src/producer/LatencyFaultTolerancyImpl.h @@ -0,0 +1,87 @@ +/* + * 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 __LATENCY_FAULT_TOLERANCY_IMPL__ +#define __LATENCY_FAULT_TOLERANCY_IMPL__ + +#include +#include +#include +#include +#include +#include + +namespace rocketmq { + +class LatencyFaultTolerancyImpl { + public: + void updateFaultItem(const std::string& name, const long currentLatency, const long notAvailableDuration); + + bool isAvailable(const std::string& name); + + void remove(const std::string& name); + + std::string pickOneAtLeast(); + + private: + class FaultItem { + public: + FaultItem(const std::string& name); + + bool isAvailable() const; + + std::string toString() const { + std::stringstream ss; + ss << "FaultItem{" + << "name='" << m_name << "'" + << ", currentLatency=" << m_currentLatency << ", startTimestamp=" << m_startTimestamp << "}"; + return ss.str(); + } + + public: + std::string m_name; + volatile long m_currentLatency; + volatile int64_t m_startTimestamp; + }; + + class ComparableFaultItem { + public: + ComparableFaultItem(const FaultItem& item) + : m_name(item.m_name), + m_isAvailable(item.isAvailable()), + m_currentLatency(item.m_currentLatency), + m_startTimestamp(item.m_startTimestamp) {} + + bool operator<(const ComparableFaultItem& other) const; + + public: + std::string m_name; + bool m_isAvailable; + long m_currentLatency; + int64_t m_startTimestamp; + }; + + private: + // brokerName -> FaultItem + std::map m_faultItemTable; + std::mutex m_faultItemTableMutex; + + std::atomic m_whichItemWorst; +}; + +} // namespace rocketmq + +#endif // __LATENCY_FAULT_TOLERANCY_IMPL__ diff --git a/src/producer/MQFaultStrategy.cpp b/src/producer/MQFaultStrategy.cpp new file mode 100644 index 000000000..6ce139c98 --- /dev/null +++ b/src/producer/MQFaultStrategy.cpp @@ -0,0 +1,82 @@ +/* + * 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 "MQFaultStrategy.h" + +namespace rocketmq { + +MQFaultStrategy::MQFaultStrategy() : m_sendLatencyFaultEnable(false) { + m_latencyMax = std::vector{50L, 100L, 550L, 1000L, 2000L, 3000L, 15000L}; + m_notAvailableDuration = std::vector{0L, 0L, 30000L, 60000L, 120000L, 180000L, 600000L}; +} + +const MQMessageQueue& MQFaultStrategy::selectOneMessageQueue(TopicPublishInfo* tpInfo, + const std::string& lastBrokerName) { + if (m_sendLatencyFaultEnable) { + { + auto index = tpInfo->getSendWhichQueue().fetch_add(1); + std::lock_guard lock(tpInfo->getMessageQueueListMutex()); + auto& messageQueueList = tpInfo->getMessageQueueList(); + for (size_t i = 0; i < messageQueueList.size(); i++) { + auto pos = index++ % messageQueueList.size(); + const auto& mq = messageQueueList[pos]; + if (m_latencyFaultTolerance.isAvailable(mq.getBrokerName())) { + // FIXME: why not mq.getBrokerName() != lastBrokerName + if (lastBrokerName.empty() || mq.getBrokerName() != lastBrokerName) { + return mq; + } + } + } + } + + auto notBestBroker = m_latencyFaultTolerance.pickOneAtLeast(); + int writeQueueNums = tpInfo->getQueueIdByBroker(notBestBroker); + if (writeQueueNums > 0) { + // FIXME: why modify origin mq object, not return a new one? + static thread_local MQMessageQueue mq; + mq = tpInfo->selectOneMessageQueue(); + if (!notBestBroker.empty()) { + mq.setBrokerName(notBestBroker); + mq.setQueueId(tpInfo->getSendWhichQueue().fetch_add(1) % writeQueueNums); + } + return mq; + } else { + m_latencyFaultTolerance.remove(notBestBroker); + } + + return tpInfo->selectOneMessageQueue(); + } + + return tpInfo->selectOneMessageQueue(lastBrokerName); +} + +void MQFaultStrategy::updateFaultItem(const std::string& brokerName, const long currentLatency, bool isolation) { + if (m_sendLatencyFaultEnable) { + long duration = computeNotAvailableDuration(isolation ? 30000 : currentLatency); + m_latencyFaultTolerance.updateFaultItem(brokerName, currentLatency, duration); + } +} + +long MQFaultStrategy::computeNotAvailableDuration(const long currentLatency) { + for (size_t i = m_latencyMax.size(); i > 0; i--) { + if (currentLatency >= m_latencyMax[i - 1]) { + return m_notAvailableDuration[i - 1]; + } + } + return 0; +} + +} // namespace rocketmq diff --git a/src/producer/MQFaultStrategy.h b/src/producer/MQFaultStrategy.h new file mode 100644 index 000000000..2615cc3b6 --- /dev/null +++ b/src/producer/MQFaultStrategy.h @@ -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 __MQ_FAULT_STRATEGY_H__ +#define __MQ_FAULT_STRATEGY_H__ + +#include +#include + +#include "LatencyFaultTolerancyImpl.h" +#include "MQMessageQueue.h" +#include "TopicPublishInfo.h" + +namespace rocketmq { + +class MQFaultStrategy { + public: + MQFaultStrategy(); + + std::vector getNotAvailableDuration() { return m_notAvailableDuration; } + + void setNotAvailableDuration(const std::vector& notAvailableDuration) { + m_notAvailableDuration = notAvailableDuration; + } + + std::vector getLatencyMax() { return m_latencyMax; } + + void setLatencyMax(const std::vector& latencyMax) { m_latencyMax = latencyMax; } + + bool isSendLatencyFaultEnable() { return m_sendLatencyFaultEnable; } + + void setSendLatencyFaultEnable(const bool sendLatencyFaultEnable) { + m_sendLatencyFaultEnable = sendLatencyFaultEnable; + } + + const MQMessageQueue& selectOneMessageQueue(TopicPublishInfo* tpInfo, const std::string& lastBrokerName); + + void updateFaultItem(const std::string& brokerName, const long currentLatency, bool isolation); + + private: + long computeNotAvailableDuration(const long currentLatency); + + private: + LatencyFaultTolerancyImpl m_latencyFaultTolerance; + bool m_sendLatencyFaultEnable; + + std::vector m_latencyMax; + std::vector m_notAvailableDuration; +}; + +} // namespace rocketmq + +#endif // __MQ_FAULT_STRATEGY_H__ diff --git a/src/producer/MQProducerInner.h b/src/producer/MQProducerInner.h new file mode 100644 index 000000000..6e3bede6c --- /dev/null +++ b/src/producer/MQProducerInner.h @@ -0,0 +1,43 @@ +/* + * 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_PRODUCER_INNER_H__ +#define __MQ_PRODUCER_INNER_H__ + +#include "TransactionListener.h" + +namespace rocketmq { + +class CheckTransactionStateRequestHeader; + +class MQProducerInner { + public: + virtual ~MQProducerInner() = default; + + public: // MQProducerInner + virtual TransactionListener* getCheckListener() = 0; + + virtual void checkTransactionState(const std::string& addr, + MQMessageExtPtr2 msg, + CheckTransactionStateRequestHeader* checkRequestHeader) = 0; + + // virtual std::vector getPublishTopicList() = 0; + // virtual void updateTopicPublishInfo(const std::string& topic, TopicPublishInfoPtr info) = 0; +}; + +} // namespace rocketmq + +#endif // __MQ_PRODUCER_INNER_H__ diff --git a/src/producer/SendResult.cpp b/src/producer/SendResult.cpp index 6c5576902..74f4f1344 100644 --- a/src/producer/SendResult.cpp +++ b/src/producer/SendResult.cpp @@ -15,19 +15,21 @@ * limitations under the License. */ #include "SendResult.h" + #include + #include "UtilAll.h" #include "VirtualEnvUtil.h" namespace rocketmq { -// +#include +#include -#include -#include -#include -#include -#include -#include -#include -#include "Logging.h" #include "MQMessageQueue.h" +#include "TopicRouteData.h" namespace rocketmq { -//interrupt(); - m_async_service_thread->join(); - m_nonSerivceQueues.clear(); - m_onSerivceQueues.clear(); - m_brokerTimerMap.clear(); - m_queues.clear(); - } +class TopicPublishInfo; +typedef std::shared_ptr TopicPublishInfoPtr; - bool ok() { - boost::lock_guard lock(m_queuelock); - return !m_queues.empty(); - } +class TopicPublishInfo { + public: + typedef std::vector QueuesVec; - void updateMessageQueueList(const MQMessageQueue& mq) { - boost::lock_guard lock(m_queuelock); - m_queues.push_back(mq); - string key = mq.getBrokerName() + UtilAll::to_string(mq.getQueueId()); - m_onSerivceQueues[key] = mq; - if (m_nonSerivceQueues.find(key) != m_nonSerivceQueues.end()) { - m_nonSerivceQueues.erase(key); // if topicPublishInfo changed, erase this - // mq from m_nonSerivceQueues to avoid 2 - // copies both in m_onSerivceQueues and - // m_nonSerivceQueues - } - } + public: + TopicPublishInfo() : m_orderTopic(false), m_haveTopicRouterInfo(false), m_sendWhichQueue(0) {} - void op_resumeNonServiceMessageQueueList(boost::system::error_code& ec, boost::asio::deadline_timer* t) { - resumeNonServiceMessageQueueList(); - boost::system::error_code e; - t->expires_from_now(t->expires_from_now() + boost::posix_time::seconds(60), e); - t->async_wait(boost::bind(&TopicPublishInfo::op_resumeNonServiceMessageQueueList, this, e, t)); - } + virtual ~TopicPublishInfo() = default; - void resumeNonServiceMessageQueueList() { - boost::lock_guard lock(m_queuelock); - for (map::iterator it = m_brokerTimerMap.begin(); it != m_brokerTimerMap.end(); ++it) { - if (UtilAll::currentTimeMillis() - it->second >= 1000 * 60 * 5) { - string key = it->first.getBrokerName() + UtilAll::to_string(it->first.getQueueId()); - if (m_nonSerivceQueues.find(key) != m_nonSerivceQueues.end()) { - m_nonSerivceQueues.erase(key); - } - m_onSerivceQueues[key] = it->first; - } - } - } + bool isOrderTopic() { return m_orderTopic; } - void updateNonServiceMessageQueue(const MQMessageQueue& mq, int timeoutMilliseconds) { - boost::lock_guard lock(m_queuelock); + void setOrderTopic(bool orderTopic) { m_orderTopic = orderTopic; } - string key = mq.getBrokerName() + UtilAll::to_string(mq.getQueueId()); - if (m_nonSerivceQueues.find(key) != m_nonSerivceQueues.end()) { - return; - } - LOG_INFO("updateNonServiceMessageQueue of mq:%s", mq.toString().c_str()); - m_brokerTimerMap[mq] = UtilAll::currentTimeMillis(); - m_nonSerivceQueues[key] = mq; - if (m_onSerivceQueues.find(key) != m_onSerivceQueues.end()) { - m_onSerivceQueues.erase(key); - } + bool ok() { + std::lock_guard lock(m_queuelock); + return !m_messageQueueList.empty(); } - vector& getMessageQueueList() { - boost::lock_guard lock(m_queuelock); - return m_queues; - } + QueuesVec& getMessageQueueList() { return m_messageQueueList; } - int getWhichQueue() { return m_sendWhichQueue.load(boost::memory_order_acquire); } + std::mutex& getMessageQueueListMutex() { return m_queuelock; } - MQMessageQueue selectOneMessageQueue(const MQMessageQueue& lastmq, int& mq_index) { - boost::lock_guard lock(m_queuelock); + std::atomic& getSendWhichQueue() { return m_sendWhichQueue; } - if (m_queues.size() > 0) { - LOG_DEBUG("selectOneMessageQueue Enter, queue size:" SIZET_FMT "", m_queues.size()); - unsigned int pos = 0; - if (mq_index >= 0) { - pos = mq_index % m_queues.size(); - } else { - LOG_ERROR("mq_index is negative"); - return MQMessageQueue(); - } - if (!lastmq.getBrokerName().empty()) { - for (size_t i = 0; i < m_queues.size(); i++) { - if (m_sendWhichQueue.load(boost::memory_order_acquire) == (numeric_limits::max)()) { - m_sendWhichQueue.store(0, boost::memory_order_release); - } + bool isHaveTopicRouterInfo() { return m_haveTopicRouterInfo; } - if (pos >= m_queues.size()) - pos = pos % m_queues.size(); + void setHaveTopicRouterInfo(bool haveTopicRouterInfo) { m_haveTopicRouterInfo = haveTopicRouterInfo; } - ++m_sendWhichQueue; - MQMessageQueue mq = m_queues.at(pos); - LOG_DEBUG("lastmq broker not empty, m_sendWhichQueue:%d, pos:%d", - m_sendWhichQueue.load(boost::memory_order_acquire), pos); - if (mq.getBrokerName().compare(lastmq.getBrokerName()) != 0) { - mq_index = pos; - return mq; - } - ++pos; + MQMessageQueue& selectOneMessageQueue(const std::string& lastBrokerName) { + if (!lastBrokerName.empty()) { + auto index = m_sendWhichQueue.fetch_add(1); + std::lock_guard lock(m_queuelock); + for (size_t i = 0; i < m_messageQueueList.size(); i++) { + auto pos = index++ % m_messageQueueList.size(); + auto& mq = m_messageQueueList[pos]; + if (mq.getBrokerName() != lastBrokerName) { + return mq; } - LOG_ERROR("could not find property mq"); - return MQMessageQueue(); - } else { - if (m_sendWhichQueue.load(boost::memory_order_acquire) == (numeric_limits::max)()) { - m_sendWhichQueue.store(0, boost::memory_order_release); - } - - ++m_sendWhichQueue; - LOG_DEBUG("lastmq broker empty, m_sendWhichQueue:%d, pos:%d", - m_sendWhichQueue.load(boost::memory_order_acquire), pos); - mq_index = pos; - return m_queues.at(pos); } - } else { - LOG_ERROR("m_queues empty"); - return MQMessageQueue(); } + return selectOneMessageQueue(); } - MQMessageQueue selectOneActiveMessageQueue(const MQMessageQueue& lastmq, int& mq_index) { - boost::lock_guard lock(m_queuelock); + MQMessageQueue& selectOneMessageQueue() { + auto index = m_sendWhichQueue.fetch_add(1); + std::lock_guard lock(m_queuelock); + auto pos = index % m_messageQueueList.size(); + return m_messageQueueList[pos]; + } - if (m_queues.size() > 0) { - unsigned int pos = 0; - if (mq_index >= 0) { - pos = mq_index % m_queues.size(); - } else { - LOG_ERROR("mq_index is negative"); - return MQMessageQueue(); + int getQueueIdByBroker(const std::string& brokerName) { + for (const auto& queueData : m_topicRouteData->getQueueDatas()) { + if (queueData.brokerName == brokerName) { + return queueData.writeQueueNums; } - if (!lastmq.getBrokerName().empty()) { - for (size_t i = 0; i < m_queues.size(); i++) { - if (m_sendWhichQueue.load(boost::memory_order_acquire) == (numeric_limits::max)()) { - m_sendWhichQueue.store(0, boost::memory_order_release); - } + } - if (pos >= m_queues.size()) - pos = pos % m_queues.size(); + return -1; + } - ++m_sendWhichQueue; - MQMessageQueue mq = m_queues.at(pos); - string key = mq.getBrokerName() + UtilAll::to_string(mq.getQueueId()); - if ((mq.getBrokerName().compare(lastmq.getBrokerName()) != 0) && - (m_onSerivceQueues.find(key) != m_onSerivceQueues.end())) { - mq_index = pos; - return mq; - } - ++pos; - } + void setTopicRouteData(TopicRouteDataPtr topicRouteData) { m_topicRouteData = topicRouteData; } - for (MQMAP::iterator it = m_nonSerivceQueues.begin(); it != m_nonSerivceQueues.end(); - ++it) { // if no MQMessageQueue(except lastmq) in - // m_onSerivceQueues, search m_nonSerivceQueues - if (it->second.getBrokerName().compare(lastmq.getBrokerName()) != 0) - return it->second; - } - LOG_ERROR("can not find property mq"); - return MQMessageQueue(); - } else { - for (size_t i = 0; i < m_queues.size(); i++) { - if (m_sendWhichQueue.load(boost::memory_order_acquire) == (numeric_limits::max)()) { - m_sendWhichQueue.store(0, boost::memory_order_release); - } - if (pos >= m_queues.size()) - pos = pos % m_queues.size(); + private: + bool m_orderTopic; + bool m_haveTopicRouterInfo; - ++m_sendWhichQueue; - LOG_DEBUG("lastmq broker empty, m_sendWhichQueue:%d, pos:%d", - m_sendWhichQueue.load(boost::memory_order_acquire), pos); - mq_index = pos; - MQMessageQueue mq = m_queues.at(pos); - string key = mq.getBrokerName() + UtilAll::to_string(mq.getQueueId()); - if (m_onSerivceQueues.find(key) != m_onSerivceQueues.end()) { - return mq; - } else { - ++pos; - } - } + QueuesVec m_messageQueueList; + std::mutex m_queuelock; - for (MQMAP::iterator it = m_nonSerivceQueues.begin(); it != m_nonSerivceQueues.end(); - ++it) { // if no MQMessageQueue(except lastmq) in - // m_onSerivceQueues, search m_nonSerivceQueues - if (it->second.getBrokerName().compare(lastmq.getBrokerName()) != 0) - return it->second; - } - LOG_ERROR("can not find property mq"); - return MQMessageQueue(); - } - } else { - LOG_ERROR("m_queues empty"); - return MQMessageQueue(); - } - } + std::atomic m_sendWhichQueue; - private: - boost::mutex m_queuelock; - typedef vector QueuesVec; - QueuesVec m_queues; - typedef map MQMAP; - MQMAP m_onSerivceQueues; - MQMAP m_nonSerivceQueues; - boost::atomic m_sendWhichQueue; - map m_brokerTimerMap; - boost::asio::io_service m_async_ioService; - boost::scoped_ptr m_async_service_thread; + TopicRouteDataPtr m_topicRouteData; // no change after set }; -// -#include "CommandHeader.h" -#include "Logging.h" -#include "MQClientFactory.h" -#include "MQDecoder.h" -#include "MessageSysFlag.h" -#include "TransactionListener.h" -#include "TransactionSendResult.h" - -using namespace std; -namespace rocketmq { - -void TransactionMQProducer::initTransactionEnv() { - for (int i = 0; i < m_thread_num; ++i) { - m_threadpool.create_thread(boost::bind(&boost::asio::io_service::run, &m_ioService)); - } -} - -void TransactionMQProducer::destroyTransactionEnv() { - m_ioService.stop(); - m_threadpool.join_all(); -} - -TransactionSendResult TransactionMQProducer::sendMessageInTransaction(MQMessage& msg, void* arg) { - if (!m_transactionListener) { - THROW_MQEXCEPTION(MQClientException, "transactionListener is null", -1); - } - SendResult sendResult; - msg.setProperty(MQMessage::PROPERTY_TRANSACTION_PREPARED, "true"); - msg.setProperty(MQMessage::PROPERTY_PRODUCER_GROUP, getGroupName()); - try { - sendResult = send(msg); - } catch (MQException& e) { - THROW_MQEXCEPTION(MQClientException, e.what(), -1); - } - - LocalTransactionState localTransactionState = LocalTransactionState::UNKNOWN; - switch (sendResult.getSendStatus()) { - case SendStatus::SEND_OK: - try { - if (sendResult.getTransactionId() != "") { - msg.setProperty("__transactionId__", sendResult.getTransactionId()); - } - string transactionId = msg.getProperty(MQMessage::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX); - if (transactionId != "") { - msg.setTransactionId(transactionId); - } - LOG_DEBUG("sendMessageInTransaction, msgId:%s, transactionId:%s", sendResult.getMsgId().data(), - transactionId.data()); - localTransactionState = m_transactionListener->executeLocalTransaction(msg, arg); - if (localTransactionState != LocalTransactionState::COMMIT_MESSAGE) { - LOG_WARN("executeLocalTransaction ret not LocalTransactionState::commit, msg:%s", msg.toString().data()); - } - } catch (MQException& e) { - THROW_MQEXCEPTION(MQClientException, e.what(), -1); - } - break; - case SendStatus::SEND_FLUSH_DISK_TIMEOUT: - case SendStatus::SEND_FLUSH_SLAVE_TIMEOUT: - case SendStatus::SEND_SLAVE_NOT_AVAILABLE: - localTransactionState = LocalTransactionState::ROLLBACK_MESSAGE; - LOG_WARN("sendMessageInTransaction, send not ok, rollback, result:%s", sendResult.toString().data()); - break; - default: - break; - } - - try { - endTransaction(sendResult, localTransactionState); - } catch (MQException& e) { - LOG_WARN("endTransaction exception:%s", e.what()); - } - - TransactionSendResult transactionSendResult(sendResult.getSendStatus(), sendResult.getMsgId(), - sendResult.getOffsetMsgId(), sendResult.getMessageQueue(), - sendResult.getQueueOffset()); - transactionSendResult.setTransactionId(msg.getTransactionId()); - transactionSendResult.setLocalTransactionState(localTransactionState); - return transactionSendResult; -} - -void TransactionMQProducer::endTransaction(SendResult& sendResult, LocalTransactionState& localTransactionState) { - MQMessageId id; - if (sendResult.getOffsetMsgId() != "") { - id = MQDecoder::decodeMessageId(sendResult.getOffsetMsgId()); - } else { - id = MQDecoder::decodeMessageId(sendResult.getMsgId()); - } - string transId = sendResult.getTransactionId(); +#include "DefaultMQProducerImpl.h" - int commitOrRollback = MessageSysFlag::TransactionNotType; - switch (localTransactionState) { - case COMMIT_MESSAGE: - commitOrRollback = MessageSysFlag::TransactionCommitType; - break; - case ROLLBACK_MESSAGE: - commitOrRollback = MessageSysFlag::TransactionRollbackType; - break; - case UNKNOWN: - commitOrRollback = MessageSysFlag::TransactionNotType; - break; - default: - break; - } - - bool fromTransCheck = false; - EndTransactionRequestHeader* requestHeader = - new EndTransactionRequestHeader(getGroupName(), sendResult.getQueueOffset(), id.getOffset(), commitOrRollback, - fromTransCheck, sendResult.getMsgId(), transId); - LOG_DEBUG("endTransaction: msg:%s", requestHeader->toString().data()); - getFactory()->endTransactionOneway(sendResult.getMessageQueue(), requestHeader, getSessionCredentials()); -} - -void TransactionMQProducer::checkTransactionState(const std::string& addr, - const MQMessageExt& message, - long tranStateTableOffset, - long commitLogOffset, - const std::string& msgId, - const std::string& transactionId, - const std::string& offsetMsgId) { - LOG_DEBUG("checkTransactionState: msgId:%s, transactionId:%s", msgId.data(), transactionId.data()); - if (!m_transactionListener) { - LOG_WARN("checkTransactionState, transactionListener null"); - THROW_MQEXCEPTION(MQClientException, "checkTransactionState, transactionListener null", -1); - } - - m_ioService.post(boost::bind(&TransactionMQProducer::checkTransactionStateImpl, this, addr, message, - tranStateTableOffset, commitLogOffset, msgId, transactionId, offsetMsgId)); -} - -void TransactionMQProducer::checkTransactionStateImpl(const std::string& addr, - const MQMessageExt& message, - long tranStateTableOffset, - long commitLogOffset, - const std::string& msgId, - const std::string& transactionId, - const std::string& offsetMsgId) { - LOG_DEBUG("checkTransactionStateImpl: msgId:%s, transactionId:%s", msgId.data(), transactionId.data()); - LocalTransactionState localTransactionState = UNKNOWN; - try { - localTransactionState = m_transactionListener->checkLocalTransaction(message); - } catch (MQException& e) { - LOG_INFO("checkTransactionState, checkLocalTransaction exception: %s", e.what()); - } +namespace rocketmq { - EndTransactionRequestHeader* endHeader = new EndTransactionRequestHeader(); - endHeader->m_commitLogOffset = commitLogOffset; - endHeader->m_producerGroup = getGroupName(); - endHeader->m_tranStateTableOffset = tranStateTableOffset; - endHeader->m_fromTransactionCheck = true; +TransactionMQProducerConfig::TransactionMQProducerConfig() : m_transactionListener(nullptr) {} - string uniqueKey = transactionId; - if (transactionId.empty()) { - uniqueKey = message.getMsgId(); - } +TransactionMQProducer::TransactionMQProducer(const std::string& groupname) + : TransactionMQProducer(groupname, nullptr) {} - endHeader->m_msgId = uniqueKey; - endHeader->m_transactionId = transactionId; - switch (localTransactionState) { - case COMMIT_MESSAGE: - endHeader->m_commitOrRollback = MessageSysFlag::TransactionCommitType; - break; - case ROLLBACK_MESSAGE: - endHeader->m_commitOrRollback = MessageSysFlag::TransactionRollbackType; - LOG_WARN("when broker check, client rollback this transaction, %s", endHeader->toString().data()); - break; - case UNKNOWN: - endHeader->m_commitOrRollback = MessageSysFlag::TransactionNotType; - LOG_WARN("when broker check, client does not know this transaction state, %s", endHeader->toString().data()); - break; - default: - break; - } +TransactionMQProducer::TransactionMQProducer(const std::string& groupname, std::shared_ptr rpcHook) + : DefaultMQProducer(groupname, rpcHook) {} - LOG_INFO("checkTransactionState, endTransactionOneway: uniqueKey:%s, client state:%d, end header: %s", - uniqueKey.data(), localTransactionState, endHeader->toString().data()); - - string remark; - try { - getFactory()->getMQClientAPIImpl()->endTransactionOneway(addr, endHeader, remark, getSessionCredentials()); - } catch (MQException& e) { - LOG_ERROR("endTransactionOneway exception:%s", e.what()); - throw e; - } -} +TransactionMQProducer::~TransactionMQProducer() = default; void TransactionMQProducer::start() { - initTransactionEnv(); + dynamic_cast(m_producerDelegate.get())->initTransactionEnv(); DefaultMQProducer::start(); } void TransactionMQProducer::shutdown() { DefaultMQProducer::shutdown(); - destroyTransactionEnv(); + dynamic_cast(m_producerDelegate.get())->destroyTransactionEnv(); +} + +TransactionSendResult TransactionMQProducer::sendMessageInTransaction(MQMessagePtr msg, void* arg) { + if (nullptr == m_transactionListener) { + THROW_MQEXCEPTION(MQClientException, "TransactionListener is null", -1); + } + return m_producerDelegate->sendMessageInTransaction(msg, arg); } } // namespace rocketmq diff --git a/src/protocol/CommandHeader.cpp b/src/protocol/CommandHeader.cpp index 30dcf59c5..1a2694138 100644 --- a/src/protocol/CommandHeader.cpp +++ b/src/protocol/CommandHeader.cpp @@ -1,671 +1,776 @@ -/* - * 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 "CommandHeader.h" -#include -#include -#include "Logging.h" -#include "UtilAll.h" - -namespace rocketmq { -//& requestMap) { - requestMap.insert(pair("topic", topic)); -} -//& requestMap) { - requestMap.insert(pair("clientID", clientID)); - requestMap.insert(pair("producerGroup", producerGroup)); - requestMap.insert(pair("consumerGroup", consumerGroup)); -} -//& requestMap) { - requestMap.insert(pair("topic", topic)); - requestMap.insert(pair("defaultTopic", defaultTopic)); - requestMap.insert(pair("readQueueNums", UtilAll::to_string(readQueueNums))); - requestMap.insert(pair("writeQueueNums", UtilAll::to_string(writeQueueNums))); - requestMap.insert(pair("perm", UtilAll::to_string(perm))); - requestMap.insert(pair("topicFilterType", topicFilterType)); -} - -void CheckTransactionStateRequestHeader::Encode(Json::Value& outData) {} - -CommandHeader* CheckTransactionStateRequestHeader::Decode(Json::Value& ext) { - CheckTransactionStateRequestHeader* h = new CheckTransactionStateRequestHeader(); - Json::Value& tempValue = ext["msgId"]; - if (tempValue.isString()) { - h->m_msgId = tempValue.asString(); - } - - tempValue = ext["transactionId"]; - if (tempValue.isString()) { - h->m_transactionId = tempValue.asString(); - } - - tempValue = ext["offsetMsgId"]; - if (tempValue.isString()) { - h->m_offsetMsgId = tempValue.asString(); - } - - tempValue = ext["tranStateTableOffset"]; - if (tempValue.isString()) { - h->m_tranStateTableOffset = UtilAll::str2ll(tempValue.asCString()); - } - - tempValue = ext["commitLogOffset"]; - if (tempValue.isString()) { - h->m_commitLogOffset = UtilAll::str2ll(tempValue.asCString()); - } - - return h; -} - -void CheckTransactionStateRequestHeader::SetDeclaredFieldOfCommandHeader(map& requestMap) { - requestMap.insert(pair("msgId", m_msgId)); - requestMap.insert(pair("transactionId", m_transactionId)); - requestMap.insert(pair("offsetMsgId", m_offsetMsgId)); - requestMap.insert(pair("commitLogOffset", UtilAll::to_string(m_commitLogOffset))); - requestMap.insert(pair("tranStateTableOffset", UtilAll::to_string(m_tranStateTableOffset))); -} - -std::string CheckTransactionStateRequestHeader::toString() { - stringstream ss; - ss << "CheckTransactionStateRequestHeader:"; - ss << " msgId:" << m_msgId; - ss << " transactionId:" << m_transactionId; - ss << " offsetMsgId:" << m_offsetMsgId; - ss << " commitLogOffset:" << m_commitLogOffset; - ss << " tranStateTableOffset:" << m_tranStateTableOffset; - return ss.str(); -} - -void EndTransactionRequestHeader::Encode(Json::Value& outData) { - outData["msgId"] = m_msgId; - outData["transactionId"] = m_transactionId; - outData["producerGroup"] = m_producerGroup; - outData["tranStateTableOffset"] = UtilAll::to_string(m_tranStateTableOffset); - outData["commitLogOffset"] = UtilAll::to_string(m_commitLogOffset); - outData["commitOrRollback"] = UtilAll::to_string(m_commitOrRollback); - outData["fromTransactionCheck"] = UtilAll::to_string(m_fromTransactionCheck); -} - -void EndTransactionRequestHeader::SetDeclaredFieldOfCommandHeader(map& requestMap) { - requestMap.insert(pair("msgId", m_msgId)); - requestMap.insert(pair("transactionId", m_transactionId)); - requestMap.insert(pair("producerGroup", m_producerGroup)); - requestMap.insert(pair("tranStateTableOffset", UtilAll::to_string(m_tranStateTableOffset))); - requestMap.insert(pair("commitLogOffset", UtilAll::to_string(m_commitLogOffset))); - requestMap.insert(pair("commitOrRollback", UtilAll::to_string(m_commitOrRollback))); - requestMap.insert(pair("fromTransactionCheck", UtilAll::to_string(m_fromTransactionCheck))); -} - -std::string EndTransactionRequestHeader::toString() { - stringstream ss; - ss << "EndTransactionRequestHeader:"; - ss << " m_msgId:" << m_msgId; - ss << " m_transactionId:" << m_transactionId; - ss << " m_producerGroup:" << m_producerGroup; - ss << " m_tranStateTableOffset:" << m_tranStateTableOffset; - ss << " m_commitLogOffset:" << m_commitLogOffset; - ss << " m_commitOrRollback:" << m_commitOrRollback; - ss << " m_fromTransactionCheck:" << m_fromTransactionCheck; - return ss.str(); -} - -//& requestMap) { - LOG_DEBUG( - "SendMessageRequestHeader producerGroup is:%s,topic is:%s, defaulttopic " - "is:%s, properties is:%s,UtilAll::to_string( defaultTopicQueueNums) " - "is:%s,UtilAll::to_string( queueId):%s, UtilAll::to_string( sysFlag) " - "is:%s, UtilAll::to_string( bornTimestamp) is:%s,UtilAll::to_string( " - "flag) is:%s", - producerGroup.c_str(), topic.c_str(), defaultTopic.c_str(), properties.c_str(), - UtilAll::to_string(defaultTopicQueueNums).c_str(), UtilAll::to_string(queueId).c_str(), - UtilAll::to_string(sysFlag).c_str(), UtilAll::to_string(bornTimestamp).c_str(), UtilAll::to_string(flag).c_str()); - - requestMap.insert(pair("producerGroup", producerGroup)); - requestMap.insert(pair("topic", topic)); - requestMap.insert(pair("defaultTopic", defaultTopic)); - requestMap.insert(pair("defaultTopicQueueNums", UtilAll::to_string(defaultTopicQueueNums))); - requestMap.insert(pair("queueId", UtilAll::to_string(queueId))); - requestMap.insert(pair("sysFlag", UtilAll::to_string(sysFlag))); - requestMap.insert(pair("bornTimestamp", UtilAll::to_string(bornTimestamp))); - requestMap.insert(pair("flag", UtilAll::to_string(flag))); - requestMap.insert(pair("properties", properties)); - requestMap.insert(pair("reconsumeTimes", UtilAll::to_string(reconsumeTimes))); - requestMap.insert(pair("unitMode", UtilAll::to_string(unitMode))); - requestMap.insert(pair("batch", UtilAll::to_string(batch))); -} - -//& requestMap) { - LOG_DEBUG( - "SendMessageRequestHeaderV2 producerGroup is:%s,topic is:%s, defaulttopic " - "is:%s, properties is:%s,UtilAll::to_string( defaultTopicQueueNums) " - "is:%s,UtilAll::to_string( queueId):%s, UtilAll::to_string( sysFlag) " - "is:%s, UtilAll::to_string( bornTimestamp) is:%s,UtilAll::to_string( " - "flag) is:%s,UtilAll::to_string( reconsumeTimes) is:%s,UtilAll::to_string( unitMode) is:%s,UtilAll::to_string( " - "batch) is:%s", - a.c_str(), b.c_str(), c.c_str(), i.c_str(), UtilAll::to_string(d).c_str(), UtilAll::to_string(e).c_str(), - UtilAll::to_string(f).c_str(), UtilAll::to_string(g).c_str(), UtilAll::to_string(g).c_str(), - UtilAll::to_string(j).c_str(), UtilAll::to_string(k).c_str(), UtilAll::to_string(m).c_str()); - - requestMap.insert(pair("a", a)); - requestMap.insert(pair("b", b)); - requestMap.insert(pair("c", c)); - requestMap.insert(pair("d", UtilAll::to_string(d))); - requestMap.insert(pair("e", UtilAll::to_string(e))); - requestMap.insert(pair("f", UtilAll::to_string(f))); - requestMap.insert(pair("g", UtilAll::to_string(g))); - requestMap.insert(pair("h", UtilAll::to_string(h))); - requestMap.insert(pair("i", i)); - requestMap.insert(pair("j", UtilAll::to_string(j))); - requestMap.insert(pair("k", UtilAll::to_string(k))); - requestMap.insert(pair("l", UtilAll::to_string(l))); - requestMap.insert(pair("m", UtilAll::to_string(m))); -} -void SendMessageRequestHeaderV2::CreateSendMessageRequestHeaderV1(SendMessageRequestHeader& v1) { - v1.producerGroup = a; - v1.topic = b; - v1.defaultTopic = c; - v1.defaultTopicQueueNums = d; - v1.queueId = e; - v1.sysFlag = f; - v1.bornTimestamp = g; - v1.flag = h; - v1.properties = i; - v1.reconsumeTimes = j; - v1.unitMode = k; - v1.consumeRetryTimes = l; - v1.batch = m; -} -//msgId = tempValue.asString(); - } - - tempValue = ext["queueId"]; - if (tempValue.isString()) { - h->queueId = atoi(tempValue.asCString()); - } - - tempValue = ext["queueOffset"]; - if (tempValue.isString()) { - h->queueOffset = UtilAll::str2ll(tempValue.asCString()); - } - return h; -} - -void SendMessageResponseHeader::SetDeclaredFieldOfCommandHeader(map& requestMap) { - requestMap.insert(pair("msgId", msgId)); - requestMap.insert(pair("queueId", UtilAll::to_string(queueId))); - requestMap.insert(pair("queueOffset", UtilAll::to_string(queueOffset))); -} -//& requestMap) { - requestMap.insert(pair("consumerGroup", consumerGroup)); - requestMap.insert(pair("topic", topic)); - requestMap.insert(pair("queueId", UtilAll::to_string(queueId))); - requestMap.insert(pair("queueOffset", UtilAll::to_string(queueOffset))); - requestMap.insert(pair("maxMsgNums", UtilAll::to_string(maxMsgNums))); - requestMap.insert(pair("sysFlag", UtilAll::to_string(sysFlag))); - requestMap.insert(pair("commitOffset", UtilAll::to_string(commitOffset))); - requestMap.insert(pair("subVersion", UtilAll::to_string(subVersion))); - requestMap.insert(pair("suspendTimeoutMillis", UtilAll::to_string(suspendTimeoutMillis))); - requestMap.insert(pair("subscription", subscription)); -} -//suggestWhichBrokerId = UtilAll::str2ll(tempValue.asCString()); - } - - tempValue = ext["nextBeginOffset"]; - if (tempValue.isString()) { - h->nextBeginOffset = UtilAll::str2ll(tempValue.asCString()); - } - - tempValue = ext["minOffset"]; - if (tempValue.isString()) { - h->minOffset = UtilAll::str2ll(tempValue.asCString()); - } - - tempValue = ext["maxOffset"]; - if (tempValue.isString()) { - h->maxOffset = UtilAll::str2ll(tempValue.asCString()); - } - - return h; -} - -void PullMessageResponseHeader::SetDeclaredFieldOfCommandHeader(map& requestMap) { - requestMap.insert(pair("suggestWhichBrokerId", UtilAll::to_string(suggestWhichBrokerId))); - requestMap.insert(pair("nextBeginOffset", UtilAll::to_string(nextBeginOffset))); - requestMap.insert(pair("minOffset", UtilAll::to_string(minOffset))); - requestMap.insert(pair("maxOffset", UtilAll::to_string(maxOffset))); -} -//& requestMap) {} -//& requestMap) { - requestMap.insert(pair("topic", topic)); - requestMap.insert(pair("queueId", UtilAll::to_string(queueId))); -} -//offset = UtilAll::str2ll(tempValue.asCString()); - } - return h; -} - -void GetMinOffsetResponseHeader::SetDeclaredFieldOfCommandHeader(map& requestMap) { - requestMap.insert(pair("offset", UtilAll::to_string(offset))); -} -//& requestMap) { - requestMap.insert(pair("topic", topic)); - requestMap.insert(pair("queueId", UtilAll::to_string(queueId))); -} -//offset = UtilAll::str2ll(tempValue.asCString()); - } - return h; -} - -void GetMaxOffsetResponseHeader::SetDeclaredFieldOfCommandHeader(map& requestMap) { - requestMap.insert(pair("offset", UtilAll::to_string(offset))); -} -//& requestMap) { - requestMap.insert(pair("topic", topic)); - requestMap.insert(pair("queueId", UtilAll::to_string(queueId))); - requestMap.insert(pair("timestamp", UtilAll::to_string(timestamp))); -} -//offset = UtilAll::str2ll(tempValue.asCString()); - } - return h; -} - -void SearchOffsetResponseHeader::SetDeclaredFieldOfCommandHeader(map& requestMap) { - requestMap.insert(pair("offset", UtilAll::to_string(offset))); -} -//& requestMap) { - requestMap.insert(pair("offset", UtilAll::to_string(offset))); -} -//& requestMap) { - requestMap.insert(pair("topic", topic)); - requestMap.insert(pair("queueId", UtilAll::to_string(queueId))); -} -//timestamp = UtilAll::str2ll(tempValue.asCString()); - } - return h; -} - -void GetEarliestMsgStoretimeResponseHeader::SetDeclaredFieldOfCommandHeader(map& requestMap) { - requestMap.insert(pair("timestamp", UtilAll::to_string(timestamp))); -} -//& requestMap) { - requestMap.insert(pair("consumerGroup", consumerGroup)); -} -//& requestMap) { - requestMap.insert(pair("consumerGroup", consumerGroup)); - requestMap.insert(pair("topic", topic)); - requestMap.insert(pair("queueId", UtilAll::to_string(queueId))); -} -//offset = UtilAll::str2ll(tempValue.asCString()); - } - return h; -} - -void QueryConsumerOffsetResponseHeader::SetDeclaredFieldOfCommandHeader(map& requestMap) { - requestMap.insert(pair("offset", UtilAll::to_string(offset))); -} -//& requestMap) { - requestMap.insert(pair("consumerGroup", consumerGroup)); - requestMap.insert(pair("topic", topic)); - requestMap.insert(pair("queueId", UtilAll::to_string(queueId))); - requestMap.insert(pair("commitOffset", UtilAll::to_string(commitOffset))); -} -//& requestMap) { - requestMap.insert(pair("group", group)); - requestMap.insert(pair("delayLevel", UtilAll::to_string(delayLevel))); - requestMap.insert(pair("offset", UtilAll::to_string(offset))); - requestMap.insert(pair("unitMode", UtilAll::to_string(unitMode))); - requestMap.insert(pair("originMsgId", originMsgId)); - requestMap.insert(pair("originTopic", originTopic)); - requestMap.insert(pair("maxReconsumeTimes", UtilAll::to_string(maxReconsumeTimes))); -} -//& cids) { - cids.clear(); - //(mem->getData()); - - Json::Reader reader; - Json::Value root; - if (!reader.parse(pData, root)) { - LOG_ERROR("GetConsumerListByGroupResponse error"); - return; - } - - Json::Value ids = root["consumerIdList"]; - for (unsigned int i = 0; i < ids.size(); i++) { - if (ids[i].isString()) { - cids.push_back(ids[i].asString()); - } - } -} - -void GetConsumerListByGroupResponseBody::SetDeclaredFieldOfCommandHeader(map& requestMap) {} - -void ResetOffsetRequestHeader::setTopic(const string& tmp) { - topic = tmp; -} - -void ResetOffsetRequestHeader::setGroup(const string& tmp) { - group = tmp; -} - -void ResetOffsetRequestHeader::setTimeStamp(const int64& tmp) { - timestamp = tmp; -} - -void ResetOffsetRequestHeader::setForceFlag(const bool& tmp) { - isForce = tmp; -} - -const string ResetOffsetRequestHeader::getTopic() const { - return topic; -} - -const string ResetOffsetRequestHeader::getGroup() const { - return group; -} - -const int64 ResetOffsetRequestHeader::getTimeStamp() const { - return timestamp; -} - -const bool ResetOffsetRequestHeader::getForceFlag() const { - return isForce; -} - -CommandHeader* ResetOffsetRequestHeader::Decode(Json::Value& ext) { - ResetOffsetRequestHeader* h = new ResetOffsetRequestHeader(); - - Json::Value& tempValue = ext["topic"]; - if (tempValue.isString()) { - h->topic = tempValue.asString(); - } - - tempValue = ext["group"]; - if (tempValue.isString()) { - h->group = tempValue.asString(); - } - - tempValue = ext["timestamp"]; - if (tempValue.isString()) { - h->timestamp = UtilAll::str2ll(tempValue.asCString()); - } - - tempValue = ext["isForce"]; - if (tempValue.isString()) { - h->isForce = UtilAll::to_bool(tempValue.asCString()); - } - LOG_INFO("topic:%s, group:%s, timestamp:%lld, isForce:%d", h->topic.c_str(), h->group.c_str(), h->timestamp, - h->isForce); - return h; -} - -CommandHeader* GetConsumerRunningInfoRequestHeader::Decode(Json::Value& ext) { - GetConsumerRunningInfoRequestHeader* h = new GetConsumerRunningInfoRequestHeader(); - - Json::Value& tempValue = ext["consumerGroup"]; - if (tempValue.isString()) { - h->consumerGroup = tempValue.asString(); - } - - tempValue = ext["clientId"]; - if (tempValue.isString()) { - h->clientId = tempValue.asString(); - } - - tempValue = ext["jstackEnable"]; - if (tempValue.isBool()) { - h->jstackEnable = tempValue.asBool(); - } else if (tempValue.isString()) { - h->jstackEnable = UtilAll::to_bool(tempValue.asCString()); - } - LOG_INFO("consumerGroup:%s, clientId:%s, jstackEnable:%d", h->consumerGroup.c_str(), h->clientId.c_str(), - h->jstackEnable); - return h; -} - -void GetConsumerRunningInfoRequestHeader::Encode(Json::Value& outData) { - outData["consumerGroup"] = consumerGroup; - outData["clientId"] = clientId; - outData["jstackEnable"] = jstackEnable; -} - -void GetConsumerRunningInfoRequestHeader::SetDeclaredFieldOfCommandHeader(map& requestMap) { - requestMap.insert(pair("consumerGroup", consumerGroup)); - requestMap.insert(pair("clientId", clientId)); - requestMap.insert(pair("jstackEnable", UtilAll::to_string(jstackEnable))); -} - -const string GetConsumerRunningInfoRequestHeader::getConsumerGroup() const { - return consumerGroup; -} - -void GetConsumerRunningInfoRequestHeader::setConsumerGroup(const string& Group) { - consumerGroup = Group; -} - -const string GetConsumerRunningInfoRequestHeader::getClientId() const { - return clientId; -} - -void GetConsumerRunningInfoRequestHeader::setClientId(const string& input_clientId) { - clientId = input_clientId; -} - -const bool GetConsumerRunningInfoRequestHeader::isJstackEnable() const { - return jstackEnable; -} - -void GetConsumerRunningInfoRequestHeader::setJstackEnable(const bool& input_jstackEnable) { - jstackEnable = input_jstackEnable; -} - -CommandHeader* NotifyConsumerIdsChangedRequestHeader::Decode(Json::Value& ext) { - NotifyConsumerIdsChangedRequestHeader* h = new NotifyConsumerIdsChangedRequestHeader(); - - Json::Value& tempValue = ext["consumerGroup"]; - if (tempValue.isString()) { - h->consumerGroup = tempValue.asString(); - } - - return h; -} - -void NotifyConsumerIdsChangedRequestHeader::setGroup(const string& tmp) { - consumerGroup = tmp; -} -const string NotifyConsumerIdsChangedRequestHeader::getGroup() const { - return consumerGroup; -} - -// + +#include "Logging.h" +#include "MQClientException.h" +#include "RemotingSerializable.h" +#include "UtilAll.h" + +namespace rocketmq { + +//###################################### +// GetRouteInfoRequestHeader +//###################################### + +void GetRouteInfoRequestHeader::Encode(Json::Value& extFields) { + extFields["topic"] = topic; +} + +void GetRouteInfoRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + requestMap.emplace("topic", topic); +} + +//###################################### +// UnregisterClientRequestHeader +//###################################### + +void UnregisterClientRequestHeader::Encode(Json::Value& extFields) { + extFields["clientID"] = clientID; + if (!producerGroup.empty()) { + extFields["producerGroup"] = producerGroup; + } + if (!consumerGroup.empty()) { + extFields["consumerGroup"] = consumerGroup; + } +} + +void UnregisterClientRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + requestMap.emplace("clientID", clientID); + if (!producerGroup.empty()) { + requestMap.emplace("producerGroup", producerGroup); + } + if (!consumerGroup.empty()) { + requestMap.emplace("consumerGroup", consumerGroup); + } +} + +//###################################### +// CreateTopicRequestHeader +//###################################### + +void CreateTopicRequestHeader::Encode(Json::Value& extFields) { + extFields["topic"] = topic; + extFields["defaultTopic"] = defaultTopic; + extFields["readQueueNums"] = UtilAll::to_string(readQueueNums); + extFields["writeQueueNums"] = UtilAll::to_string(writeQueueNums); + extFields["perm"] = UtilAll::to_string(perm); + extFields["topicFilterType"] = topicFilterType; + if (topicSysFlag != -1) { + extFields["topicSysFlag"] = UtilAll::to_string(topicSysFlag); + } + extFields["order"] = UtilAll::to_string(order); +} + +void CreateTopicRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + requestMap.emplace("topic", topic); + requestMap.emplace("defaultTopic", defaultTopic); + requestMap.emplace("readQueueNums", UtilAll::to_string(readQueueNums)); + requestMap.emplace("writeQueueNums", UtilAll::to_string(writeQueueNums)); + requestMap.emplace("perm", UtilAll::to_string(perm)); + requestMap.emplace("topicFilterType", topicFilterType); + if (topicSysFlag != -1) { + requestMap.emplace("topicSysFlag", UtilAll::to_string(topicSysFlag)); + } + requestMap.emplace("order", UtilAll::to_string(order)); +} + +//###################################### +// CheckTransactionStateRequestHeader +//###################################### + +CheckTransactionStateRequestHeader* CheckTransactionStateRequestHeader::Decode( + std::map& extFields) { + std::unique_ptr header(new CheckTransactionStateRequestHeader()); + header->tranStateTableOffset = std::stoll(extFields.at("tranStateTableOffset")); + header->commitLogOffset = std::stoll(extFields.at("commitLogOffset")); + + auto it = extFields.find("msgId"); + if (it != extFields.end()) { + header->msgId = it->second; + } + + it = extFields.find("transactionId"); + if (it != extFields.end()) { + header->transactionId = it->second; + } + + it = extFields.find("offsetMsgId"); + if (it != extFields.end()) { + header->offsetMsgId = it->second; + } + + return header.release(); +} + +void CheckTransactionStateRequestHeader::SetDeclaredFieldOfCommandHeader( + std::map& requestMap) { + // TODO: unnecessary + requestMap.emplace("tranStateTableOffset", UtilAll::to_string(tranStateTableOffset)); + requestMap.emplace("commitLogOffset", UtilAll::to_string(commitLogOffset)); + requestMap.emplace("msgId", msgId); + requestMap.emplace("transactionId", transactionId); + requestMap.emplace("offsetMsgId", offsetMsgId); +} + +std::string CheckTransactionStateRequestHeader::toString() const { + std::stringstream ss; + ss << "CheckTransactionStateRequestHeader:"; + ss << " tranStateTableOffset:" << tranStateTableOffset; + ss << " commitLogOffset:" << commitLogOffset; + ss << " msgId:" << msgId; + ss << " transactionId:" << transactionId; + ss << " offsetMsgId:" << offsetMsgId; + return ss.str(); +} + +//###################################### +// EndTransactionRequestHeader +//###################################### + +void EndTransactionRequestHeader::Encode(Json::Value& extFields) { + extFields["producerGroup"] = producerGroup; + extFields["tranStateTableOffset"] = UtilAll::to_string(tranStateTableOffset); + extFields["commitLogOffset"] = UtilAll::to_string(commitLogOffset); + extFields["commitOrRollback"] = UtilAll::to_string(commitOrRollback); + extFields["fromTransactionCheck"] = UtilAll::to_string(fromTransactionCheck); + extFields["msgId"] = msgId; + if (!transactionId.empty()) { + extFields["transactionId"] = transactionId; + } +} + +void EndTransactionRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + requestMap.emplace("producerGroup", producerGroup); + requestMap.emplace("tranStateTableOffset", UtilAll::to_string(tranStateTableOffset)); + requestMap.emplace("commitLogOffset", UtilAll::to_string(commitLogOffset)); + requestMap.emplace("commitOrRollback", UtilAll::to_string(commitOrRollback)); + requestMap.emplace("fromTransactionCheck", UtilAll::to_string(fromTransactionCheck)); + requestMap.emplace("msgId", msgId); + if (!transactionId.empty()) { + requestMap.emplace("transactionId", transactionId); + } +} + +std::string EndTransactionRequestHeader::toString() const { + std::stringstream ss; + ss << "EndTransactionRequestHeader:"; + ss << " m_producerGroup:" << producerGroup; + ss << " m_tranStateTableOffset:" << tranStateTableOffset; + ss << " m_commitLogOffset:" << commitLogOffset; + ss << " m_commitOrRollback:" << commitOrRollback; + ss << " m_fromTransactionCheck:" << fromTransactionCheck; + ss << " m_msgId:" << msgId; + ss << " m_transactionId:" << transactionId; + return ss.str(); +} + +//###################################### +// SendMessageRequestHeader +//###################################### + +void SendMessageRequestHeader::Encode(Json::Value& extFields) { + extFields["producerGroup"] = producerGroup; + extFields["topic"] = topic; + extFields["defaultTopic"] = defaultTopic; + extFields["defaultTopicQueueNums"] = UtilAll::to_string(defaultTopicQueueNums); + extFields["queueId"] = UtilAll::to_string(queueId); + extFields["sysFlag"] = UtilAll::to_string(sysFlag); + extFields["bornTimestamp"] = UtilAll::to_string(bornTimestamp); + extFields["flag"] = UtilAll::to_string(flag); + if (!properties.empty()) { + extFields["properties"] = properties; + } + if (reconsumeTimes != -1) { + extFields["reconsumeTimes"] = UtilAll::to_string(reconsumeTimes); + } + extFields["unitMode"] = UtilAll::to_string(unitMode); + extFields["batch"] = UtilAll::to_string(batch); + if (maxReconsumeTimes != -1) { + extFields["maxReconsumeTimes"] = UtilAll::to_string(maxReconsumeTimes); + } +} + +void SendMessageRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + LOG_DEBUG_NEW( + "SendMessageRequestHeader producerGroup:{}, topic:%s, defaulttopic:{}, properties:{}, " + "defaultTopicQueueNums:{}, queueId:{}, sysFlag:{}, bornTimestamp:{}, flag:{}", + producerGroup, topic, defaultTopic, properties, defaultTopicQueueNums, queueId, sysFlag, bornTimestamp, flag); + + requestMap.emplace("producerGroup", producerGroup); + requestMap.emplace("topic", topic); + requestMap.emplace("defaultTopic", defaultTopic); + requestMap.emplace("defaultTopicQueueNums", UtilAll::to_string(defaultTopicQueueNums)); + requestMap.emplace("queueId", UtilAll::to_string(queueId)); + requestMap.emplace("sysFlag", UtilAll::to_string(sysFlag)); + requestMap.emplace("bornTimestamp", UtilAll::to_string(bornTimestamp)); + requestMap.emplace("flag", UtilAll::to_string(flag)); + if (!properties.empty()) { + requestMap.emplace("properties", properties); + } + if (reconsumeTimes != -1) { + requestMap.emplace("reconsumeTimes", UtilAll::to_string(reconsumeTimes)); + } + requestMap.emplace("unitMode", UtilAll::to_string(unitMode)); + requestMap.emplace("batch", UtilAll::to_string(batch)); + if (maxReconsumeTimes != -1) { + requestMap.emplace("maxReconsumeTimes", UtilAll::to_string(maxReconsumeTimes)); + } +} + +int SendMessageRequestHeader::getReconsumeTimes() { + return reconsumeTimes; +} + +void SendMessageRequestHeader::setReconsumeTimes(int _reconsumeTimes) { + reconsumeTimes = _reconsumeTimes; +} + +//###################################### +// SendMessageRequestHeaderV2 +//###################################### + +SendMessageRequestHeaderV2* SendMessageRequestHeaderV2::createSendMessageRequestHeaderV2(SendMessageRequestHeader* v1) { + SendMessageRequestHeaderV2* v2 = new SendMessageRequestHeaderV2(); + v2->a = v1->producerGroup; + v2->b = v1->topic; + v2->c = v1->defaultTopic; + v2->d = v1->defaultTopicQueueNums; + v2->e = v1->queueId; + v2->f = v1->sysFlag; + v2->g = v1->bornTimestamp; + v2->h = v1->flag; + v2->i = v1->properties; + v2->j = v1->reconsumeTimes; + v2->k = v1->unitMode; + v2->l = v1->maxReconsumeTimes; + v2->m = v1->batch; + return v2; +} + +void SendMessageRequestHeaderV2::Encode(Json::Value& extFields) { + extFields["a"] = a; + extFields["b"] = b; + extFields["c"] = c; + extFields["d"] = UtilAll::to_string(d); + extFields["e"] = UtilAll::to_string(e); + extFields["f"] = UtilAll::to_string(f); + extFields["g"] = UtilAll::to_string(g); + extFields["h"] = UtilAll::to_string(h); + if (!i.empty()) { + extFields["i"] = i; + } + if (j != -1) { + extFields["j"] = UtilAll::to_string(j); + } + extFields["k"] = UtilAll::to_string(k); + if (l != -1) { + extFields["l"] = UtilAll::to_string(l); + } + extFields["m"] = UtilAll::to_string(m); +} + +void SendMessageRequestHeaderV2::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + requestMap.emplace("a", a); + requestMap.emplace("b", b); + requestMap.emplace("c", c); + requestMap.emplace("d", UtilAll::to_string(d)); + requestMap.emplace("e", UtilAll::to_string(e)); + requestMap.emplace("f", UtilAll::to_string(f)); + requestMap.emplace("g", UtilAll::to_string(g)); + requestMap.emplace("h", UtilAll::to_string(h)); + if (!i.empty()) { + requestMap.emplace("i", i); + } + if (j != -1) { + requestMap.emplace("j", UtilAll::to_string(j)); + } + requestMap.emplace("k", UtilAll::to_string(k)); + if (l != -1) { + requestMap.emplace("l", UtilAll::to_string(l)); + } + requestMap.emplace("m", UtilAll::to_string(m)); +} + +//###################################### +// SendMessageResponseHeader +//###################################### + +SendMessageResponseHeader* SendMessageResponseHeader::Decode(std::map& extFields) { + std::unique_ptr header(new SendMessageResponseHeader()); + header->msgId = extFields.at("msgId"); + header->queueId = std::stoi(extFields.at("queueId")); + header->queueOffset = std::stoll(extFields.at("queueOffset")); + + auto it = extFields.find("transactionId"); + if (it != extFields.end()) { + header->transactionId = it->second; + } + + return header.release(); +} + +void SendMessageResponseHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + // TODO: unnecessary + requestMap.emplace("msgId", msgId); + requestMap.emplace("queueId", UtilAll::to_string(queueId)); + requestMap.emplace("queueOffset", UtilAll::to_string(queueOffset)); + requestMap.emplace("transactionId", transactionId); +} + +//###################################### +// PullMessageRequestHeader +//###################################### + +void PullMessageRequestHeader::Encode(Json::Value& extFields) { + extFields["consumerGroup"] = consumerGroup; + extFields["topic"] = topic; + extFields["queueId"] = queueId; + extFields["queueOffset"] = UtilAll::to_string(queueOffset); + extFields["maxMsgNums"] = maxMsgNums; + extFields["sysFlag"] = sysFlag; + extFields["commitOffset"] = UtilAll::to_string(commitOffset); + extFields["suspendTimeoutMillis"] = UtilAll::to_string(suspendTimeoutMillis); + if (!subscription.empty()) { + extFields["subscription"] = subscription; + } + extFields["subVersion"] = UtilAll::to_string(subVersion); + if (!expressionType.empty()) { + extFields["expressionType"] = expressionType; + } +} + +void PullMessageRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + requestMap.emplace("consumerGroup", consumerGroup); + requestMap.emplace("topic", topic); + requestMap.emplace("queueId", UtilAll::to_string(queueId)); + requestMap.emplace("queueOffset", UtilAll::to_string(queueOffset)); + requestMap.emplace("maxMsgNums", UtilAll::to_string(maxMsgNums)); + requestMap.emplace("sysFlag", UtilAll::to_string(sysFlag)); + requestMap.emplace("commitOffset", UtilAll::to_string(commitOffset)); + requestMap.emplace("suspendTimeoutMillis", UtilAll::to_string(suspendTimeoutMillis)); + if (!subscription.empty()) { + requestMap.emplace("subscription", subscription); + } + requestMap.emplace("subVersion", UtilAll::to_string(subVersion)); + if (!expressionType.empty()) { + requestMap.emplace("expressionType", expressionType); + } +} + +//###################################### +// PullMessageResponseHeader +//###################################### + +PullMessageResponseHeader* PullMessageResponseHeader::Decode(std::map& extFields) { + std::unique_ptr header(new PullMessageResponseHeader()); + header->suggestWhichBrokerId = std::stoll(extFields.at("suggestWhichBrokerId")); + header->nextBeginOffset = std::stoll(extFields.at("nextBeginOffset")); + header->minOffset = std::stoll(extFields.at("minOffset")); + header->maxOffset = std::stoll(extFields.at("maxOffset")); + return header.release(); +} + +void PullMessageResponseHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + // TODO: unnecessary + requestMap.emplace("suggestWhichBrokerId", UtilAll::to_string(suggestWhichBrokerId)); + requestMap.emplace("nextBeginOffset", UtilAll::to_string(nextBeginOffset)); + requestMap.emplace("minOffset", UtilAll::to_string(minOffset)); + requestMap.emplace("maxOffset", UtilAll::to_string(maxOffset)); +} + +//###################################### +// GetConsumerListByGroupResponseHeader +//###################################### + +void GetConsumerListByGroupResponseHeader::Encode(Json::Value& extFields) {} + +void GetConsumerListByGroupResponseHeader::SetDeclaredFieldOfCommandHeader( + std::map& requestMap) {} + +//###################################### +// GetMinOffsetRequestHeader +//###################################### + +void GetMinOffsetRequestHeader::Encode(Json::Value& extFields) { + extFields["topic"] = topic; + extFields["queueId"] = UtilAll::to_string(queueId); +} + +void GetMinOffsetRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + requestMap.emplace("topic", topic); + requestMap.emplace("queueId", UtilAll::to_string(queueId)); +} + +//###################################### +// GetMinOffsetResponseHeader +//###################################### + +GetMinOffsetResponseHeader* GetMinOffsetResponseHeader::Decode(std::map& extFields) { + std::unique_ptr header(new GetMinOffsetResponseHeader()); + header->offset = std::stoll(extFields.at("offset")); + return header.release(); +} + +void GetMinOffsetResponseHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + // TODO: unnecessary + requestMap.emplace("offset", UtilAll::to_string(offset)); +} + +//###################################### +// GetMaxOffsetRequestHeader +//###################################### + +void GetMaxOffsetRequestHeader::Encode(Json::Value& extFields) { + extFields["topic"] = topic; + extFields["queueId"] = UtilAll::to_string(queueId); +} + +void GetMaxOffsetRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + requestMap.emplace("topic", topic); + requestMap.emplace("queueId", UtilAll::to_string(queueId)); +} + +//###################################### +// GetMaxOffsetResponseHeader +//###################################### + +GetMaxOffsetResponseHeader* GetMaxOffsetResponseHeader::Decode(std::map& extFields) { + std::unique_ptr header(new GetMaxOffsetResponseHeader()); + header->offset = std::stoll(extFields.at("offset")); + return header.release(); +} + +void GetMaxOffsetResponseHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + // TODO: unnecessary + requestMap.emplace("offset", UtilAll::to_string(offset)); +} + +//###################################### +// SearchOffsetRequestHeader +//###################################### + +void SearchOffsetRequestHeader::Encode(Json::Value& extFields) { + extFields["topic"] = topic; + extFields["queueId"] = UtilAll::to_string(queueId); + extFields["timestamp"] = UtilAll::to_string(timestamp); +} + +void SearchOffsetRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + requestMap.emplace("topic", topic); + requestMap.emplace("queueId", UtilAll::to_string(queueId)); + requestMap.emplace("timestamp", UtilAll::to_string(timestamp)); +} + +//###################################### +// SearchOffsetResponseHeader +//###################################### + +SearchOffsetResponseHeader* SearchOffsetResponseHeader::Decode(std::map& extFields) { + std::unique_ptr header(new SearchOffsetResponseHeader()); + header->offset = std::stoll(extFields.at("offset")); + return header.release(); +} + +void SearchOffsetResponseHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + // TODO: unnecessary + requestMap.emplace("offset", UtilAll::to_string(offset)); +} + +//###################################### +// ViewMessageRequestHeader +//###################################### + +void ViewMessageRequestHeader::Encode(Json::Value& extFields) { + extFields["offset"] = UtilAll::to_string(offset); +} + +void ViewMessageRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + requestMap.emplace("offset", UtilAll::to_string(offset)); +} + +//###################################### +// GetEarliestMsgStoretimeRequestHeader +//###################################### + +void GetEarliestMsgStoretimeRequestHeader::Encode(Json::Value& extFields) { + extFields["topic"] = topic; + extFields["queueId"] = UtilAll::to_string(queueId); +} + +void GetEarliestMsgStoretimeRequestHeader::SetDeclaredFieldOfCommandHeader( + std::map& requestMap) { + requestMap.emplace("topic", topic); + requestMap.emplace("queueId", UtilAll::to_string(queueId)); +} + +//###################################### +// GetEarliestMsgStoretimeResponseHeader +//###################################### + +GetEarliestMsgStoretimeResponseHeader* GetEarliestMsgStoretimeResponseHeader::Decode( + std::map& extFields) { + std::unique_ptr header(new GetEarliestMsgStoretimeResponseHeader()); + header->timestamp = std::stoll(extFields.at("timestamp")); + return header.release(); +} + +void GetEarliestMsgStoretimeResponseHeader::SetDeclaredFieldOfCommandHeader( + std::map& requestMap) { + // TODO: unnecessary + requestMap.emplace("timestamp", UtilAll::to_string(timestamp)); +} + +//###################################### +// GetConsumerListByGroupRequestHeader +//###################################### + +void GetConsumerListByGroupRequestHeader::Encode(Json::Value& extFields) { + extFields["consumerGroup"] = consumerGroup; +} + +void GetConsumerListByGroupRequestHeader::SetDeclaredFieldOfCommandHeader( + std::map& requestMap) { + requestMap.emplace("consumerGroup", consumerGroup); +} + +//###################################### +// QueryConsumerOffsetRequestHeader +//###################################### + +void QueryConsumerOffsetRequestHeader::Encode(Json::Value& extFields) { + extFields["consumerGroup"] = consumerGroup; + extFields["topic"] = topic; + extFields["queueId"] = UtilAll::to_string(queueId); +} + +void QueryConsumerOffsetRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + requestMap.emplace("consumerGroup", consumerGroup); + requestMap.emplace("topic", topic); + requestMap.emplace("queueId", UtilAll::to_string(queueId)); +} + +//###################################### +// QueryConsumerOffsetResponseHeader +//###################################### + +QueryConsumerOffsetResponseHeader* QueryConsumerOffsetResponseHeader::Decode( + std::map& extFields) { + std::unique_ptr header(new QueryConsumerOffsetResponseHeader()); + header->offset = std::stoll(extFields.at("offset")); + return header.release(); +} + +void QueryConsumerOffsetResponseHeader::SetDeclaredFieldOfCommandHeader( + std::map& requestMap) { + // TODO: unnecessary + requestMap.emplace("offset", UtilAll::to_string(offset)); +} + +//###################################### +// UpdateConsumerOffsetRequestHeader +//###################################### + +void UpdateConsumerOffsetRequestHeader::Encode(Json::Value& extFields) { + extFields["consumerGroup"] = consumerGroup; + extFields["topic"] = topic; + extFields["queueId"] = UtilAll::to_string(queueId); + extFields["commitOffset"] = UtilAll::to_string(commitOffset); +} + +void UpdateConsumerOffsetRequestHeader::SetDeclaredFieldOfCommandHeader( + std::map& requestMap) { + requestMap.emplace("consumerGroup", consumerGroup); + requestMap.emplace("topic", topic); + requestMap.emplace("queueId", std::to_string(queueId)); + requestMap.emplace("commitOffset", std::to_string(commitOffset)); +} + +//###################################### +// ConsumerSendMsgBackRequestHeader +//###################################### + +void ConsumerSendMsgBackRequestHeader::Encode(Json::Value& extFields) { + extFields["offset"] = std::to_string(offset); + extFields["group"] = group; + extFields["delayLevel"] = std::to_string(delayLevel); + if (!originMsgId.empty()) { + extFields["originMsgId"] = originMsgId; + } + if (!originTopic.empty()) { + extFields["originTopic"] = originTopic; + } + extFields["unitMode"] = std::to_string(unitMode); + if (maxReconsumeTimes != -1) { + extFields["maxReconsumeTimes"] = std::to_string(maxReconsumeTimes); + } +} + +void ConsumerSendMsgBackRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { + requestMap.emplace("offset", std::to_string(offset)); + requestMap.emplace("group", group); + requestMap.emplace("delayLevel", std::to_string(delayLevel)); + if (!originMsgId.empty()) { + requestMap.emplace("originMsgId", originMsgId); + } + if (!originTopic.empty()) { + requestMap.emplace("originTopic", originTopic); + } + requestMap.emplace("unitMode", std::to_string(unitMode)); + if (maxReconsumeTimes != -1) { + requestMap.emplace("maxReconsumeTimes", std::to_string(maxReconsumeTimes)); + } +} + +//###################################### +// GetConsumerListByGroupResponseBody +//###################################### + +GetConsumerListByGroupResponseBody* GetConsumerListByGroupResponseBody::Decode(MemoryBlock& mem) { + Json::Value root = RemotingSerializable::fromJson(mem); + auto& ids = root["consumerIdList"]; + std::unique_ptr body(new GetConsumerListByGroupResponseBody()); + for (unsigned int i = 0; i < ids.size(); i++) { + body->consumerIdList.push_back(ids[i].asString()); + } + return body.release(); +} + +void GetConsumerListByGroupResponseBody::SetDeclaredFieldOfCommandHeader( + std::map& requestMap) {} + +//###################################### +// ResetOffsetRequestHeader +//###################################### + +ResetOffsetRequestHeader* ResetOffsetRequestHeader::Decode(std::map& extFields) { + std::unique_ptr header(new ResetOffsetRequestHeader()); + header->topic = extFields.at("topic"); + header->group = extFields.at("group"); + header->timestamp = std::stoll(extFields.at("timestamp")); + header->isForce = UtilAll::stob(extFields.at("isForce")); + LOG_INFO("topic:%s, group:%s, timestamp:%lld, isForce:%d", header->topic.c_str(), header->group.c_str(), + header->timestamp, header->isForce); + return header.release(); +} + +void ResetOffsetRequestHeader::setTopic(const std::string& tmp) { + topic = tmp; +} + +void ResetOffsetRequestHeader::setGroup(const std::string& tmp) { + group = tmp; +} + +void ResetOffsetRequestHeader::setTimeStamp(const int64_t& tmp) { + timestamp = tmp; +} + +void ResetOffsetRequestHeader::setForceFlag(const bool& tmp) { + isForce = tmp; +} + +const std::string ResetOffsetRequestHeader::getTopic() const { + return topic; +} + +const std::string ResetOffsetRequestHeader::getGroup() const { + return group; +} + +const int64_t ResetOffsetRequestHeader::getTimeStamp() const { + return timestamp; +} + +const bool ResetOffsetRequestHeader::getForceFlag() const { + return isForce; +} + +//###################################### +// GetConsumerRunningInfoRequestHeader +//###################################### + +GetConsumerRunningInfoRequestHeader* GetConsumerRunningInfoRequestHeader::Decode( + std::map& extFields) { + std::unique_ptr header(new GetConsumerRunningInfoRequestHeader()); + header->consumerGroup = extFields.at("consumerGroup"); + header->clientId = extFields.at("clientId"); + header->jstackEnable = UtilAll::stob(extFields.at("jstackEnable")); + LOG_INFO("consumerGroup:%s, clientId:%s, jstackEnable:%d", header->consumerGroup.c_str(), header->clientId.c_str(), + header->jstackEnable); + return header.release(); +} + +void GetConsumerRunningInfoRequestHeader::Encode(Json::Value& extFields) { + extFields["consumerGroup"] = consumerGroup; + extFields["clientId"] = clientId; + extFields["jstackEnable"] = UtilAll::to_string(jstackEnable); +} + +void GetConsumerRunningInfoRequestHeader::SetDeclaredFieldOfCommandHeader( + std::map& requestMap) { + requestMap.emplace("consumerGroup", consumerGroup); + requestMap.emplace("clientId", clientId); + requestMap.emplace("jstackEnable", std::to_string(jstackEnable)); +} + +const std::string GetConsumerRunningInfoRequestHeader::getConsumerGroup() const { + return consumerGroup; +} + +void GetConsumerRunningInfoRequestHeader::setConsumerGroup(const std::string& consumerGroup) { + this->consumerGroup = consumerGroup; +} + +const std::string GetConsumerRunningInfoRequestHeader::getClientId() const { + return clientId; +} + +void GetConsumerRunningInfoRequestHeader::setClientId(const std::string& clientId) { + this->clientId = clientId; +} + +const bool GetConsumerRunningInfoRequestHeader::isJstackEnable() const { + return jstackEnable; +} + +void GetConsumerRunningInfoRequestHeader::setJstackEnable(const bool& jstackEnable) { + this->jstackEnable = jstackEnable; +} + +//###################################### +// NotifyConsumerIdsChangedRequestHeader +//###################################### + +NotifyConsumerIdsChangedRequestHeader* NotifyConsumerIdsChangedRequestHeader::Decode( + std::map& extFields) { + std::unique_ptr header(new NotifyConsumerIdsChangedRequestHeader()); + header->consumerGroup = extFields.at("consumerGroup"); + return header.release(); +} + +const std::string NotifyConsumerIdsChangedRequestHeader::getConsumerGroup() const { + return consumerGroup; +} + +void NotifyConsumerIdsChangedRequestHeader::setConsumerGroup(const std::string& consumerGroup) { + this->consumerGroup = consumerGroup; +} + +} // namespace rocketmq diff --git a/src/protocol/CommandHeader.h b/src/protocol/CommandHeader.h index bf74e0709..a83fd1939 100644 --- a/src/protocol/CommandHeader.h +++ b/src/protocol/CommandHeader.h @@ -14,133 +14,95 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef __COMMAND_HEADER_H__ +#define __COMMAND_HEADER_H__ -#ifndef __COMMANDCUSTOMHEADER_H__ -#define __COMMANDCUSTOMHEADER_H__ +#include -#include -#include -#include "MQClientException.h" -#include "MessageSysFlag.h" -#include "UtilAll.h" -#include "dataBlock.h" -#include "json/json.h" +#include "CommandCustomHeader.h" +#include "DataBlock.h" namespace rocketmq { -//& requestMap) {} -}; + GetRouteInfoRequestHeader(const std::string& _topic) : topic(_topic) {} -class CheckTransactionStateRequestHeader : public CommandHeader { - public: - CheckTransactionStateRequestHeader() {} - CheckTransactionStateRequestHeader(long tableOffset, - long commLogOffset, - const std::string& msgid, - const std::string& transactionId, - const std::string& offsetMsgId) - : m_tranStateTableOffset(tableOffset), - m_commitLogOffset(commLogOffset), - m_msgId(msgid), - m_transactionId(transactionId), - m_offsetMsgId(offsetMsgId) {} - virtual ~CheckTransactionStateRequestHeader() {} - virtual void Encode(Json::Value& outData); - static CommandHeader* Decode(Json::Value& ext); - virtual void SetDeclaredFieldOfCommandHeader(std::map& requestMap); - std::string toString(); - - public: - long m_tranStateTableOffset; - long m_commitLogOffset; - std::string m_msgId; - std::string m_transactionId; - std::string m_offsetMsgId; -}; + void Encode(Json::Value& extFields) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; -class EndTransactionRequestHeader : public CommandHeader { - public: - EndTransactionRequestHeader() {} - EndTransactionRequestHeader(const std::string& groupName, - long tableOffset, - long commLogOffset, - int commitOrRoll, - bool fromTransCheck, - const std::string& msgid, - const std::string& transId) - : m_producerGroup(groupName), - m_tranStateTableOffset(tableOffset), - m_commitLogOffset(commLogOffset), - m_commitOrRollback(commitOrRoll), - m_fromTransactionCheck(fromTransCheck), - m_msgId(msgid), - m_transactionId(transId) {} - virtual ~EndTransactionRequestHeader() {} - virtual void Encode(Json::Value& outData); - virtual void SetDeclaredFieldOfCommandHeader(std::map& requestMap); - std::string toString(); - - public: - std::string m_producerGroup; - long m_tranStateTableOffset; - long m_commitLogOffset; - int m_commitOrRollback; - bool m_fromTransactionCheck; - std::string m_msgId; - std::string m_transactionId; + private: + std::string topic; }; -//& requestMap); + UnregisterClientRequestHeader(std::string cID, std::string proGroup, std::string conGroup) + : clientID(cID), producerGroup(proGroup), consumerGroup(conGroup) {} + + void Encode(Json::Value& extFields) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; private: - string topic; + std::string clientID; + std::string producerGroup; // nullable + std::string consumerGroup; // nullable }; -//& requestMap); + CreateTopicRequestHeader() : readQueueNums(0), writeQueueNums(0), perm(0), topicSysFlag(-1), order(false) {} - private: - string clientID; - string producerGroup; - string consumerGroup; + void Encode(Json::Value& extFields) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; + + public: + std::string topic; + std::string defaultTopic; + int32_t readQueueNums; + int32_t writeQueueNums; + int32_t perm; + std::string topicFilterType; + int32_t topicSysFlag; // nullable + bool order; }; -//& requestMap); + CheckTransactionStateRequestHeader() : tranStateTableOffset(0), commitLogOffset(0) {} + + static CheckTransactionStateRequestHeader* Decode(std::map& extFields); + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; + std::string toString() const; public: - string topic; - string defaultTopic; - int readQueueNums; - int writeQueueNums; - int perm; - string topicFilterType; + int64_t tranStateTableOffset; + int64_t commitLogOffset; + std::string msgId; // nullable + std::string transactionId; // nullable + std::string offsetMsgId; // nullable }; -//& requestMap) override; + std::string toString() const; + + public: + std::string producerGroup; + int64_t tranStateTableOffset; + int64_t commitLogOffset; + int32_t commitOrRollback; + bool fromTransactionCheck; // nullable + std::string msgId; + std::string transactionId; // nullable +}; + +class SendMessageRequestHeader : public CommandCustomHeader { public: SendMessageRequestHeader() : defaultTopicQueueNums(0), @@ -148,385 +110,357 @@ class SendMessageRequestHeader : public CommandHeader { sysFlag(0), bornTimestamp(0), flag(0), - reconsumeTimes(0), + reconsumeTimes(-1), unitMode(false), - consumeRetryTimes(0), - batch(false) {} - virtual ~SendMessageRequestHeader() {} - virtual void Encode(Json::Value& outData); - virtual void SetDeclaredFieldOfCommandHeader(map& requestMap); - - public: - string producerGroup; - string topic; - string defaultTopic; - int defaultTopicQueueNums; - int queueId; - int sysFlag; - int64 bornTimestamp; - int flag; - string properties; - int reconsumeTimes; - bool unitMode; - int consumeRetryTimes; - bool batch; + batch(false), + maxReconsumeTimes(1) {} + + void Encode(Json::Value& extFields) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; + + int getReconsumeTimes(); + void setReconsumeTimes(int _reconsumeTimes); + + public: + std::string producerGroup; + std::string topic; + std::string defaultTopic; + int32_t defaultTopicQueueNums; + int32_t queueId; + int32_t sysFlag; + int64_t bornTimestamp; + int32_t flag; + std::string properties; // nullable + int32_t reconsumeTimes; // nullable + bool unitMode; // nullable + bool batch; // nullable + int32_t maxReconsumeTimes; // nullable }; -//& requestMap); - virtual void CreateSendMessageRequestHeaderV1(SendMessageRequestHeader& v1); - - public: - string a; // producerGroup - string b; // topic; - string c; // defaultTopic; - int d; // defaultTopicQueueNums; - int e; // queueId; - int f; // sysFlag; - int64 g; // bornTimestamp; - int h; // flag; - string i; // properties; - int j; // reconsumeTimes; - bool k; // unitMode; - int l; // consumeRetryTimes; - bool m; // batch; +class SendMessageRequestHeaderV2 : public CommandCustomHeader { + public: + static SendMessageRequestHeaderV2* createSendMessageRequestHeaderV2(SendMessageRequestHeader* v1); + + void Encode(Json::Value& outData) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; + + private: + SendMessageRequestHeaderV2() {} + + public: + std::string a; // producerGroup + std::string b; // topic + std::string c; // defaultTopic + int32_t d; // defaultTopicQueueNums + int32_t e; // queueId + int32_t f; // sysFlag + int64_t g; // bornTimestamp + int32_t h; // flag + std::string i; // nullable, properties + int32_t j; // nullable, reconsumeTimes + bool k; // nullable, unitMode + int32_t l; // nullable, maxReconsumeTimes + bool m; // nullable, batch }; -//& requestMap); + SendMessageResponseHeader() : queueId(0), queueOffset(0) {} + + static SendMessageResponseHeader* Decode(std::map& extFields); + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - string msgId; - int queueId; - int64 queueOffset; + std::string msgId; + int32_t queueId; + int64_t queueOffset; + std::string transactionId; // nullable }; -//& requestMap); - - public: - string consumerGroup; - string topic; - int queueId; - int maxMsgNums; - int sysFlag; - string subscription; - int64 queueOffset; - int64 commitOffset; - int64 suspendTimeoutMillis; - int64 subVersion; + + void Encode(Json::Value& extFields) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; + + public: + std::string consumerGroup; + std::string topic; + int32_t queueId; + int64_t queueOffset; + int32_t maxMsgNums; + int32_t sysFlag; + int64_t commitOffset; + int64_t suspendTimeoutMillis; + std::string subscription; // nullable + int64_t subVersion; + std::string expressionType; // nullable }; -//& requestMap); + + static PullMessageResponseHeader* Decode(std::map& extFields); + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - int64 suggestWhichBrokerId; - int64 nextBeginOffset; - int64 minOffset; - int64 maxOffset; + int64_t suggestWhichBrokerId; + int64_t nextBeginOffset; + int64_t minOffset; + int64_t maxOffset; }; -//& requestMap); + void Encode(Json::Value& extFields) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; }; -//& requestMap); + GetMinOffsetRequestHeader() : queueId(0) {} + + void Encode(Json::Value& extFields) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - string topic; - int queueId; + std::string topic; + int32_t queueId; }; -//& requestMap); + GetMinOffsetResponseHeader() : offset(0) {} + + static GetMinOffsetResponseHeader* Decode(std::map& extFields); + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - int64 offset; + int64_t offset; }; -//& requestMap); + GetMaxOffsetRequestHeader() : queueId(0) {} + + void Encode(Json::Value& extFields) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - string topic; - int queueId; + std::string topic; + int32_t queueId; }; -//& requestMap); + GetMaxOffsetResponseHeader() : offset(0) {} + + static GetMaxOffsetResponseHeader* Decode(std::map& extFields); + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - int64 offset; + int64_t offset; }; -//& requestMap); + SearchOffsetRequestHeader() : queueId(0), timestamp(0) {} + + void Encode(Json::Value& extFields) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - string topic; - int queueId; - int64 timestamp; + std::string topic; + int32_t queueId; + int64_t timestamp; }; -//& requestMap); + SearchOffsetResponseHeader() : offset(0) {} + + static SearchOffsetResponseHeader* Decode(std::map& extFields); + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - int64 offset; + int64_t offset; }; -//& requestMap); + ViewMessageRequestHeader() : offset(0) {} + + void Encode(Json::Value& extFields) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - int64 offset; + int64_t offset; }; -//& requestMap); + GetEarliestMsgStoretimeRequestHeader() : queueId(0) {} + + void Encode(Json::Value& extFields) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - string topic; - int queueId; + std::string topic; + int32_t queueId; }; -//& requestMap); + GetEarliestMsgStoretimeResponseHeader() : timestamp(0) {} + + static GetEarliestMsgStoretimeResponseHeader* Decode(std::map& extFields); + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - int64 timestamp; + int64_t timestamp; }; -//& requestMap); + void Encode(Json::Value& extFields) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - string consumerGroup; + std::string consumerGroup; }; -//& requestMap); + QueryConsumerOffsetRequestHeader() : queueId(0) {} + + void Encode(Json::Value& extFields) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - string consumerGroup; - string topic; - int queueId; + std::string consumerGroup; + std::string topic; + int32_t queueId; }; -//& requestMap); + QueryConsumerOffsetResponseHeader() : offset(0) {} + + static QueryConsumerOffsetResponseHeader* Decode(std::map& extFields); + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - int64 offset; + int64_t offset; }; -//& requestMap); + UpdateConsumerOffsetRequestHeader() : queueId(0), commitOffset(0) {} + + void Encode(Json::Value& extFields) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - string consumerGroup; - string topic; - int queueId; - int64 commitOffset; + std::string consumerGroup; + std::string topic; + int32_t queueId; + int64_t commitOffset; }; -//& requestMap); + ConsumerSendMsgBackRequestHeader() : offset(0), delayLevel(0), unitMode(false), maxReconsumeTimes(-1) {} + + void Encode(Json::Value& extFields) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - string group; - int delayLevel; - int64 offset; - bool unitMode = false; - string originMsgId; - string originTopic; - int maxReconsumeTimes = 16; + int64_t offset; + std::string group; + int32_t delayLevel; + std::string originMsgId; // nullable + std::string originTopic; // nullable + bool unitMode; + int32_t maxReconsumeTimes; // nullable }; -//& requestMap); + static GetConsumerListByGroupResponseBody* Decode(MemoryBlock& mem); + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: - static void Decode(const MemoryBlock* mem, vector& cids); + std::vector consumerIdList; }; -class ResetOffsetRequestHeader : public CommandHeader { +class ResetOffsetRequestHeader : public CommandCustomHeader { public: - ResetOffsetRequestHeader() {} - ~ResetOffsetRequestHeader() {} - static CommandHeader* Decode(Json::Value& ext); - void setTopic(const string& tmp); - void setGroup(const string& tmp); - void setTimeStamp(const int64& tmp); - void setForceFlag(const bool& tmp); - const string getTopic() const; - const string getGroup() const; - const int64 getTimeStamp() const; + ResetOffsetRequestHeader() : timestamp(0), isForce(false) {} + + static ResetOffsetRequestHeader* Decode(std::map& extFields); + + const std::string getTopic() const; + void setTopic(const std::string& tmp); + + const std::string getGroup() const; + void setGroup(const std::string& tmp); + + const int64_t getTimeStamp() const; + void setTimeStamp(const int64_t& tmp); + const bool getForceFlag() const; + void setForceFlag(const bool& tmp); private: - string topic; - string group; - int64 timestamp; + std::string topic; + std::string group; + int64_t timestamp; bool isForce; }; -class GetConsumerRunningInfoRequestHeader : public CommandHeader { - public: - GetConsumerRunningInfoRequestHeader() {} - virtual ~GetConsumerRunningInfoRequestHeader() {} - virtual void Encode(Json::Value& outData); - virtual void SetDeclaredFieldOfCommandHeader(map& requestMap); - static CommandHeader* Decode(Json::Value& ext); - const string getConsumerGroup() const; - void setConsumerGroup(const string& consumerGroup); - const string getClientId() const; - void setClientId(const string& clientId); +class GetConsumerRunningInfoRequestHeader : public CommandCustomHeader { + public: + GetConsumerRunningInfoRequestHeader() : jstackEnable(false) {} + + static GetConsumerRunningInfoRequestHeader* Decode(std::map& extFields); + void Encode(Json::Value& extFields) override; + void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; + + const std::string getConsumerGroup() const; + void setConsumerGroup(const std::string& consumerGroup); + + const std::string getClientId() const; + void setClientId(const std::string& clientId); + const bool isJstackEnable() const; void setJstackEnable(const bool& jstackEnable); private: - string consumerGroup; - string clientId; - bool jstackEnable; + std::string consumerGroup; + std::string clientId; + bool jstackEnable; // nullable }; -class NotifyConsumerIdsChangedRequestHeader : public CommandHeader { +class NotifyConsumerIdsChangedRequestHeader : public CommandCustomHeader { public: - NotifyConsumerIdsChangedRequestHeader() {} - virtual ~NotifyConsumerIdsChangedRequestHeader() {} - static CommandHeader* Decode(Json::Value& ext); - void setGroup(const string& tmp); - const string getGroup() const; + static NotifyConsumerIdsChangedRequestHeader* Decode(std::map& extFields); + + const std::string getConsumerGroup() const; + void setConsumerGroup(const std::string& tmp); private: - string consumerGroup; + std::string consumerGroup; }; -// ConsumerRunningInfo::getProperties() const { + +const std::string ConsumerRunningInfo::PROP_NAMESERVER_ADDR = "PROP_NAMESERVER_ADDR"; +const std::string ConsumerRunningInfo::PROP_THREADPOOL_CORE_SIZE = "PROP_THREADPOOL_CORE_SIZE"; +const std::string ConsumerRunningInfo::PROP_CONSUME_ORDERLY = "PROP_CONSUMEORDERLY"; +const std::string ConsumerRunningInfo::PROP_CONSUME_TYPE = "PROP_CONSUME_TYPE"; +const std::string ConsumerRunningInfo::PROP_CLIENT_VERSION = "PROP_CLIENT_VERSION"; +const std::string ConsumerRunningInfo::PROP_CONSUMER_START_TIMESTAMP = "PROP_CONSUMER_START_TIMESTAMP"; + +const std::map ConsumerRunningInfo::getProperties() const { return properties; } -void ConsumerRunningInfo::setProperties(const map& input_properties) { - properties = input_properties; +void ConsumerRunningInfo::setProperties(const std::map& properties) { + this->properties = properties; } -void ConsumerRunningInfo::setProperty(const string& key, const string& value) { +void ConsumerRunningInfo::setProperty(const std::string& key, const std::string& value) { properties[key] = value; } -const map ConsumerRunningInfo::getMqTable() const { +const std::map ConsumerRunningInfo::getMqTable() const { return mqTable; } -void ConsumerRunningInfo::setMqTable(MessageQueue queue, ProcessQueueInfo queueInfo) { +void ConsumerRunningInfo::setMqTable(const MQMessageQueue& queue, ProcessQueueInfo queueInfo) { mqTable[queue] = queueInfo; } -/*const map ConsumerRunningInfo::getStatusTable() const -{ -return statusTable; +/* const std::map ConsumerRunningInfo::getStatusTable() const { + return statusTable; } +void ConsumerRunningInfo::setStatusTable(const std::map& statusTable) { + this->statusTable = statusTable; +} */ -void ConsumerRunningInfo::setStatusTable(const map& -input_statusTable) -{ -statusTable = input_statusTable; -} */ - -const vector ConsumerRunningInfo::getSubscriptionSet() const { +const std::vector ConsumerRunningInfo::getSubscriptionSet() const { return subscriptionSet; } -void ConsumerRunningInfo::setSubscriptionSet(const vector& input_subscriptionSet) { - subscriptionSet = input_subscriptionSet; +void ConsumerRunningInfo::setSubscriptionSet(const std::vector& subscriptionSet) { + this->subscriptionSet = subscriptionSet; } -const string ConsumerRunningInfo::getJstack() const { +const std::string ConsumerRunningInfo::getJstack() const { return jstack; } -void ConsumerRunningInfo::setJstack(const string& input_jstack) { - jstack = input_jstack; +void ConsumerRunningInfo::setJstack(const std::string& jstack) { + this->jstack = jstack; } -string ConsumerRunningInfo::encode() { +std::string ConsumerRunningInfo::encode() { Json::Value outData; outData[PROP_NAMESERVER_ADDR] = properties[PROP_NAMESERVER_ADDR]; @@ -87,24 +85,21 @@ string ConsumerRunningInfo::encode() { root["jstack"] = jstack; root["properties"] = outData; - { - vector::const_iterator it = subscriptionSet.begin(); - for (; it != subscriptionSet.end(); it++) { - root["subscriptionSet"].append(it->toJson()); - } + for (const auto& subscription : subscriptionSet) { + root["subscriptionSet"].append(subscription.toJson()); } Json::FastWriter fastwrite; - string finals = fastwrite.write(root); + std::string finals = fastwrite.write(root); Json::Value mq; - string key = "\"mqTable\":"; + std::string key = "\"mqTable\":"; key.append("{"); - for (map::iterator it = mqTable.begin(); it != mqTable.end(); ++it) { - key.append((it->first).toJson().toStyledString()); + for (const auto& it : mqTable) { + key.append(toJson(it.first).toStyledString()); key.erase(key.end() - 1); key.append(":"); - key.append((it->second).toJson().toStyledString()); + key.append(it.second.toJson().toStyledString()); key.append(","); } key.erase(key.end() - 1); @@ -116,4 +111,5 @@ string ConsumerRunningInfo::encode() { return finals; } -} + +} // namespace rocketmq diff --git a/src/protocol/ConsumerRunningInfo.h b/src/protocol/ConsumerRunningInfo.h index 3c83834b6..cdc23dc90 100644 --- a/src/protocol/ConsumerRunningInfo.h +++ b/src/protocol/ConsumerRunningInfo.h @@ -1,21 +1,21 @@ /* -* 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 __CONSUMERRUNNINGINFO_H__ -#define __CONSUMERRUNNINGINFO_H__ + * 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 __CONSUMER_RUNNING_INFO_H__ +#define __CONSUMER_RUNNING_INFO_H__ #include "MessageQueue.h" #include "ProcessQueueInfo.h" @@ -33,33 +33,35 @@ class ConsumerRunningInfo { } public: - static const string PROP_NAMESERVER_ADDR; - static const string PROP_THREADPOOL_CORE_SIZE; - static const string PROP_CONSUME_ORDERLY; - static const string PROP_CONSUME_TYPE; - static const string PROP_CLIENT_VERSION; - static const string PROP_CONSUMER_START_TIMESTAMP; + static const std::string PROP_NAMESERVER_ADDR; + static const std::string PROP_THREADPOOL_CORE_SIZE; + static const std::string PROP_CONSUME_ORDERLY; + static const std::string PROP_CONSUME_TYPE; + static const std::string PROP_CLIENT_VERSION; + static const std::string PROP_CONSUMER_START_TIMESTAMP; public: - const map getProperties() const; - void setProperties(const map& input_properties); - void setProperty(const string& key, const string& value); - const map getMqTable() const; - void setMqTable(MessageQueue queue, ProcessQueueInfo queueInfo); - // const map getStatusTable() const; - // void setStatusTable(const map& input_statusTable) ; - const vector getSubscriptionSet() const; - void setSubscriptionSet(const vector& input_subscriptionSet); - const string getJstack() const; - void setJstack(const string& input_jstack); - string encode(); + const std::map getProperties() const; + void setProperties(const std::map& properties); + void setProperty(const std::string& key, const std::string& value); + const std::map getMqTable() const; + void setMqTable(const MQMessageQueue& queue, ProcessQueueInfo queueInfo); + // const std::map getStatusTable() const; + // void setStatusTable(const std::map& statusTable) ; + const std::vector getSubscriptionSet() const; + void setSubscriptionSet(const std::vector& subscriptionSet); + const std::string getJstack() const; + void setJstack(const std::string& jstack); + std::string encode(); private: - map properties; - vector subscriptionSet; - map mqTable; - // map statusTable; - string jstack; + std::map properties; + std::vector subscriptionSet; + std::map mqTable; + // std::map statusTable; + std::string jstack; }; -} -#endif + +} // namespace rocketmq + +#endif // __CONSUMER_RUNNING_INFO_H__ diff --git a/src/protocol/HeartbeatData.h b/src/protocol/HeartbeatData.h index 2bd4aa71a..1453b63bd 100644 --- a/src/protocol/HeartbeatData.h +++ b/src/protocol/HeartbeatData.h @@ -14,22 +14,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef __HEARTBEAT_DATA_H__ +#define __HEARTBEAT_DATA_H__ -#ifndef __HEARTBEATDATA_H__ -#define __HEARTBEATDATA_H__ -#include -#include #include #include + #include "ConsumeType.h" +#include "RemotingSerializable.h" #include "SubscriptionData.h" namespace rocketmq { -//::const_iterator it = subscriptionDataSet.begin(); - for (; it != subscriptionDataSet.end(); it++) { - outJson["subscriptionDataSet"].append((*it).toJson()); + for (const auto& sd : subscriptionDataSet) { + outJson["subscriptionDataSet"].append(sd.toJson()); } return outJson; } public: - string groupName; + std::string groupName; ConsumeType consumeType; MessageModel messageModel; ConsumeFromWhere consumeFromWhere; - vector subscriptionDataSet; + std::vector subscriptionDataSet; }; -// lock(m_consumerDataMutex); - vector::iterator itc = m_consumerDataSet.begin(); - for (; itc != m_consumerDataSet.end(); itc++) { - root["consumerDataSet"].append((*itc).toJson()); - } + // consumer + for (const auto& cd : m_consumerDataSet) { + root["consumerDataSet"].append(cd.toJson()); } - // lock(m_producerDataMutex); - vector::iterator itp = m_producerDataSet.begin(); - for (; itp != m_producerDataSet.end(); itp++) { - root["producerDataSet"].append((*itp).toJson()); - } + // producer + for (const auto& pd : m_producerDataSet) { + root["producerDataSet"].append(pd.toJson()); } - // lock(m_producerDataMutex); - return m_producerDataSet.empty(); - } + bool isProducerDataSetEmpty() { return m_producerDataSet.empty(); } - void insertDataToProducerDataSet(ProducerData& producerData) { - boost::lock_guard lock(m_producerDataMutex); - m_producerDataSet.push_back(producerData); - } + void insertDataToProducerDataSet(ProducerData& producerData) { m_producerDataSet.push_back(producerData); } - bool isConsumerDataSetEmpty() { - boost::lock_guard lock(m_consumerDataMutex); - return m_consumerDataSet.empty(); - } + bool isConsumerDataSetEmpty() { return m_consumerDataSet.empty(); } - void insertDataToConsumerDataSet(ConsumerData& consumerData) { - boost::lock_guard lock(m_consumerDataMutex); - m_consumerDataSet.push_back(consumerData); - } + void insertDataToConsumerDataSet(ConsumerData& consumerData) { m_consumerDataSet.push_back(consumerData); } private: - string m_clientID; - vector m_producerDataSet; - vector m_consumerDataSet; - boost::mutex m_producerDataMutex; - boost::mutex m_consumerDataMutex; + std::string m_clientID; + std::vector m_producerDataSet; + std::vector m_consumerDataSet; }; -} // #include -#include "RemotingSerializable.h" -using std::map; -using std::string; +#include "RemotingSerializable.h" namespace rocketmq { -//& getTable() { return m_table; } - const map& getTable() { return m_table; } - - void setTable(const map& table) { m_table = table; } + void setTable(const std::map& table) { m_table = table; } private: - map m_table; + std::map m_table; }; + } // namespace rocketmq -#endif +#endif // __KV_TABLE_H__ diff --git a/src/protocol/LockBatchBody.cpp b/src/protocol/LockBatchBody.cpp index a63426dfc..9c3b6f0a4 100644 --- a/src/protocol/LockBatchBody.cpp +++ b/src/protocol/LockBatchBody.cpp @@ -14,120 +14,103 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "LockBatchBody.h" + #include "Logging.h" -namespace rocketmq { // LockBatchRequestBody::getMqSet() { - return mqSet; + +std::vector& LockBatchRequestBody::getMqSet() { + return m_mqSet; } -void LockBatchRequestBody::setMqSet(vector in_mqSet) { - mqSet.swap(in_mqSet); + +void LockBatchRequestBody::setMqSet(std::vector mqSet) { + m_mqSet.swap(mqSet); } -void LockBatchRequestBody::Encode(string& outData) { + +std::string LockBatchRequestBody::encode() { Json::Value root; - root["consumerGroup"] = consumerGroup; - root["clientId"] = clientId; + root["consumerGroup"] = m_consumerGroup; + root["clientId"] = m_clientId; - vector::const_iterator it = mqSet.begin(); - for (; it != mqSet.end(); it++) { - root["mqSet"].append(toJson(*it)); + for (const auto& mq : m_mqSet) { + root["mqSet"].append(rocketmq::toJson(mq)); } - Json::FastWriter fastwrite; - outData = fastwrite.write(root); + return RemotingSerializable::toJson(root); } -Json::Value LockBatchRequestBody::toJson(const MQMessageQueue& mq) const { - Json::Value outJson; - outJson["topic"] = mq.getTopic(); - outJson["brokerName"] = mq.getBrokerName(); - outJson["queueId"] = mq.getQueueId(); - return outJson; +const std::vector& LockBatchResponseBody::getLockOKMQSet() { + return m_lockOKMQSet; } -vector LockBatchResponseBody::getLockOKMQSet() { - return lockOKMQSet; +void LockBatchResponseBody::setLockOKMQSet(std::vector lockOKMQSet) { + m_lockOKMQSet.swap(lockOKMQSet); } -void LockBatchResponseBody::setLockOKMQSet(vector in_lockOKMQSet) { - lockOKMQSet.swap(in_lockOKMQSet); -} - -void LockBatchResponseBody::Decode(const MemoryBlock* mem, vector& messageQueues) { - messageQueues.clear(); - //(mem->getData()); - Json::Reader reader; - Json::Value root; - if (!reader.parse(pData, root)) { - LOG_WARN("decode LockBatchResponseBody error"); - return; - } - - Json::Value mqs = root["lockOKMQSet"]; - LOG_DEBUG("LockBatchResponseBody mqs size:%d", mqs.size()); - for (unsigned int i = 0; i < mqs.size(); i++) { - MQMessageQueue mq; - Json::Value qd = mqs[i]; - mq.setTopic(qd["topic"].asString()); - mq.setBrokerName(qd["brokerName"].asString()); - mq.setQueueId(qd["queueId"].asInt()); +LockBatchResponseBody* LockBatchResponseBody::Decode(MemoryBlock& mem) { + Json::Value root = RemotingSerializable::fromJson(mem); + auto& mqs = root["lockOKMQSet"]; + std::unique_ptr body(new LockBatchResponseBody()); + for (const auto& qd : mqs) { + MQMessageQueue mq(qd["topic"].asString(), qd["brokerName"].asString(), qd["queueId"].asInt()); LOG_INFO("LockBatchResponseBody MQ:%s", mq.toString().c_str()); - messageQueues.push_back(mq); + body->m_lockOKMQSet.push_back(std::move(mq)); } + return body.release(); } -string UnlockBatchRequestBody::getConsumerGroup() { - return consumerGroup; +std::string UnlockBatchRequestBody::getConsumerGroup() { + return m_consumerGroup; } -void UnlockBatchRequestBody::setConsumerGroup(string in_consumerGroup) { - consumerGroup = in_consumerGroup; + +void UnlockBatchRequestBody::setConsumerGroup(std::string consumerGroup) { + m_consumerGroup = consumerGroup; } -string UnlockBatchRequestBody::getClientId() { - return clientId; + +std::string UnlockBatchRequestBody::getClientId() { + return m_clientId; } -void UnlockBatchRequestBody::setClientId(string in_clientId) { - clientId = in_clientId; + +void UnlockBatchRequestBody::setClientId(std::string clientId) { + m_clientId = clientId; } -vector UnlockBatchRequestBody::getMqSet() { - return mqSet; + +std::vector& UnlockBatchRequestBody::getMqSet() { + return m_mqSet; } -void UnlockBatchRequestBody::setMqSet(vector in_mqSet) { - mqSet.swap(in_mqSet); + +void UnlockBatchRequestBody::setMqSet(std::vector mqSet) { + m_mqSet.swap(mqSet); } -void UnlockBatchRequestBody::Encode(string& outData) { + +std::string UnlockBatchRequestBody::encode() { Json::Value root; - root["consumerGroup"] = consumerGroup; - root["clientId"] = clientId; + root["consumerGroup"] = m_consumerGroup; + root["clientId"] = m_clientId; - vector::const_iterator it = mqSet.begin(); - for (; it != mqSet.end(); it++) { - root["mqSet"].append(toJson(*it)); + for (const auto& mq : m_mqSet) { + root["mqSet"].append(rocketmq::toJson(mq)); } - Json::FastWriter fastwrite; - outData = fastwrite.write(root); + return RemotingSerializable::toJson(root); } -Json::Value UnlockBatchRequestBody::toJson(const MQMessageQueue& mq) const { - Json::Value outJson; - outJson["topic"] = mq.getTopic(); - outJson["brokerName"] = mq.getBrokerName(); - outJson["queueId"] = mq.getQueueId(); - return outJson; -} -} +} // namespace rocketmq diff --git a/src/protocol/LockBatchBody.h b/src/protocol/LockBatchBody.h index 7f92e8936..22bd8e638 100644 --- a/src/protocol/LockBatchBody.h +++ b/src/protocol/LockBatchBody.h @@ -14,66 +14,68 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef __LOCK_BATCH_BODY_H__ +#define __LOCK_BATCH_BODY_H__ -#ifndef __LOCKBATCHBODY_H__ -#define __LOCKBATCHBODY_H__ #include #include + +#include "DataBlock.h" #include "MQMessageQueue.h" #include "RemotingSerializable.h" -#include "dataBlock.h" -#include "json/json.h" #include "UtilAll.h" namespace rocketmq { -// getMqSet(); - void setMqSet(vector mqSet); - void Encode(string& outData); - Json::Value toJson(const MQMessageQueue& mq) const; + std::string getConsumerGroup(); + void setConsumerGroup(std::string consumerGroup); + + std::string getClientId(); + void setClientId(std::string clientId); + + std::vector& getMqSet(); + void setMqSet(std::vector mqSet); + + std::string encode() override; private: - string consumerGroup; - string clientId; - vector mqSet; + std::string m_consumerGroup; + std::string m_clientId; + std::vector m_mqSet; }; class LockBatchResponseBody { public: - virtual ~LockBatchResponseBody() { lockOKMQSet.clear(); } - vector getLockOKMQSet(); - void setLockOKMQSet(vector lockOKMQSet); - static void Decode(const MemoryBlock* mem, vector& messageQueues); + static LockBatchResponseBody* Decode(MemoryBlock& mem); + + const std::vector& getLockOKMQSet(); + void setLockOKMQSet(std::vector lockOKMQSet); private: - vector lockOKMQSet; + std::vector m_lockOKMQSet; }; -class UnlockBatchRequestBody { +class UnlockBatchRequestBody : public RemotingSerializable { public: - virtual ~UnlockBatchRequestBody() { mqSet.clear(); } - string getConsumerGroup(); - void setConsumerGroup(string consumerGroup); - string getClientId(); - void setClientId(string clientId); - vector getMqSet(); - void setMqSet(vector mqSet); - void Encode(string& outData); - Json::Value toJson(const MQMessageQueue& mq) const; + std::string getConsumerGroup(); + void setConsumerGroup(std::string consumerGroup); + + std::string getClientId(); + void setClientId(std::string clientId); + + std::vector& getMqSet(); + void setMqSet(std::vector mqSet); + + std::string encode() override; private: - string consumerGroup; - string clientId; - vector mqSet; + std::string m_consumerGroup; + std::string m_clientId; + std::vector m_mqSet; }; -} // -#include "json/json.h" - -namespace rocketmq { -// + +#include "MQMessageQueue.h" + +namespace rocketmq { + +Json::Value toJson(const MQMessageQueue& mq); + +} // namespace rocketmq + +#endif // __MESSAGE_QUEUE_H__ diff --git a/src/protocol/ProcessQueueInfo.h b/src/protocol/ProcessQueueInfo.h index 85686f6ff..f9ee5e81c 100644 --- a/src/protocol/ProcessQueueInfo.h +++ b/src/protocol/ProcessQueueInfo.h @@ -1,94 +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 __PROCESSQUEUEINFO_H__ -#define __PROCESSQUEUEINFO_H__ + * 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 __PROCESS_QUEUE_INFO_H__ +#define __PROCESS_QUEUE_INFO_H__ + +#include #include "UtilAll.h" -#include "json/json.h" namespace rocketmq { + class ProcessQueueInfo { public: - ProcessQueueInfo() { - commitOffset = 0; - cachedMsgMinOffset = 0; - cachedMsgMaxOffset = 0; - cachedMsgCount = 0; - transactionMsgMinOffset = 0; - transactionMsgMaxOffset = 0; - transactionMsgCount = 0; - locked = false; - tryUnlockTimes = 0; - lastLockTimestamp = 123; - droped = false; - lastPullTimestamp = 0; - lastConsumeTimestamp = 0; - } - virtual ~ProcessQueueInfo() {} + ProcessQueueInfo() + : commitOffset(0), + cachedMsgMinOffset(0), + cachedMsgMaxOffset(0), + cachedMsgCount(0), + transactionMsgMinOffset(0), + transactionMsgMaxOffset(0), + transactionMsgCount(0), + locked(false), + tryUnlockTimes(0), + lastLockTimestamp(0), + droped(false), + lastPullTimestamp(0), + lastConsumeTimestamp(0) {} + + virtual ~ProcessQueueInfo() = default; public: - const uint64 getCommitOffset() const { return commitOffset; } + const uint64_t getCommitOffset() const { return commitOffset; } - void setCommitOffset(uint64 input_commitOffset) { commitOffset = input_commitOffset; } + void setCommitOffset(uint64_t commitOffset) { this->commitOffset = commitOffset; } - void setLocked(bool in_locked) { locked = in_locked; } + void setLocked(bool locked) { this->locked = locked; } const bool isLocked() const { return locked; } - void setDroped(bool in_dropped) { droped = in_dropped; } + void setDroped(bool droped) { this->droped = droped; } const bool isDroped() const { return droped; } Json::Value toJson() const { Json::Value outJson; - outJson["commitOffset"] = (UtilAll::to_string(commitOffset)).c_str(); - outJson["cachedMsgMinOffset"] = (UtilAll::to_string(cachedMsgMinOffset)).c_str(); - outJson["cachedMsgMaxOffset"] = (UtilAll::to_string(cachedMsgMaxOffset)).c_str(); - outJson["cachedMsgCount"] = (int)(cachedMsgCount); - outJson["transactionMsgMinOffset"] = (UtilAll::to_string(transactionMsgMinOffset)).c_str(); - outJson["transactionMsgMaxOffset"] = (UtilAll::to_string(transactionMsgMaxOffset)).c_str(); - outJson["transactionMsgCount"] = (int)(transactionMsgCount); - outJson["locked"] = (locked); - outJson["tryUnlockTimes"] = (int)(tryUnlockTimes); - outJson["lastLockTimestamp"] = (UtilAll::to_string(lastLockTimestamp)).c_str(); - outJson["droped"] = (droped); - outJson["lastPullTimestamp"] = (UtilAll::to_string(lastPullTimestamp)).c_str(); - outJson["lastConsumeTimestamp"] = (UtilAll::to_string(lastConsumeTimestamp)).c_str(); + outJson["commitOffset"] = UtilAll::to_string(commitOffset); + outJson["cachedMsgMinOffset"] = UtilAll::to_string(cachedMsgMinOffset); + outJson["cachedMsgMaxOffset"] = UtilAll::to_string(cachedMsgMaxOffset); + outJson["cachedMsgCount"] = cachedMsgCount; + outJson["transactionMsgMinOffset"] = UtilAll::to_string(transactionMsgMinOffset); + outJson["transactionMsgMaxOffset"] = UtilAll::to_string(transactionMsgMaxOffset); + outJson["transactionMsgCount"] = transactionMsgCount; + outJson["locked"] = locked; + outJson["tryUnlockTimes"] = tryUnlockTimes; + outJson["lastLockTimestamp"] = UtilAll::to_string(lastLockTimestamp); + outJson["droped"] = droped; + outJson["lastPullTimestamp"] = UtilAll::to_string(lastPullTimestamp); + outJson["lastConsumeTimestamp"] = UtilAll::to_string(lastConsumeTimestamp); return outJson; } public: - uint64 commitOffset; - uint64 cachedMsgMinOffset; - uint64 cachedMsgMaxOffset; - int cachedMsgCount; - uint64 transactionMsgMinOffset; - uint64 transactionMsgMaxOffset; - int transactionMsgCount; + uint64_t commitOffset; + uint64_t cachedMsgMinOffset; + uint64_t cachedMsgMaxOffset; + int32_t cachedMsgCount; + uint64_t transactionMsgMinOffset; + uint64_t transactionMsgMaxOffset; + int32_t transactionMsgCount; bool locked; - int tryUnlockTimes; - uint64 lastLockTimestamp; + int32_t tryUnlockTimes; + uint64_t lastLockTimestamp; bool droped; - uint64 lastPullTimestamp; - uint64 lastConsumeTimestamp; + uint64_t lastPullTimestamp; + uint64_t lastConsumeTimestamp; }; -} -#endif +} // namespace rocketmq + +#endif // __PROCESS_QUEUE_INFO_H__ diff --git a/src/protocol/RemotingCommand.cpp b/src/protocol/RemotingCommand.cpp index cb7bd1d47..3bc9067f0 100644 --- a/src/protocol/RemotingCommand.cpp +++ b/src/protocol/RemotingCommand.cpp @@ -15,77 +15,65 @@ * limitations under the License. */ #include "RemotingCommand.h" + +#include +#include + +#include "ByteOrder.h" #include "Logging.h" -#include "MQProtos.h" #include "MQVersion.h" -#include "SessionCredentials.h" +#include "RemotingSerializable.h" namespace rocketmq { -boost::atomic RemotingCommand::s_seqNumber; +const int RPC_TYPE = 0; // 0 - REQUEST_COMMAND; 1 - RESPONSE_COMMAND; +const int RPC_ONEWAY = 1; // 0 - RPC; 1 - Oneway; -// sSeqNumber; // mask sign bit - m_opaque = s_seqNumber.fetch_add(1, boost::memory_order_relaxed) & numeric_limits::max(); + return sSeqNumber.fetch_add(1, std::memory_order_relaxed) & std::numeric_limits::max(); } -RemotingCommand::RemotingCommand(int code, - string language, - int version, - int opaque, - int flag, - string remark, - CommandHeader* pExtHeader) +RemotingCommand::RemotingCommand(int32_t code, CommandCustomHeader* customHeader) + : RemotingCommand(code, + MQVersion::s_CurrentLanguage, + MQVersion::s_CurrentVersion, + createNewRequestId(), + 0, + "", + customHeader) {} + +RemotingCommand::RemotingCommand(int32_t code, + const std::string& language, + int32_t version, + int32_t opaque, + int32_t flag, + const std::string& remark, + CommandCustomHeader* customHeader) : m_code(code), m_language(language), m_version(version), m_opaque(opaque), m_flag(flag), m_remark(remark), - m_pExtHeader(pExtHeader) {} - -RemotingCommand::RemotingCommand(const RemotingCommand& command) { - Assign(command); -} - -RemotingCommand& RemotingCommand::operator=(const RemotingCommand& command) { - if (this != &command) { - Assign(command); - } - return *this; -} - -RemotingCommand::~RemotingCommand() { - m_pExtHeader = NULL; -} + m_customHeader(customHeader) {} -void RemotingCommand::Assign(const RemotingCommand& command) { +RemotingCommand::RemotingCommand(RemotingCommand&& command) { m_code = command.m_code; - m_language = command.m_language; + m_language = std::move(command.m_language); m_version = command.m_version; m_opaque = command.m_opaque; m_flag = command.m_flag; - m_remark = command.m_remark; - m_msgBody = command.m_msgBody; - - for (auto& it : command.m_extFields) { - m_extFields[it.first] = it.second; - } - - m_head = command.m_head; - m_body = command.m_body; - m_parsedJson = command.m_parsedJson; - // m_pExtHeader = command.m_pExtHeader; //ignore this filed at this moment, if need please add it + m_remark = std::move(command.m_remark); + m_extFields = std::move(command.m_extFields); + m_customHeader = std::move(command.m_customHeader); + m_body = std::move(command.m_body); } -void RemotingCommand::Encode() { +RemotingCommand::~RemotingCommand() = default; + +MemoryBlockPtr RemotingCommand::encode() { Json::Value root; root["code"] = m_code; root["language"] = m_language; @@ -94,220 +82,174 @@ void RemotingCommand::Encode() { root["flag"] = m_flag; root["remark"] = m_remark; - if (m_pExtHeader) { - Json::Value extJson; - m_pExtHeader->Encode(extJson); - - extJson[SessionCredentials::Signature] = m_extFields[SessionCredentials::Signature]; - extJson[SessionCredentials::AccessKey] = m_extFields[SessionCredentials::AccessKey]; - extJson[SessionCredentials::ONSChannelKey] = m_extFields[SessionCredentials::ONSChannelKey]; - - root["extFields"] = extJson; - } else { // for heartbeat - Json::Value extJson; - extJson[SessionCredentials::Signature] = m_extFields[SessionCredentials::Signature]; - extJson[SessionCredentials::AccessKey] = m_extFields[SessionCredentials::AccessKey]; - extJson[SessionCredentials::ONSChannelKey] = m_extFields[SessionCredentials::ONSChannelKey]; - root["extFields"] = extJson; + Json::Value extJson; + for (const auto& it : m_extFields) { + extJson[it.first] = it.second; + } + if (m_customHeader != nullptr) { + // write customHeader to extFields + m_customHeader->Encode(extJson); } + root["extFields"] = extJson; - Json::FastWriter fastwrite; - string data = fastwrite.write(root); + std::string header = RemotingSerializable::toJson(root); - uint32 headLen = data.size(); - uint32 totalLen = 4 + headLen + m_body.getSize(); + uint32 headerLen = header.size(); + uint32 packageLen = 4 + headerLen; + if (m_body != nullptr) { + packageLen += m_body->getSize(); + } uint32 messageHeader[2]; - messageHeader[0] = htonl(totalLen); - messageHeader[1] = htonl(headLen); + messageHeader[0] = ByteOrder::swapIfLittleEndian(packageLen); + messageHeader[1] = ByteOrder::swapIfLittleEndian(headerLen); + + auto* package = new MemoryPool(4 + packageLen); + package->copyFrom(messageHeader, 0, sizeof(messageHeader)); + package->copyFrom(header.data(), sizeof(messageHeader), headerLen); + if (m_body != nullptr && m_body->getSize() > 0) { + package->copyFrom(m_body->getData(), sizeof(messageHeader) + headerLen, m_body->getSize()); + } - //getSize(); -const MemoryBlock* RemotingCommand::GetBody() const { - return &m_body; -} + uint32 netHeaderLen; + package->copyTo(&netHeaderLen, 0, sizeof(netHeaderLen)); + int oriHeaderLen = ByteOrder::swapIfLittleEndian(netHeaderLen); + int headerLength = oriHeaderLen & 0xFFFFFF; -void RemotingCommand::SetBody(const char* pData, int len) { - m_body.reset(); - m_body.setSize(len); - m_body.copyFrom(pData, 0, len); -} + // decode header + const char* data = package->getData(); + const char* begin = data + 4; + const char* end = data + 4 + headerLength; -RemotingCommand* RemotingCommand::Decode(const MemoryBlock& mem) { - //(mem.getData()); - Json::Reader reader; Json::Value object; - const char* begin = pData + 4; - const char* end = pData + 4 + headLen; - - if (!reader.parse(begin, end, object)) { + try { + object = RemotingSerializable::fromJson(begin, end); + } catch (std::exception& e) { + LOG_WARN_NEW("parse json failed. {}", e.what()); THROW_MQEXCEPTION(MQClientException, "conn't parse json", -1); } - int code = object["code"].asInt(); - - string language = object["language"].asString(); - int version = object["version"].asInt(); - int opaque = object["opaque"].asInt(); - int flag = object["flag"].asInt(); - Json::Value v = object["remark"]; - string remark = ""; - if (!v.isNull()) { + int32_t code = object["code"].asInt(); + std::string language = object["language"].asString(); + int32_t version = object["version"].asInt(); + int32_t opaque = object["opaque"].asInt(); + int32_t flag = object["flag"].asInt(); + std::string remark; + if (!object["remark"].isNull()) { remark = object["remark"].asString(); } - LOG_DEBUG( - "code:%d, language:%s, version:%d, opaque:%d, flag:%d, remark:%s, " - "headLen:%d, bodyLen:%d ", - code, language.c_str(), version, opaque, flag, remark.c_str(), headLen, bodyLen); - RemotingCommand* cmd = new RemotingCommand(code, language, version, opaque, flag, remark, NULL); - cmd->setParsedJson(object); - if (bodyLen > 0) { - cmd->SetBody(pData + 4 + headLen, bodyLen); + + std::unique_ptr cmd(new RemotingCommand(code, language, version, opaque, flag, remark, nullptr)); + + if (!object["extFields"].isNull()) { + auto extFields = object["extFields"]; + for (auto& name : extFields.getMemberNames()) { + auto& value = extFields[name]; + if (value.isString()) { + cmd->m_extFields[name] = value.asString(); + } + } + } + + // decode body + int bodyLength = packageLength - 4 - headerLength; + if (bodyLength > 0) { + auto* body = new MemoryView(package, 4 + headerLength); + cmd->setBody(body); } - return cmd; + + LOG_DEBUG_NEW("code:{}, language:{}, version:{}, opaque:{}, flag:{}, remark:{}, headLen:{}, bodyLen:{}", code, + language, version, opaque, flag, remark, headerLength, bodyLength); + + return cmd.release(); } -void RemotingCommand::markResponseType() { - int bits = 1 << RPC_TYPE; - m_flag |= bits; +int32_t RemotingCommand::getCode() const { + return m_code; } -bool RemotingCommand::isResponseType() { - int bits = 1 << RPC_TYPE; - return (m_flag & bits) == bits; +void RemotingCommand::setCode(int32_t code) { + m_code = code; } -void RemotingCommand::markOnewayRPC() { - int bits = 1 << RPC_ONEWAY; - m_flag |= bits; +int32_t RemotingCommand::getVersion() const { + return m_version; } -bool RemotingCommand::isOnewayRPC() { - int bits = 1 << RPC_ONEWAY; - return (m_flag & bits) == bits; +int32_t RemotingCommand::getOpaque() const { + return m_opaque; } -void RemotingCommand::setOpaque(const int opa) { - m_opaque = opa; +void RemotingCommand::setOpaque(int32_t opaque) { + m_opaque = opaque; } -void RemotingCommand::SetExtHeader(int code) { - try { - Json::Value ext = m_parsedJson["extFields"]; - if (!ext.isNull()) { - m_pExtHeader = NULL; - switch (code) { - case SEND_MESSAGE: - case SEND_MESSAGE_V2: - m_pExtHeader.reset(SendMessageResponseHeader::Decode(ext)); - break; - case PULL_MESSAGE: - m_pExtHeader.reset(PullMessageResponseHeader::Decode(ext)); - break; - case GET_MIN_OFFSET: - m_pExtHeader.reset(GetMinOffsetResponseHeader::Decode(ext)); - break; - case GET_MAX_OFFSET: - m_pExtHeader.reset(GetMaxOffsetResponseHeader::Decode(ext)); - break; - case SEARCH_OFFSET_BY_TIMESTAMP: - m_pExtHeader.reset(SearchOffsetResponseHeader::Decode(ext)); - break; - case GET_EARLIEST_MSG_STORETIME: - m_pExtHeader.reset(GetEarliestMsgStoretimeResponseHeader::Decode(ext)); - break; - case QUERY_CONSUMER_OFFSET: - m_pExtHeader.reset(QueryConsumerOffsetResponseHeader::Decode(ext)); - break; - case RESET_CONSUMER_CLIENT_OFFSET: - m_pExtHeader.reset(ResetOffsetRequestHeader::Decode(ext)); - break; - case GET_CONSUMER_RUNNING_INFO: - m_pExtHeader.reset(GetConsumerRunningInfoRequestHeader::Decode(ext)); - break; - case NOTIFY_CONSUMER_IDS_CHANGED: - m_pExtHeader.reset(NotifyConsumerIdsChangedRequestHeader::Decode(ext)); - break; - case CHECK_TRANSACTION_STATE: - m_pExtHeader.reset(CheckTransactionStateRequestHeader::Decode(ext)); - break; - default: - break; - } - } - } catch (MQException& e) { - LOG_ERROR("set response head error"); - } +int32_t RemotingCommand::getFlag() const { + return m_flag; } -void RemotingCommand::setCode(int code) { - m_code = code; +const std::string& RemotingCommand::getRemark() const { + return m_remark; } -int RemotingCommand::getCode() const { - return m_code; +void RemotingCommand::setRemark(const std::string& mark) { + m_remark = mark; } -int RemotingCommand::getOpaque() const { - return m_opaque; +bool RemotingCommand::isResponseType() { + int bits = 1 << RPC_TYPE; + return (m_flag & bits) == bits; } -string RemotingCommand::getRemark() const { - return m_remark; +void RemotingCommand::markResponseType() { + int bits = 1 << RPC_TYPE; + m_flag |= bits; } -void RemotingCommand::setRemark(string mark) { - m_remark = mark; +bool RemotingCommand::isOnewayRPC() { + int bits = 1 << RPC_ONEWAY; + return (m_flag & bits) == bits; } -CommandHeader* RemotingCommand::getCommandHeader() const { - return m_pExtHeader.get(); +void RemotingCommand::markOnewayRPC() { + int bits = 1 << RPC_ONEWAY; + m_flag |= bits; } -void RemotingCommand::setParsedJson(Json::Value json) { - m_parsedJson = json; +void RemotingCommand::addExtField(const std::string& key, const std::string& value) { + m_extFields[key] = value; } -const int RemotingCommand::getFlag() const { - return m_flag; +CommandCustomHeader* RemotingCommand::readCustomHeader() const { + return m_customHeader.get(); } -const int RemotingCommand::getVersion() const { - return m_version; +MemoryBlockPtr2 RemotingCommand::getBody() { + return m_body; } -void RemotingCommand::setMsgBody(const string& body) { - m_msgBody = body; +void RemotingCommand::setBody(MemoryBlock* body) { + m_body.reset(body); } -string RemotingCommand::getMsgBody() const { - return m_msgBody; +void RemotingCommand::setBody(MemoryBlockPtr2 body) { + m_body = body; } -void RemotingCommand::addExtField(const string& key, const string& value) { - m_extFields[key] = value; +void RemotingCommand::setBody(const std::string& body) { + m_body.reset(new MemoryPool(body.data(), body.size())); } -std::string RemotingCommand::ToString() const { +std::string RemotingCommand::toString() const { std::stringstream ss; - ss << "code:" << m_code << ",opaque:" << m_opaque << ",flag:" << m_flag << ",body.size:" << m_body.getSize() - << ",header.size:" << m_head.getSize(); + ss << "code:" << m_code << ", opaque:" << m_opaque << ", flag:" << m_flag << ", body.size:" << m_body->getSize(); return ss.str(); } diff --git a/src/protocol/RemotingCommand.h b/src/protocol/RemotingCommand.h deleted file mode 100644 index bc137f7ed..000000000 --- a/src/protocol/RemotingCommand.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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 __REMOTINGCOMMAND_H__ -#define __REMOTINGCOMMAND_H__ -#include -#include -#include -#include -#include -#include "CommandHeader.h" -#include "dataBlock.h" - -namespace rocketmq { -// m_extFields; - - MemoryBlock m_head; - MemoryBlock m_body; - // m_pExtHeader; - - static boost::atomic s_seqNumber; -}; - -} // +#include + +#include "MQClientException.h" + +namespace rocketmq { + +Json::StreamWriterBuilder& RemotingSerializable::getPrettyWriterBuilder() { + static Json::StreamWriterBuilder sPrettyWriterBuilder; + return sPrettyWriterBuilder; +} + +Json::StreamWriterBuilder& RemotingSerializable::getPlainWriterBuilder() { + static PlainStreamWriterBuilder sPlainWriterBuilder; + return sPlainWriterBuilder; +} + +Json::CharReaderBuilder& RemotingSerializable::getPowerReaderBuilder() { + static PowerCharReaderBuilder sPowerReaderBuilder; + return sPowerReaderBuilder; +} + +std::string RemotingSerializable::toJson(Json::Value root) { + return toJson(root, false); +} + +std::string RemotingSerializable::toJson(Json::Value root, bool prettyFormat) { + std::ostringstream sout; + toJson(root, sout, prettyFormat); + return sout.str(); +} + +void RemotingSerializable::toJson(Json::Value root, std::ostream& sout, bool prettyFormat) { + std::unique_ptr writer; + if (prettyFormat) { + writer.reset(getPrettyWriterBuilder().newStreamWriter()); + } else { + writer.reset(getPlainWriterBuilder().newStreamWriter()); + } + writer->write(root, &sout); +} + +Json::Value RemotingSerializable::fromJson(std::istream& sin) { + std::ostringstream ssin; + ssin << sin.rdbuf(); + std::string json = ssin.str(); + return fromJson(json); +} + +Json::Value RemotingSerializable::fromJson(const std::string& json) { + const char* begin = json.data(); + const char* end = begin + json.size(); + return fromJson(begin, end); +} + +Json::Value RemotingSerializable::fromJson(const MemoryBlock& data) { + const char* begin = data.getData(); + const char* end = begin + data.getSize(); + return fromJson(begin, end); +} + +Json::Value RemotingSerializable::fromJson(const char* begin, const char* end) { + Json::Value root; + std::string errs; + std::unique_ptr reader(getPowerReaderBuilder().newCharReader()); + if (reader->parse(begin, end, &root, &errs)) { + return root; + } else { + THROW_MQEXCEPTION(RemotingCommandException, errs, -1); + } +} + +} // namespace rocketmq diff --git a/src/protocol/RemotingSerializable.h b/src/protocol/RemotingSerializable.h index 812a892bd..08ed73b08 100644 --- a/src/protocol/RemotingSerializable.h +++ b/src/protocol/RemotingSerializable.h @@ -14,19 +14,46 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __REMOTINGSERIALIZABLE_H__ -#define __REMOTINGSERIALIZABLE_H__ -#include "json/json.h" +#ifndef __REMOTING_SERIALIZABLE_H__ +#define __REMOTING_SERIALIZABLE_H__ + +#include + +#include "DataBlock.h" namespace rocketmq { -// #include -#include "dataBlock.h" + +#include "DataBlock.h" namespace rocketmq { -// m_topicList; + std::vector m_topicList; }; -// #include +#include + +#include + +#include "DataBlock.h" #include "Logging.h" +#include "RemotingSerializable.h" #include "UtilAll.h" -#include "dataBlock.h" -#include "json/json.h" namespace rocketmq { -// brokerAddrs; // brokerAddrs; // master:0; slave:1,2,3,etc. bool operator<(const BrokerData& other) const { return brokerName < other.brokerName; } @@ -52,37 +55,18 @@ struct BrokerData { } }; -// TopicRouteDataPtr; + class TopicRouteData { public: - virtual ~TopicRouteData() { - m_brokerDatas.clear(); - m_queueDatas.clear(); - } - - static TopicRouteData* Decode(const MemoryBlock* mem) { - //(mem->getData()); - string data(pData, mem->getSize()); - - Json::CharReaderBuilder charReaderBuilder; - charReaderBuilder.settings_["allowNumericKeys"] = true; - unique_ptr pCharReaderPtr(charReaderBuilder.newCharReader()); - - const char* begin = pData; - const char* end = pData + mem->getSize(); - Json::Value root; - string errs; - - if (!pCharReaderPtr->parse(begin, end, &root, &errs)) { - LOG_ERROR("parse json error:%s, value isArray:%d, isObject:%d", errs.c_str(), root.isArray(), root.isObject()); - return nullptr; - } + static TopicRouteData* Decode(MemoryBlock& mem) { + Json::Value root = RemotingSerializable::fromJson(mem); - auto* trd = new TopicRouteData(); + std::unique_ptr trd(new TopicRouteData()); trd->setOrderTopicConf(root["orderTopicConf"].asString()); - Json::Value qds = root["queueDatas"]; + auto& qds = root["queueDatas"]; for (auto qd : qds) { QueueData d; d.brokerName = qd["brokerName"].asString(); @@ -93,7 +77,7 @@ class TopicRouteData { } sort(trd->getQueueDatas().begin(), trd->getQueueDatas().end()); - Json::Value bds = root["brokerDatas"]; + auto& bds = root["brokerDatas"]; for (auto bd : bds) { BrokerData d; d.brokerName = bd["brokerName"].asString(); @@ -101,8 +85,8 @@ class TopicRouteData { Json::Value bas = bd["brokerAddrs"]; Json::Value::Members mbs = bas.getMemberNames(); for (const auto& key : mbs) { - int id = atoi(key.c_str()); - string addr = bas[key].asString(); + int id = std::stoi(key); + std::string addr = bas[key].asString(); d.brokerAddrs[id] = addr; LOG_DEBUG("brokerId:%d, brokerAddr:%s", id, addr.c_str()); } @@ -110,7 +94,7 @@ class TopicRouteData { } sort(trd->getBrokerDatas().begin(), trd->getBrokerDatas().end()); - return trd; + return trd.release(); } /** @@ -144,7 +128,7 @@ class TopicRouteData { const std::string& getOrderTopicConf() const { return m_orderTopicConf; } - void setOrderTopicConf(const string& orderTopicConf) { m_orderTopicConf = orderTopicConf; } + void setOrderTopicConf(const std::string& orderTopicConf) { m_orderTopicConf = orderTopicConf; } bool operator==(const TopicRouteData& other) const { return m_brokerDatas == other.m_brokerDatas && m_orderTopicConf == other.m_orderTopicConf && @@ -159,4 +143,4 @@ class TopicRouteData { } // namespace rocketmq -#endif +#endif // __TOPIC_ROUTE_DATA_H__ diff --git a/src/thread/disruptor/batch_descriptor.h b/src/thread/disruptor/batch_descriptor.h deleted file mode 100755 index ba1a035f2..000000000 --- a/src/thread/disruptor/batch_descriptor.h +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2011, François Saint-Jacques -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the disruptor-- nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL FRANÇOIS SAINT-JACQUES BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DISRUPTOR_BATCH_DESCRIPTOR_H_ // NOLINT -#define DISRUPTOR_BATCH_DESCRIPTOR_H_ // NOLINT - -#include "sequence.h" - -namespace rocketmq { - -// Used to record the batch of sequences claimed via {@link Sequencer}. -class BatchDescriptor { - public: - // Create a holder for tracking a batch of claimed sequences in a - // {@link Sequencer} - // - // @param size of the batch to claim. - BatchDescriptor(int size) : - size_(size), - end_(kInitialCursorValue) {} - - // Get the size of the batch - int size() const { return size_; } - - // Get the end sequence of a batch. - // - // @return the end sequence in the batch. - int64_t end() const { return end_; } - - // Set the end sequence of a batch. - // - // @param end sequence in the batch. - void set_end(int64_t end) { end_ = end; } - - - // Get the starting sequence of the batch. - // - // @return starting sequence in the batch. - int64_t Start() const { return end_ - size_ + 1L; } - - private: - int size_; - int64_t end_; -}; - -}; // namespace rocketmq - -#endif // DISRUPTOR_SEQUENCE_BATCH_H_ NOLINT diff --git a/src/thread/disruptor/claim_strategy.h b/src/thread/disruptor/claim_strategy.h deleted file mode 100755 index 0f3263a39..000000000 --- a/src/thread/disruptor/claim_strategy.h +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright (c) 2011, François Saint-Jacques -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the disruptor-- nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL FRANÇOIS SAINT-JACQUES BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DISRUPTOR_CLAIM_STRATEGY_H_ // NOLINT -#define DISRUPTOR_CLAIM_STRATEGY_H_ // NOLINT - -#include -#include -#include - -#include "interface.h" - -namespace rocketmq { - -enum ClaimStrategyOption { - kSingleThreadedStrategy, - kMultiThreadedStrategy -}; - -// Optimised strategy can be used when there is a single publisher thread -// claiming {@link AbstractEvent}s. -class SingleThreadedStrategy :public noncopyable, public ClaimStrategyInterface { - public: - SingleThreadedStrategy(const int& buffer_size) : - buffer_size_(buffer_size), - sequence_(kInitialCursorValue), - min_gating_sequence_(kInitialCursorValue) {} - - virtual int64_t IncrementAndGet( - const std::vector& dependent_sequences) { - int64_t next_sequence = sequence_.IncrementAndGet(1L); - WaitForFreeSlotAt(next_sequence, dependent_sequences); - return next_sequence; - } - - virtual int64_t IncrementAndGet(const int& delta, - const std::vector& dependent_sequences) { - int64_t next_sequence = sequence_.IncrementAndGet(delta); - WaitForFreeSlotAt(next_sequence, dependent_sequences); - return next_sequence; - } - - virtual bool HasAvalaibleCapacity( - const std::vector& dependent_sequences) { - int64_t wrap_point = sequence_.sequence() + 1L - buffer_size_; - if (wrap_point > min_gating_sequence_.sequence()) { - int64_t min_sequence = GetMinimumSequence(dependent_sequences); - min_gating_sequence_.set_sequence(min_sequence); - if (wrap_point > min_sequence) - return false; - } - return true; - } - - virtual void SetSequence(const int64_t& sequence, - const std::vector& dependent_sequences) { - sequence_.set_sequence(sequence); - WaitForFreeSlotAt(sequence, dependent_sequences); - } - - virtual void SerialisePublishing(const int64_t& sequence, - const Sequence& cursor, - const int64_t& batch_size) {} - - private: - SingleThreadedStrategy(); - - void WaitForFreeSlotAt(const int64_t& sequence, - const std::vector& dependent_sequences) { - int64_t wrap_point = sequence - buffer_size_; - if (wrap_point > min_gating_sequence_.sequence()) { - int64_t min_sequence; - while (wrap_point > (min_sequence = GetMinimumSequence(dependent_sequences))) { - boost::this_thread::yield(); - } - } - } - - const int buffer_size_; - PaddedLong sequence_; - PaddedLong min_gating_sequence_; - -}; - -// Strategy to be used when there are multiple publisher threads claiming -// {@link AbstractEvent}s. -/* -class MultiThreadedStrategy : public ClaimStrategyInterface { - public: - MultiThreadedStrategy(const int& buffer_size) : - buffer_size_(buffer_size), - sequence_(kInitialCursorValue), - min_processor_sequence_(kInitialCursorValue) {} - - virtual int64_t IncrementAndGet( - const std::vector& dependent_sequences) { - WaitForCapacity(dependent_sequences, min_gating_sequence_local_); - int64_t next_sequence = sequence_.IncrementAndGet(); - WaitForFreeSlotAt(next_sequence, - dependent_sequences, - min_gating_sequence_local_); - return next_sequence; - } - - virtual int64_t IncrementAndGet(const int& delta, - const std::vector& dependent_sequences) { - int64_t next_sequence = sequence_.IncrementAndGet(delta); - WaitForFreeSlotAt(next_sequence, - dependent_sequences, - min_gating_sequence_local_); - return next_sequence; - } - virtual void SetSequence(const int64_t& sequence, - const std::vector& dependent_sequences) { - sequence_.set_sequence(sequence); - WaitForFreeSlotAt(sequence, - dependent_sequences, - min_gating_sequence_local_); - } - - virtual bool HasAvalaibleCapacity( - const std::vector& dependent_sequences) { - const int64_t wrap_point = sequence_.sequence() + 1L - buffer_size_; - if (wrap_point > min_gating_sequence_local_.sequence()) { - int64_t min_sequence = GetMinimumSequence(dependent_sequences); - min_gating_sequence_local_.set_sequence(min_sequence); - if (wrap_point > min_sequence) - return false; - } - return true; - } - - virtual void SerialisePublishing(const Sequence& cursor, - const int64_t& sequence, - const int64_t& batch_size) { - int64_t expected_sequence = sequence - batch_size; - int counter = retries; - - while (expected_sequence != cursor.sequence()) { - if (0 == --counter) { - counter = retries; - std::this_thread::yield(); - } - } - } - - private: - // Methods - void WaitForCapacity(const std::vector& dependent_sequences, - const MutableLong& min_gating_sequence) { - const int64_t wrap_point = sequence_.sequence() + 1L - buffer_size_; - if (wrap_point > min_gating_sequence.sequence()) { - int counter = retries; - int64_t min_sequence; - while (wrap_point > (min_sequence = GetMinimumSequence(dependent_sequences))) { - counter = ApplyBackPressure(counter); - } - min_gating_sequence.set_sequence(min_sequence); - } - } - - void WaitForFreeSlotAt(const int64_t& sequence, - const std::vector& dependent_sequences, - const MutableLong& min_gating_sequence) { - const int64_t wrap_point = sequence - buffer_size_; - if (wrap_point > min_gating_sequence.sequence()) { - int64_t min_sequence; - while (wrap_point > (min_sequence = GetMinimumSequence(dependent_sequences))) { - std::this_thread::yield(); - } - min_gating_sequence.set_sequence(min_sequence); - } - } - - int ApplyBackPressure(int counter) { - if (0 != counter) { - --counter; - std::this_thread::yield(); - } else { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } - - return counter; - } - - const int buffer_size_; - PaddedSequence sequence_; - thread_local PaddedLong min_gating_sequence_local_; - - const int retries = 100; - -}; -*/ - -ClaimStrategyInterface* CreateClaimStrategy(ClaimStrategyOption option, - const int& buffer_size) { - switch (option) { - case kSingleThreadedStrategy: - return new SingleThreadedStrategy(buffer_size); - // case kMultiThreadedStrategy: - // return new MultiThreadedStrategy(buffer_size); - default: - return NULL; - } -}; - -}; // namespace rocketmq - -#endif // DISRUPTOR_CLAIM_STRATEGY_H_ NOLINT diff --git a/src/thread/disruptor/event_processor.h b/src/thread/disruptor/event_processor.h deleted file mode 100755 index 3ad080ddd..000000000 --- a/src/thread/disruptor/event_processor.h +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2011, François Saint-Jacques -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the disruptor-- nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL FRANÇOIS SAINT-JACQUES BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DISRUPTOR_EVENT_PROCESSOR_H_ // NOLINT -#define DISRUPTOR_EVENT_PROCESSOR_H_ // NOLINT - -#include -#include "ring_buffer.h" - -namespace rocketmq { - -template -class NoOpEventProcessor : public EventProcessorInterface { - public: - NoOpEventProcessor(RingBuffer* ring_buffer) : - ring_buffer_(ring_buffer) { } - - virtual Sequence* GetSequence() { - return ring_buffer_->GetSequencePtr(); - } - - virtual void Halt() {} - - virtual void Run() {} - - private: - RingBuffer* ring_buffer_; -}; - -template -class BatchEventProcessor : public boost::noncopyable, public EventProcessorInterface { - public: - BatchEventProcessor(RingBuffer* ring_buffer, - SequenceBarrierInterface* sequence_barrier, - EventHandlerInterface* event_handler, - ExceptionHandlerInterface* exception_handler) : - running_(false), - ring_buffer_(ring_buffer), - sequence_barrier_(sequence_barrier), - event_handler_(event_handler), - exception_handler_(exception_handler) {} - - - virtual Sequence* GetSequence() { return &sequence_; } - - virtual void Halt() { - running_.store(false); - sequence_barrier_->Alert(); - } - - virtual void Run() { - if (running_.load()) - { - printf("Thread is already running\r\n"); - } - running_.store(true); - sequence_barrier_->ClearAlert(); - event_handler_->OnStart(); - - T* event = NULL; - int64_t next_sequence = sequence_.sequence() + 1L; - - while (true) { - try { - int64_t avalaible_sequence = \ - sequence_barrier_->WaitFor(next_sequence, 300*1000);//wait 300 milliseconds to avoid taskThread blocking on BlockingStrategy::WaitFor when shutdown - //rocketmq::LOG_INFO("avalaible_sequence:%d, next_sequence:%d", avalaible_sequence,next_sequence); - while (next_sequence <= avalaible_sequence) { - event = ring_buffer_->Get(next_sequence); - event_handler_->OnEvent(next_sequence, - next_sequence == avalaible_sequence, event); - next_sequence++; - } - - sequence_.set_sequence(next_sequence - 1L); - } catch(const AlertException& e) { - //rocketmq::LOG_INFO("catch alertException"); - if (!running_.load()) - break; - } catch(const std::exception& e) { - //rocketmq::LOG_ERROR("catch stdException"); - exception_handler_->Handle(e, next_sequence, event); - sequence_.set_sequence(next_sequence); - next_sequence++; - } - } - //rocketmq::LOG_INFO("BatchEventProcessor shutdown"); - event_handler_->OnShutdown(); - running_.store(false); - } - - void operator()() { Run(); } - - private: - boost::atomic running_; - Sequence sequence_; - - RingBuffer* ring_buffer_; - SequenceBarrierInterface* sequence_barrier_; - EventHandlerInterface* event_handler_; - ExceptionHandlerInterface* exception_handler_; - -}; - - -}; // namespace rocketmq - -#endif // DISRUPTOR_EVENT_PROCESSOR_H_ NOLINT diff --git a/src/thread/disruptor/event_publisher.h b/src/thread/disruptor/event_publisher.h deleted file mode 100755 index ae0efd9ec..000000000 --- a/src/thread/disruptor/event_publisher.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2011, François Saint-Jacques -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the disruptor-- nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL FRANÇOIS SAINT-JACQUES BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DISRUPTOR_EVENT_PUBLISHER_H_ // NOLINT -#define DISRUPTOR_EVENT_PUBLISHER_H_ // NOLINT - -#include "ring_buffer.h" - -namespace rocketmq { - -template -class EventPublisher { - public: - EventPublisher(RingBuffer* ring_buffer) : ring_buffer_(ring_buffer) {} - - void PublishEvent(EventTranslatorInterface* translator) { - int64_t sequence = ring_buffer_->Next(); - translator->TranslateTo(sequence, ring_buffer_->Get(sequence)); - ring_buffer_->Publish(sequence); - } - - private: - RingBuffer* ring_buffer_; -}; - -}; // namespace rocketmq - -#endif diff --git a/src/thread/disruptor/exception_handler.h b/src/thread/disruptor/exception_handler.h deleted file mode 100755 index e7979a04f..000000000 --- a/src/thread/disruptor/exception_handler.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2011, François Saint-Jacques -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the disruptor-- nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL FRANÇOIS SAINT-JACQUES BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DISRUPTOR_EXCEPTION_HANDLER_H_ // NOLINT -#define DISRUPTOR_EXCEPTION_HANDLER_H_ // NOLINT - -#include - -#include "interface.h" - -namespace rocketmq { - -template -class IgnoreExceptionHandler: public ExceptionHandlerInterface { - public: - virtual void Handle(const std::exception& exception, - const int64_t& sequence, - T* event) { - // do nothing with the exception. - ; - } -}; - -template -class FatalExceptionHandler: public ExceptionHandlerInterface { - public: - virtual void Handle(const std::exception& exception, - const int64_t& sequence, - T* event) { - // rethrow the exception - throw exception; - } -}; - -}; // namespace rocketmq - -#endif // DISRUPTOR_EXCEPTION_HANDLER_H_ NOLINT diff --git a/src/thread/disruptor/exceptions.h b/src/thread/disruptor/exceptions.h deleted file mode 100755 index f968043a2..000000000 --- a/src/thread/disruptor/exceptions.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2011, François Saint-Jacques -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the disruptor-- nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL FRANÇOIS SAINT-JACQUES BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DISRUPTOR_EXCEPTIONS_H_ // NOLINT -#define DISRUPTOR_EXCEPTIONS_H_ // NOLINT - -#include - -namespace rocketmq { - -class AlertException : public std::exception { -}; - -}; // namespace rocketmq - -#endif // DISRUPTOR_EXCEPTIONS_H_ NOLINT diff --git a/src/thread/disruptor/interface.h b/src/thread/disruptor/interface.h deleted file mode 100755 index 0c07774c3..000000000 --- a/src/thread/disruptor/interface.h +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright (c) 2011, François Saint-Jacques -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the disruptor-- nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL FRANÇOIS SAINT-JACQUES BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DISRUPTOR_INTERFACE_H_ // NOLINT -#define DISRUPTOR_INTERFACE_H_ // NOLINT - -#include -#include - -#include "sequence.h" -#include "batch_descriptor.h" - -namespace rocketmq { - -// Strategies employed for claiming the sequence of events in the -// {@link Seqencer} by publishers. -class ClaimStrategyInterface { - public: - // Is there available capacity in the buffer for the requested sequence. - // - // @param dependent_sequences to be checked for range. - // @return true if the buffer has capacity for the requested sequence. - virtual ~ClaimStrategyInterface() {} - virtual bool HasAvalaibleCapacity( - const std::vector& dependent_sequences) = 0; - - // Claim the next sequence in the {@link Sequencer}. - // - // @param dependent_sequences to be checked for range. - // @return the index to be used for the publishing. - virtual int64_t IncrementAndGet( - const std::vector& dependent_sequences) = 0; - - // Claim the next sequence in the {@link Sequencer}. - // - // @param delta to increment by. - // @param dependent_sequences to be checked for range. - // @return the index to be used for the publishing. - virtual int64_t IncrementAndGet(const int& delta, - const std::vector& dependent_sequences) = 0; - - // Set the current sequence value for claiming an event in the - // {@link Sequencer}. - // - // @param sequence to be set as the current value. - // @param dependent_sequences to be checked for range. - virtual void SetSequence(const int64_t& sequence, - const std::vector& dependent_sequences) = 0; - - // Serialise publishing in sequence. - // - // @param sequence to be applied. - // @param cursor to be serialise against. - // @param batch_size of the sequence. - virtual void SerialisePublishing(const int64_t& sequence, - const Sequence& cursor, - const int64_t& batch_size) = 0; -}; - -// Coordination barrier for tracking the cursor for publishers and sequence of -// dependent {@link EventProcessor}s for processing a data structure. -class SequenceBarrierInterface { - public: - // Wait for the given sequence to be available for consumption. - // - // @param sequence to wait for. - // @return the sequence up to which is available. - // - // @throws AlertException if a status change has occurred for the - // Disruptor. - virtual ~SequenceBarrierInterface(){} - virtual int64_t WaitFor(const int64_t& sequence) = 0; - - // Wait for the given sequence to be available for consumption with a - // time out. - // - // @param sequence to wait for. - // @param timeout in microseconds. - // @return the sequence up to which is available. - // - // @throws AlertException if a status change has occurred for the - // Disruptor. - virtual int64_t WaitFor(const int64_t& sequence, - const int64_t& timeout_micro) = 0; - - // Delegate a call to the {@link Sequencer#getCursor()} - // - // @return value of the cursor for entries that have been published. - virtual int64_t GetCursor() const = 0; - - // The current alert status for the barrier. - // - // @return true if in alert otherwise false. - virtual bool IsAlerted() const = 0; - - // Alert the {@link EventProcessor}s of a status change and stay in this - // status until cleared. - virtual void Alert() = 0; - - // Clear the current alert status. - virtual void ClearAlert() = 0; - - // Check if barrier is alerted, if so throws an AlertException - // - // @throws AlertException if barrier is alerted - virtual void CheckAlert() const = 0; -}; - -// Called by the {@link RingBuffer} to pre-populate all the events to fill the -// RingBuffer. -// -// @param event implementation storing the data for sharing during exchange -// or parallel coordination of an event. -template -class EventFactoryInterface { - public: - virtual ~EventFactoryInterface(){} - virtual T* NewInstance(const int& size) const = 0; -}; - -// Callback interface to be implemented for processing events as they become -// available in the {@link RingBuffer}. -// -// @param event implementation storing the data for sharing during exchange -// or parallel coordination of an event. -template -class EventHandlerInterface { - public: - // Called when a publisher has published an event to the {@link RingBuffer} - // - // @param event published to the {@link RingBuffer} - // @param sequence of the event being processed - // @param end_of_batch flag to indicate if this is the last event in a batch - // from the {@link RingBuffer} - // - // @throws Exception if the EventHandler would like the exception handled - // further up the chain. - virtual ~EventHandlerInterface(){} - virtual void OnEvent(const int64_t& sequence, - const bool& end_of_batch, - T* event) = 0; - - // Called once on thread start before processing the first event. - virtual void OnStart() = 0; - - // Called once on thread stop just before shutdown. - virtual void OnShutdown() = 0; -}; - -// Implementations translate another data representations into events claimed -// for the {@link RingBuffer}. -// -// @param event implementation storing the data for sharing during exchange -// or parallel coordination of an event. -template -class EventTranslatorInterface { - public: - // Translate a data representation into fields set in given event - // - // @param event into which the data should be translated. - // @param sequence that is assigned to events. - // @return the resulting event after it has been translated. - virtual ~EventTranslatorInterface(){} - virtual T* TranslateTo(const int64_t& sequence, T* event) { return NULL;} -}; - -// EventProcessors wait for events to become available for consumption from -// the {@link RingBuffer}. An event processor should be associated with a -// thread. -// -// @param event implementation storing the data for sharing during exchange -// or parallel coordination of an event. -template -class EventProcessorInterface { - public: - // Get a pointer to the {@link Sequence} being used by this - // {@link EventProcessor}. - // - // @return pointer to the {@link Sequence} for this - // {@link EventProcessor} - virtual ~EventProcessorInterface(){} - virtual Sequence* GetSequence() = 0; - - // Signal that this EventProcessor should stop when it has finished - // consuming at the next clean break. - // It will call {@link DependencyBarrier#alert()} to notify the thread to - // check status. - virtual void Halt() = 0; -}; - -// Callback handler for uncaught exception in the event processing cycle -// of the {@link BatchEventProcessor}. -// -// @param event type stored in the {@link RingBuffer}. -template -class ExceptionHandlerInterface { - public: - // Strategy for handling uncaught exceptions when processing an event. - // If the strategy wishes to suspend further processing by the - // {@link BatchEventProcessor} then it should throw a std::runtime_error. - // - // @param exception that propagated from the {@link EventHandler}. - // @param sequence of the event which caused the exception. - // @param event being processed when the exception occured. - virtual ~ExceptionHandlerInterface(){} - virtual void Handle(const std::exception& exception, - const int64_t& sequence, - T* event) = 0; -}; - -// Strategy employed for making {@link EventProcessor}s wait on a cursor -// {@link Sequence}. -class WaitStrategyInterface: public boost::noncopyable { - public: - // Wait for the given sequence to be available for consumption. - // - // @param dependents further back the chain that must advance first. - // @param cursor on which to wait. - // @param barrier the consumer is waiting on. - // @param sequence to be waited on. - // @return the sequence that is available which may be greater than the - // requested sequence. - // - // @throws AlertException if the status of the Disruptor has changed. - virtual ~WaitStrategyInterface(){} - virtual int64_t WaitFor(const std::vector& dependents, - const Sequence& cursor, - const SequenceBarrierInterface& barrier, - const int64_t& sequence) = 0; - - // Wait for the given sequence to be available for consumption in a - // {@link RingBuffer} with a timeout specified. - // - // @param dependents further back the chain that must advance first - // @param cursor on which to wait. - // @param barrier the consumer is waiting on. - // @param sequence to be waited on. - // @param timeout value in micro seconds to abort after. - // @return the sequence that is available which may be greater than the - // requested sequence. - // - // @throws AlertException if the status of the Disruptor has changed. - // @throws InterruptedException if the thread is interrupted. - virtual int64_t WaitFor(const std::vector& dependents, - const Sequence& cursor, - const SequenceBarrierInterface& barrier, - const int64_t & sequence, - const int64_t & timeout_micros) = 0; - - // Signal those waiting that the cursor has advanced. - virtual void SignalAllWhenBlocking() = 0; -}; - -}; // namespace rocketmq - -#endif // DISRUPTOR_INTERFACE_H_ NOLINT diff --git a/src/thread/disruptor/ring_buffer.h b/src/thread/disruptor/ring_buffer.h deleted file mode 100755 index c7150f152..000000000 --- a/src/thread/disruptor/ring_buffer.h +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) 2011, François Saint-Jacques -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the disruptor-- nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL FRANÇOIS SAINT-JACQUES BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DISRUPTOR_RING_BUFFER_H_ // NOLINT -#define DISRUPTOR_RING_BUFFER_H_ // NOLINT - -#include -#include - -#include "interface.h" -#include "claim_strategy.h" -#include "wait_strategy.h" -#include "sequencer.h" -#include "sequence_barrier.h" - -namespace rocketmq { - -// Ring based store of reusable entries containing the data representing an -// event beign exchanged between publisher and {@link EventProcessor}s. -// -// @param implementation storing the data for sharing during exchange -// or parallel coordination of an event. -template -class RingBuffer : public Sequencer { - public: - // Construct a RingBuffer with the full option set. - // - // @param event_factory to instance new entries for filling the RingBuffer. - // @param buffer_size of the RingBuffer, must be a power of 2. - // @param claim_strategy_option threading strategy for publishers claiming - // entries in the ring. - // @param wait_strategy_option waiting strategy employed by - // processors_to_track waiting in entries becoming available. - RingBuffer(EventFactoryInterface* event_factory, - int buffer_size, - ClaimStrategyOption claim_strategy_option, - WaitStrategyOption wait_strategy_option) : - Sequencer(buffer_size, - claim_strategy_option, - wait_strategy_option), - buffer_size_(buffer_size), - mask_(buffer_size - 1), - events_(event_factory->NewInstance(buffer_size)) { - } - - ~RingBuffer() { - delete[] events_; - } - - // Get the event for a given sequence in the RingBuffer. - // - // @param sequence for the event - // @return event pointer at the specified sequence position. - T* Get(const int64_t& sequence) { - return &events_[sequence & mask_]; - } - - private: - // Members - int buffer_size_; - int mask_; - T* events_; - -}; - -}; // namespace rocketmq - -#endif // DISRUPTOR_RING_BUFFER_H_ NOLINT diff --git a/src/thread/disruptor/sequence.h b/src/thread/disruptor/sequence.h deleted file mode 100755 index 4a5c75cec..000000000 --- a/src/thread/disruptor/sequence.h +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) 2011, François Saint-Jacques -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the disruptor-- nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL FRANÇOIS SAINT-JACQUES BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef CACHE_LINE_SIZE_IN_BYTES // NOLINT -#define CACHE_LINE_SIZE_IN_BYTES 64 // NOLINT -#endif // NOLINT -#define ATOMIC_SEQUENCE_PADDING_LENGTH \ - (CACHE_LINE_SIZE_IN_BYTES - sizeof(boost::atomic))/8 -#define SEQUENCE_PADDING_LENGTH \ - (CACHE_LINE_SIZE_IN_BYTES - sizeof(int64_t))/8 - -#ifndef DISRUPTOR_SEQUENCE_H_ // NOLINT -#define DISRUPTOR_SEQUENCE_H_ // NOLINT - -#include -#include -#include -#include -#include -using namespace boost; -namespace rocketmq { - -const int64_t kInitialCursorValue = -1L; - -// Sequence counter. -class Sequence:public noncopyable { - public: - // Construct a sequence counter that can be tracked across threads. - // - // @param initial_value for the counter. - Sequence(int64_t initial_value = kInitialCursorValue) : - value_(initial_value) {} - - // Get the current value of the {@link Sequence}. - // - // @return the current value. - int64_t sequence() const { return value_.load(boost::memory_order_acquire); } - - // Set the current value of the {@link Sequence}. - // - // @param the value to which the {@link Sequence} will be set. - void set_sequence(int64_t value) { value_.store(value, boost::memory_order_release); } - - // Increment and return the value of the {@link Sequence}. - // - // @param increment the {@link Sequence}. - // @return the new value incremented. - int64_t IncrementAndGet(const int64_t& increment) { - return value_.fetch_add(increment, boost::memory_order_release) + increment; - } - - private: - // members - boost::atomic value_; - -}; - -// Cache line padded sequence counter. -// -// Can be used across threads without worrying about false sharing if a -// located adjacent to another counter in memory. -class PaddedSequence : public Sequence { - public: - PaddedSequence(int64_t initial_value = kInitialCursorValue) : - Sequence(initial_value) {} - - //private: - // padding - //int64_t padding_[ATOMIC_SEQUENCE_PADDING_LENGTH]; - -}; - -// Non-atomic sequence counter. -// -// This counter is not thread safe. -class MutableLong { - public: - MutableLong(int64_t initial_value = kInitialCursorValue) : - sequence_(initial_value) {} - - int64_t sequence() const { return sequence_; } - - void set_sequence(const int64_t& sequence) { sequence_ = sequence; }; - - int64_t IncrementAndGet(const int64_t& delta) { sequence_ += delta; return sequence_; } - - private: - volatile int64_t sequence_; -}; - -// Cache line padded non-atomic sequence counter. -// -// This counter is not thread safe. -class PaddedLong : public MutableLong { - public: - PaddedLong(int64_t initial_value = kInitialCursorValue) : - MutableLong(initial_value) {} - //private: - //int64_t padding_[SEQUENCE_PADDING_LENGTH]; -}; - -int64_t GetMinimumSequence( - const std::vector& sequences) { - int64_t minimum = std::numeric_limits::max(); - - std::vector::const_iterator it= sequences.begin(); - for (;it!=sequences.end();it++) { - int64_t sequence = (*it)->sequence(); - minimum = minimum < sequence ? minimum : sequence; - } - - return minimum; -}; - -}; // namespace rocketmq - -#endif // DISRUPTOR_SEQUENCE_H_ NOLINT diff --git a/src/thread/disruptor/sequence_barrier.h b/src/thread/disruptor/sequence_barrier.h deleted file mode 100755 index 5882e39db..000000000 --- a/src/thread/disruptor/sequence_barrier.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2011, François Saint-Jacques -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the disruptor-- nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL FRANÇOIS SAINT-JACQUES BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DISRUPTOR_SEQUENCE_BARRIER_H_ // NOLINT -#define DISRUPTOR_SEQUENCE_BARRIER_H_ // NOLINT - -#include -#include - -#include "exceptions.h" -#include "interface.h" -namespace rocketmq { - -class ProcessingSequenceBarrier : SequenceBarrierInterface { - public: - ProcessingSequenceBarrier(WaitStrategyInterface* wait_strategy, - Sequence* sequence, - const std::vector& sequences) : - wait_strategy_(wait_strategy), - cursor_(sequence), - dependent_sequences_(sequences), - alerted_(false) { - } - - virtual int64_t WaitFor(const int64_t& sequence) { - return wait_strategy_->WaitFor(dependent_sequences_, *cursor_, *this, - sequence); - } - - virtual int64_t WaitFor(const int64_t& sequence, - const int64_t& timeout_micros) { - return wait_strategy_->WaitFor(dependent_sequences_, *cursor_, *this, - sequence, timeout_micros); - } - - virtual int64_t GetCursor() const { - return cursor_->sequence(); - } - - virtual bool IsAlerted() const { - return alerted_.load(boost::memory_order_acquire); - } - - virtual void Alert() { - //rocketmq::LOG_INFO("set alert to true"); - alerted_.store(true, boost::memory_order_release); - } - - virtual void ClearAlert() { - alerted_.store(false, boost::memory_order_release); - } - - virtual void CheckAlert() const { - if (IsAlerted()) - { - //rocketmq::LOG_INFO("throw alert exception\r\n"); - throw AlertException(); - } - } - - private: - WaitStrategyInterface* wait_strategy_; - Sequence* cursor_; - std::vector dependent_sequences_; - boost::atomic alerted_; -}; - -}; // namespace rocketmq - -#endif // DISRUPTOR_DEPENDENCY_BARRIER_H_ NOLINT diff --git a/src/thread/disruptor/sequencer.h b/src/thread/disruptor/sequencer.h deleted file mode 100755 index 98d617f5e..000000000 --- a/src/thread/disruptor/sequencer.h +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (c) 2011, François Saint-Jacques -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the disruptor-- nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL FRANÇOIS SAINT-JACQUES BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DISRUPTOR_SEQUENCER_H_ // NOLINT -#define DISRUPTOR_SEQUENCER_H_ // NOLINT - -#include - -#include "batch_descriptor.h" -#include "claim_strategy.h" -#include "interface.h" -#include "sequence_barrier.h" -#include "wait_strategy.h" - -namespace rocketmq { - -// Coordinator for claiming sequences for access to a data structures while -// tracking dependent {@link Sequence}s -class Sequencer: public boost::noncopyable { - public: - // Construct a Sequencer with the selected strategies. - // - // @param buffer_size over which sequences are valid. - // @param claim_strategy_option for those claiming sequences. - // @param wait_strategy_option for those waiting on sequences. - Sequencer(int buffer_size, - ClaimStrategyOption claim_strategy_option, - WaitStrategyOption wait_strategy_option) : - buffer_size_(buffer_size), - claim_strategy_(CreateClaimStrategy(claim_strategy_option, - buffer_size_)), - wait_strategy_(CreateWaitStrategy(wait_strategy_option)) { } - - ~Sequencer() { - delete claim_strategy_; - delete wait_strategy_; - } - - // Set the sequences that will gate publishers to prevent the buffer - // wrapping. - // - // @param sequences to be gated on. - void set_gating_sequences( - const std::vector& sequences) { - gating_sequences_ = sequences; - } - - // Create a {@link SequenceBarrier} that gates on the cursor and a list of - // {@link Sequence}s. - // - // @param sequences_to_track this barrier will track. - // @return the barrier gated as required. - ProcessingSequenceBarrier* NewBarrier( - const std::vector& sequences_to_track) { - return new ProcessingSequenceBarrier(wait_strategy_, &cursor_, - sequences_to_track); - } - - // Create a new {@link BatchDescriptor} that is the minimum of the - // requested size and the buffer_size. - // - // @param size for the new batch. - // @return the new {@link BatchDescriptor}. - BatchDescriptor* NewBatchDescriptor(const int& size) { - return new BatchDescriptor(sizeHasAvalaibleCapacity(gating_sequences_); - } - - // Claim the next event in sequence for publishing to the {@link RingBuffer}. - // - // @return the claimed sequence. - int64_t Next() { - return claim_strategy_->IncrementAndGet(gating_sequences_); - } - - // Claim the next batch of sequence numbers for publishing. - // - // @param batch_descriptor to be updated for the batch range. - // @return the updated batch_descriptor. - BatchDescriptor* Next(BatchDescriptor* batch_descriptor) { - int64_t sequence = claim_strategy_->IncrementAndGet(batch_descriptor->size(), gating_sequences_); - batch_descriptor->set_end(sequence); - return batch_descriptor; - } - - // Claim a specific sequence when only one publisher is involved. - // - // @param sequence to be claimed. - // @return sequence just claime. - int64_t Claim(const int64_t& sequence) { - claim_strategy_->SetSequence(sequence, gating_sequences_); - return sequence; - } - - // Publish an event and make it visible to {@link EventProcessor}s. - // - // @param sequence to be published. - void Publish(const int64_t& sequence) { - Publish(sequence, 1); - } - - // Publish the batch of events in sequence. - // - // @param sequence to be published. - void Publish(const BatchDescriptor& batch_descriptor) { - Publish(batch_descriptor.end(), batch_descriptor.size()); - } - - // Force the publication of a cursor sequence. - // - // Only use this method when forcing a sequence and you are sure only one - // publisher exists. This will cause the cursor to advance to this - // sequence. - // - // @param sequence to which is to be forced for publication. - void ForcePublish(const int64_t& sequence) { - cursor_.set_sequence(sequence); - wait_strategy_->SignalAllWhenBlocking(); - } - - // TODO(fsaintjacques): This was added to overcome - // NoOpEventProcessor::GetSequence(), this is not a clean solution. - Sequence* GetSequencePtr() { - return &cursor_; - } - - private: - // Helpers - void Publish(const int64_t& sequence, const int64_t& batch_size) { - //LOG_DEBUG("publish sequence:%d", sequence); - claim_strategy_->SerialisePublishing(sequence, cursor_, batch_size); - cursor_.set_sequence(sequence); - wait_strategy_->SignalAllWhenBlocking(); - } - - // Members - const int buffer_size_; - - PaddedSequence cursor_; - std::vector gating_sequences_; - - ClaimStrategyInterface* claim_strategy_; - WaitStrategyInterface* wait_strategy_; - -}; - -}; // namespace rocketmq - -#endif // DISRUPTOR_RING_BUFFER_H_ NOLINT diff --git a/src/thread/disruptor/utils.h b/src/thread/disruptor/utils.h deleted file mode 100755 index 0730093e2..000000000 --- a/src/thread/disruptor/utils.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2011, François Saint-Jacques -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the disruptor-- nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL FRANÇOIS SAINT-JACQUES BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DISRUPTOR_UTILS_H_ // NOLINT -#define DISRUPTOR_UTILS_H_ // NOLINT - -// From Google C++ Standard, modified to use C++11 deleted functions. -// A macro to disallow the copy constructor and operator= functions. -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&) delete \ - void operator=(const TypeName&) delete; - -#endif // DISRUPTOR_UTILS_H_ NOLINT diff --git a/src/thread/disruptor/wait_strategy.h b/src/thread/disruptor/wait_strategy.h deleted file mode 100755 index 92044a8b0..000000000 --- a/src/thread/disruptor/wait_strategy.h +++ /dev/null @@ -1,372 +0,0 @@ -// Copyright (c) 2011, François Saint-Jacques -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the disruptor-- nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL FRANÇOIS SAINT-JACQUES BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DISRUPTOR_WAITSTRATEGY_H_ // NOLINT -#define DISRUPTOR_WAITSTRATEGY_H_ // NOLINT - -#include -#include -#include -#include - -#include "exceptions.h" -#include "interface.h" -#include "sequence.h" - -namespace rocketmq { - -// Strategy options which are available to those waiting on a -// {@link RingBuffer} -enum WaitStrategyOption { - // This strategy uses a condition variable inside a lock to block the - // event procesor which saves CPU resource at the expense of lock - // contention. - kBlockingStrategy, - // This strategy uses a progressive back off strategy by first spinning, - // then yielding, then sleeping for 1ms period. This is a good strategy - // for burst traffic then quiet periods when latency is not critical. - kSleepingStrategy, - // This strategy calls Thread.yield() in a loop as a waiting strategy - // which reduces contention at the expense of CPU resource. - kYieldingStrategy, - // This strategy call spins in a loop as a waiting strategy which is - // lowest and most consistent latency but ties up a CPU. - kBusySpinStrategy -}; - -// Blocking strategy that uses a lock and condition variable for -// {@link Consumer}s waiting on a barrier. -// This strategy should be used when performance and low-latency are not as -// important as CPU resource. -class BlockingStrategy : public WaitStrategyInterface { - public: - BlockingStrategy() {} - - virtual int64_t WaitFor(const std::vector& dependents, - const Sequence& cursor, - const SequenceBarrierInterface& barrier, - const int64_t& sequence) { - int64_t available_sequence = 0; - // We need to wait. - if ((available_sequence = cursor.sequence()) < sequence) { - // acquire lock - boost::unique_lock ulock(mutex_); - while ((available_sequence = cursor.sequence()) < sequence) { - barrier.CheckAlert(); - consumer_notify_condition_.wait(ulock); - } - } // unlock happens here, on ulock destruction. - - if (0 != dependents.size()) { - while ((available_sequence = GetMinimumSequence(dependents)) < sequence) { - barrier.CheckAlert(); - } - } - - return available_sequence; - } - - virtual int64_t WaitFor(const std::vector& dependents, - const Sequence& cursor, - const SequenceBarrierInterface& barrier, - const int64_t& sequence, - const int64_t& timeout_micros) { - int64_t available_sequence = 0; - // We have to wait - if ((available_sequence = cursor.sequence()) < sequence) { - boost::unique_lock ulock(mutex_); - while ((available_sequence = cursor.sequence()) < sequence) { - barrier.CheckAlert(); - if (boost::cv_status::timeout == - consumer_notify_condition_.wait_for( - ulock, boost::chrono::microseconds(timeout_micros))) - break; - } - } // unlock happens here, on ulock destruction - - if (0 != dependents.size()) { - while ((available_sequence = GetMinimumSequence(dependents)) < sequence) { - barrier.CheckAlert(); - } - } - - return available_sequence; - } - - virtual void SignalAllWhenBlocking() { - boost::unique_lock ulock(mutex_); - consumer_notify_condition_.notify_all(); - } - - private: - boost::recursive_mutex mutex_; - boost::condition_variable_any consumer_notify_condition_; -}; - -// Sleeping strategy -class SleepingStrategy : public WaitStrategyInterface { - public: - SleepingStrategy() {} - - virtual int64_t WaitFor(const std::vector& dependents, - const Sequence& cursor, - const SequenceBarrierInterface& barrier, - const int64_t& sequence) { - int64_t available_sequence = 0; - int counter = kRetries; - - if (0 == dependents.size()) { - while ((available_sequence = cursor.sequence()) < sequence) { - counter = ApplyWaitMethod(barrier, counter); - } - } else { - while ((available_sequence = GetMinimumSequence(dependents)) < sequence) { - counter = ApplyWaitMethod(barrier, counter); - } - } - - return available_sequence; - } - - virtual int64_t WaitFor(const std::vector& dependents, - const Sequence& cursor, - const SequenceBarrierInterface& barrier, - const int64_t& sequence, - const int64_t& timeout_micros) { - // timing - boost::posix_time::ptime current_date_microseconds = - boost::posix_time::microsec_clock::local_time(); - int64_t start_micro = - current_date_microseconds.time_of_day().total_milliseconds(); - - int64_t available_sequence = 0; - int counter = kRetries; - - if (0 == dependents.size()) { - while ((available_sequence = cursor.sequence()) < sequence) { - counter = ApplyWaitMethod(barrier, counter); - boost::posix_time::ptime current_date_microseconds = - boost::posix_time::microsec_clock::local_time(); - int64_t end_micro = - current_date_microseconds.time_of_day().total_milliseconds(); - if (timeout_micros < (end_micro - start_micro)) break; - } - } else { - while ((available_sequence = GetMinimumSequence(dependents)) < sequence) { - counter = ApplyWaitMethod(barrier, counter); - boost::posix_time::ptime current_date_microseconds = - boost::posix_time::microsec_clock::local_time(); - int64_t end_micro = - current_date_microseconds.time_of_day().total_milliseconds(); - if (timeout_micros < (end_micro - start_micro)) break; - } - } - - return available_sequence; - } - - virtual void SignalAllWhenBlocking() {} - - static const int kRetries = 200; - - private: - int ApplyWaitMethod(const SequenceBarrierInterface& barrier, int counter) { - barrier.CheckAlert(); - if (counter > 100) { - counter--; - } else if (counter > 0) { - counter--; - boost::this_thread::yield(); - } else { - boost::this_thread::sleep_for(boost::chrono::milliseconds(1)); - } - - return counter; - } -}; - -// Yielding strategy that uses a sleep(0) for {@link EventProcessor}s waiting -// on a barrier. This strategy is a good compromise between performance and -// CPU resource. -class YieldingStrategy : public WaitStrategyInterface { - public: - YieldingStrategy() {} - - virtual int64_t WaitFor(const std::vector& dependents, - const Sequence& cursor, - const SequenceBarrierInterface& barrier, - const int64_t& sequence) { - int64_t available_sequence = 0; - int counter = kSpinTries; - - if (0 == dependents.size()) { - while ((available_sequence = cursor.sequence()) < sequence) { - counter = ApplyWaitMethod(barrier, counter); - } - } else { - while ((available_sequence = GetMinimumSequence(dependents)) < sequence) { - counter = ApplyWaitMethod(barrier, counter); - } - } - - return available_sequence; - } - - virtual int64_t WaitFor(const std::vector& dependents, - const Sequence& cursor, - const SequenceBarrierInterface& barrier, - const int64_t& sequence, - const int64_t& timeout_micros) { - boost::posix_time::ptime current_date_microseconds = - boost::posix_time::microsec_clock::local_time(); - int64_t start_micro = - current_date_microseconds.time_of_day().total_milliseconds(); - - int64_t available_sequence = 0; - int counter = kSpinTries; - - if (0 == dependents.size()) { - while ((available_sequence = cursor.sequence()) < sequence) { - counter = ApplyWaitMethod(barrier, counter); - boost::posix_time::ptime current_date_microseconds = - boost::posix_time::microsec_clock::local_time(); - int64_t end_micro = - current_date_microseconds.time_of_day().total_milliseconds(); - if (timeout_micros < (end_micro - start_micro)) break; - } - } else { - while ((available_sequence = GetMinimumSequence(dependents)) < sequence) { - counter = ApplyWaitMethod(barrier, counter); - boost::posix_time::ptime current_date_microseconds = - boost::posix_time::microsec_clock::local_time(); - int64_t end_micro = - current_date_microseconds.time_of_day().total_milliseconds(); - if (timeout_micros < (end_micro - start_micro)) break; - } - } - - return available_sequence; - } - - virtual void SignalAllWhenBlocking() {} - - static const int kSpinTries = 100; - - private: - int ApplyWaitMethod(const SequenceBarrierInterface& barrier, int counter) { - barrier.CheckAlert(); - if (counter == 0) { - boost::this_thread::yield(); - } else { - counter--; - } - - return counter; - } -}; - -// Busy Spin strategy that uses a busy spin loop for {@link EventProcessor}s -// waiting on a barrier. -// This strategy will use CPU resource to avoid syscalls which can introduce -// latency jitter. It is best used when threads can be bound to specific -// CPU cores. -class BusySpinStrategy : public WaitStrategyInterface { - public: - BusySpinStrategy() {} - - virtual int64_t WaitFor(const std::vector& dependents, - const Sequence& cursor, - const SequenceBarrierInterface& barrier, - const int64_t& sequence) { - int64_t available_sequence = 0; - if (0 == dependents.size()) { - while ((available_sequence = cursor.sequence()) < sequence) { - barrier.CheckAlert(); - } - } else { - while ((available_sequence = GetMinimumSequence(dependents)) < sequence) { - barrier.CheckAlert(); - } - } - - return available_sequence; - } - - virtual int64_t WaitFor(const std::vector& dependents, - const Sequence& cursor, - const SequenceBarrierInterface& barrier, - const int64_t& sequence, - const int64_t& timeout_micros) { - boost::posix_time::ptime current_date_microseconds = - boost::posix_time::microsec_clock::local_time(); - int64_t start_micro = - current_date_microseconds.time_of_day().total_milliseconds(); - int64_t available_sequence = 0; - - if (0 == dependents.size()) { - while ((available_sequence = cursor.sequence()) < sequence) { - barrier.CheckAlert(); - boost::posix_time::ptime current_date_microseconds = - boost::posix_time::microsec_clock::local_time(); - int64_t end_micro = - current_date_microseconds.time_of_day().total_milliseconds(); - if (timeout_micros < (end_micro - start_micro)) break; - } - } else { - while ((available_sequence = GetMinimumSequence(dependents)) < sequence) { - barrier.CheckAlert(); - boost::posix_time::ptime current_date_microseconds = - boost::posix_time::microsec_clock::local_time(); - int64_t end_micro = - current_date_microseconds.time_of_day().total_milliseconds(); - if (timeout_micros < (end_micro - start_micro)) break; - } - } - - return available_sequence; - } - - virtual void SignalAllWhenBlocking() {} -}; - -WaitStrategyInterface* CreateWaitStrategy(WaitStrategyOption wait_option) { - switch (wait_option) { - case kBlockingStrategy: - return new BlockingStrategy(); - case kSleepingStrategy: - return new SleepingStrategy(); - case kYieldingStrategy: - return new YieldingStrategy(); - case kBusySpinStrategy: - return new BusySpinStrategy(); - default: - return NULL; - } -} - -}; // namespace rocketmq - -#endif // DISRUPTOR_WAITSTRATEGY_H_ NOLINT diff --git a/src/thread/disruptorLFQ.h b/src/thread/disruptorLFQ.h deleted file mode 100644 index 30e5a1858..000000000 --- a/src/thread/disruptorLFQ.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -* 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 _DISRUPTORLFQ_ -#define _DISRUPTORLFQ_ - -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace rocketmq { -class Task; -class taskEventFactory : public EventFactoryInterface { - public: - virtual Task* NewInstance(const int& size) const; -}; - -class taskBatchHandler : public EventHandlerInterface { - public: - taskBatchHandler(int pullMsgThreadPoolNum); - virtual ~taskBatchHandler() {} - - virtual void OnEvent(const int64_t& sequence, const bool& end_of_batch, Task* event); - virtual void OnStart() {} - virtual void OnShutdown() {} - void runTaskEvent(Task event, int64_t sequence); - void stopIOService(); - - private: - boost::asio::io_service m_ioService; - boost::thread_group m_threadpool; - boost::asio::io_service::work m_ioServiceWork; -}; - -class taskEventTranslator : public EventTranslatorInterface { - public: - taskEventTranslator(Task* event); - virtual ~taskEventTranslator() {} - virtual Task* TranslateTo(const int64_t& sequence, Task* event); - - private: - Task* m_taskEvent; -}; - -class taskExceptionHandler : public ExceptionHandlerInterface { - public: - virtual void Handle(const std::exception& exception, const int64_t& sequence, Task* event) {} -}; - -class disruptorLFQ { - public: - disruptorLFQ(int threadCount) { - m_task_factory.reset(new taskEventFactory()); - m_ring_buffer.reset(new RingBuffer(m_task_factory.get(), - 1024, // default size is 1024, must be n power of 2 - kSingleThreadedStrategy, - kBlockingStrategy)); // load normal, lowest CPU occupy, but - // largest consume latency - - m_sequence_to_track.reset(new std::vector(0)); - m_sequenceBarrier.reset(m_ring_buffer->NewBarrier(*(m_sequence_to_track.get()))); - - m_task_handler.reset(new taskBatchHandler(threadCount)); - m_task_exception_handler.reset(new taskExceptionHandler()); - m_processor.reset(new BatchEventProcessor(m_ring_buffer.get(), - (SequenceBarrierInterface*)m_sequenceBarrier.get(), - m_task_handler.get(), m_task_exception_handler.get())); - - /* - Publisher will try to publish BUFFER_SIZE + 1 events. - The last event should wait for at least one consume before publishing, thus - preventing an overwrite. - After the single consume, the publisher should resume and publish the last - event. - */ - m_gating_sequences.push_back(m_processor.get()->GetSequence()); - m_ring_buffer->set_gating_sequences(m_gating_sequences); // prevent overlap, publishEvent will be blocked - // on ring_buffer_->Next(); - - m_publisher.reset(new EventPublisher(m_ring_buffer.get())); - } - virtual ~disruptorLFQ() {} - - public: - boost::scoped_ptr m_task_factory; - boost::scoped_ptr m_task_handler; - boost::scoped_ptr m_task_exception_handler; - boost::scoped_ptr> m_sequence_to_track; - boost::scoped_ptr> m_ring_buffer; - boost::scoped_ptr m_sequenceBarrier; - boost::scoped_ptr> m_processor; - boost::scoped_ptr> m_publisher; - std::vector m_gating_sequences; -}; -} -// -#endif -#include "UtilAll.h" -#include "disruptorLFQ.h" - -namespace rocketmq { -//m_task_handler->stopIOService(); - m_disruptorLFQ->m_processor->Halt(); -} - -bool TaskQueue::bTaskQueueStatusOK() { - return m_flag.load(boost::memory_order_acquire) == true; -} - -void TaskQueue::produce(const Task& task) { - boost::mutex::scoped_lock lock(m_publishLock); - taskEventTranslator pTranslator(const_cast(&task)); - m_disruptorLFQ->m_publisher->PublishEvent(&pTranslator); -} - -int TaskQueue::run() { - while (true) { - m_disruptorLFQ->m_processor->Run(); - if (m_flag.load(boost::memory_order_acquire) == false) { - break; - } - } - return 0; -} - -// -#include -#include -#include -using namespace std; - -namespace rocketmq { - -//fork()) {} - Task() { m_pTaskImpl = new Task_impl(&Task::dumy, 0); } - virtual ~Task() { delete m_pTaskImpl; } - Task& operator=(const Task& src_) { - delete m_pTaskImpl; - m_pTaskImpl = src_.m_pTaskImpl->fork(); - return *this; - } - void run() { - if (m_pTaskImpl) - m_pTaskImpl->run(); - } - - private: - ITask_impl* m_pTaskImpl; -}; - -// TaskList; - - public: - virtual ~ITaskQueue() {} - virtual void close() = 0; - virtual void produce(const Task& task) = 0; - // virtual void multi_produce(const TaskList& tasks) = 0; - // virtual int consume(Task& task) = 0; - // virtual int consume_all(TaskList& tasks) = 0; - virtual int run() = 0; - // virtual int batch_run() = 0; - virtual bool bTaskQueueStatusOK() = 0; -}; - -// - static Task gen(RET (*func)(void)) { - struct lambda { - static void taskfunc(void* p_) { (*(RET(*)(void))p_)(); }; - }; - return Task(lambda::taskfunc, (void*)func); - } - - template - static Task gen(FUNCT func, ARG1 arg1) { - struct lambda : public ITask_impl { - FUNCT dest_func; - ARG1 arg1; - lambda(FUNCT func, const ARG1& arg1) : dest_func(func), arg1(arg1) {} - virtual void run() { (*dest_func)(arg1); } - virtual ITask_impl* fork() { return new lambda(dest_func, arg1); } - }; - return Task(new lambda(func, arg1)); - } - - template - static Task gen(FUNCT func, ARG1 arg1, ARG2 arg2) { - struct lambda : public ITask_impl { - FUNCT dest_func; - ARG1 arg1; - ARG2 arg2; - lambda(FUNCT func, const ARG1& arg1, const ARG2& arg2) : dest_func(func), arg1(arg1), arg2(arg2) {} - virtual void run() { (*dest_func)(arg1, arg2); } - virtual ITask_impl* fork() { return new lambda(dest_func, arg1, arg2); } - }; - return Task(new lambda(func, arg1, arg2)); - } - - template - static Task gen(FUNCT func, ARG1 arg1, ARG2 arg2, ARG3 arg3) { - struct lambda : public ITask_impl { - FUNCT dest_func; - ARG1 arg1; - ARG2 arg2; - ARG3 arg3; - lambda(FUNCT func, const ARG1& arg1, const ARG2& arg2, const ARG3& arg3) - : dest_func(func), arg1(arg1), arg2(arg2), arg3(arg3) {} - virtual void run() { (*dest_func)(arg1, arg2, arg3); } - virtual ITask_impl* fork() { return new lambda(dest_func, arg1, arg2, arg3); } - }; - return Task(new lambda(func, arg1, arg2, arg3)); - } - - template - static Task gen(FUNCT func, ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4) { - struct lambda : public ITask_impl { - FUNCT dest_func; - ARG1 arg1; - ARG2 arg2; - ARG3 arg3; - ARG4 arg4; - lambda(FUNCT func, const ARG1& arg1, const ARG2& arg2, const ARG3& arg3, const ARG4& arg4) - : dest_func(func), arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4) {} - virtual void run() { (*dest_func)(arg1, arg2, arg3, arg4); } - virtual ITask_impl* fork() { return new lambda(dest_func, arg1, arg2, arg3, arg4); } - }; - return Task(new lambda(func, arg1, arg2, arg3, arg4)); - } - - template - static Task gen(FUNCT func, ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5) { - struct lambda : public ITask_impl { - FUNCT dest_func; - ARG1 arg1; - ARG2 arg2; - ARG3 arg3; - ARG4 arg4; - ARG5 arg5; - lambda(FUNCT func, const ARG1& arg1, const ARG2& arg2, const ARG3& arg3, const ARG4& arg4, const ARG5& arg5) - : dest_func(func), arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4), arg5(arg5) {} - virtual void run() { (*dest_func)(arg1, arg2, arg3, arg4, arg5); } - virtual ITask_impl* fork() { return new lambda(dest_func, arg1, arg2, arg3, arg4, arg5); } - }; - return Task(new lambda(func, arg1, arg2, arg3, arg4, arg5)); - } - - template - static Task gen(FUNCT func, ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6) { - struct lambda : public ITask_impl { - FUNCT dest_func; - ARG1 arg1; - ARG2 arg2; - ARG3 arg3; - ARG4 arg4; - ARG5 arg5; - ARG6 arg6; - lambda(FUNCT func, - const ARG1& arg1, - const ARG2& arg2, - const ARG3& arg3, - const ARG4& arg4, - const ARG5& arg5, - const ARG6& arg6) - : dest_func(func), arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4), arg5(arg5), arg6(arg6) {} - virtual void run() { (*dest_func)(arg1, arg2, arg3, arg4, arg5, arg6); } - virtual ITask_impl* fork() { return new lambda(dest_func, arg1, arg2, arg3, arg4, arg5, arg6); } - }; - return Task(new lambda(func, arg1, arg2, arg3, arg4, arg5, arg6)); - } - - template - static Task gen(FUNCT func, ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6, ARG7 arg7) { - struct lambda : public ITask_impl { - FUNCT dest_func; - ARG1 arg1; - ARG2 arg2; - ARG3 arg3; - ARG4 arg4; - ARG5 arg5; - ARG6 arg6; - ARG7 arg7; - lambda(FUNCT func, - const ARG1& arg1, - const ARG2& arg2, - const ARG3& arg3, - const ARG4& arg4, - const ARG5& arg5, - const ARG6& arg6, - const ARG7& arg7) - : dest_func(func), arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4), arg5(arg5), arg6(arg6), arg7(arg7) {} - virtual void run() { (*dest_func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7); } - virtual ITask_impl* fork() { return new lambda(dest_func, arg1, arg2, arg3, arg4, arg5, arg6, arg7); } - }; - return Task(new lambda(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7)); - } - - template - static Task gen(FUNCT func, ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6, ARG7 arg7, ARG8 arg8) { - struct lambda : public ITask_impl { - FUNCT dest_func; - ARG1 arg1; - ARG2 arg2; - ARG3 arg3; - ARG4 arg4; - ARG5 arg5; - ARG6 arg6; - ARG7 arg7; - ARG8 arg8; - lambda(FUNCT func, - const ARG1& arg1, - const ARG2& arg2, - const ARG3& arg3, - const ARG4& arg4, - const ARG5& arg5, - const ARG6& arg6, - const ARG7& arg7, - const ARG8& arg8) - : dest_func(func), - arg1(arg1), - arg2(arg2), - arg3(arg3), - arg4(arg4), - arg5(arg5), - arg6(arg6), - arg7(arg7), - arg8(arg8) {} - virtual void run() { (*dest_func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } - virtual ITask_impl* fork() { return new lambda(dest_func, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } - }; - return Task(new lambda(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); - } - - template - static Task - gen(FUNCT func, ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6, ARG7 arg7, ARG8 arg8, ARG9 arg9) { - struct lambda : public ITask_impl { - FUNCT dest_func; - ARG1 arg1; - ARG2 arg2; - ARG3 arg3; - ARG4 arg4; - ARG5 arg5; - ARG6 arg6; - ARG7 arg7; - ARG8 arg8; - ARG9 arg9; - lambda(FUNCT func, - const ARG1& arg1, - const ARG2& arg2, - const ARG3& arg3, - const ARG4& arg4, - const ARG5& arg5, - const ARG6& arg6, - const ARG7& arg7, - const ARG8& arg8, - const ARG9& arg9) - : dest_func(func), - arg1(arg1), - arg2(arg2), - arg3(arg3), - arg4(arg4), - arg5(arg5), - arg6(arg6), - arg7(arg7), - arg8(arg8), - arg9(arg9) {} - virtual void run() { (*dest_func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); } - virtual ITask_impl* fork() { return new lambda(dest_func, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); } - }; - return Task(new lambda(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)); - } - - // - static Task gen(RET (T::*func)(void), T* obj) { - struct lambda : public ITask_impl { - RET (T::*dest_func)(void); - T* obj; - lambda(RET (T::*func)(void), T* obj) : dest_func(func), obj(obj) {} - virtual void run() { (obj->*dest_func)(); } - virtual ITask_impl* fork() { return new lambda(dest_func, obj); } - }; - return Task(new lambda(func, obj)); - } - - template - static Task gen(RET (T::*func)(FARG1), T* obj, ARG1 arg1) { - struct lambda : public ITask_impl { - RET (T::*dest_func)(FARG1); - T* obj; - ARG1 arg1; - lambda(RET (T::*pfunc)(FARG1), T* obj, const ARG1& arg1) : dest_func(pfunc), obj(obj), arg1(arg1) {} - virtual void run() { (obj->*dest_func)(arg1); } - virtual ITask_impl* fork() { return new lambda(dest_func, obj, arg1); } - }; - return Task(new lambda(func, obj, arg1)); - } - - template - static Task gen(RET (T::*func)(FARG1, FARG2), T* obj, ARG1 arg1, ARG2 arg2) { - struct lambda : public ITask_impl { - RET (T::*dest_func)(FARG1, FARG2); - T* obj; - ARG1 arg1; - ARG2 arg2; - lambda(RET (T::*func)(FARG1, FARG2), T* obj, const ARG1& arg1, const ARG2& arg2) - : dest_func(func), obj(obj), arg1(arg1), arg2(arg2) {} - virtual void run() { (obj->*dest_func)(arg1, arg2); } - virtual ITask_impl* fork() { return new lambda(dest_func, obj, arg1, arg2); } - }; - return Task(new lambda(func, obj, arg1, arg2)); - } - - template - static Task gen(RET (T::*func)(FARG1, FARG2, FARG3), T* obj, ARG1 arg1, ARG2 arg2, ARG3 arg3) { - struct lambda : public ITask_impl { - RET (T::*dest_func)(FARG1, FARG2, FARG3); - T* obj; - ARG1 arg1; - ARG2 arg2; - ARG3 arg3; - lambda(RET (T::*func)(FARG1, FARG2, FARG3), T* obj, const ARG1& arg1, const ARG2& arg2, const ARG3& arg3) - : dest_func(func), obj(obj), arg1(arg1), arg2(arg2), arg3(arg3) {} - virtual void run() { (obj->*dest_func)(arg1, arg2, arg3); } - virtual ITask_impl* fork() { return new lambda(dest_func, obj, arg1, arg2, arg3); } - }; - return Task(new lambda(func, obj, arg1, arg2, arg3)); - } - - template - static Task gen(RET (T::*func)(FARG1, FARG2, FARG3, FARG4), T* obj, ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4) { - struct lambda : public ITask_impl { - RET (T::*dest_func)(FARG1, FARG2, FARG3, FARG4); - T* obj; - ARG1 arg1; - ARG2 arg2; - ARG3 arg3; - ARG4 arg4; - lambda(RET (T::*func)(FARG1, FARG2, FARG3, FARG4), - T* obj, - const ARG1& arg1, - const ARG2& arg2, - const ARG3& arg3, - const ARG4& arg4) - : dest_func(func), obj(obj), arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4) {} - virtual void run() { (obj->*dest_func)(arg1, arg2, arg3, arg4); } - virtual ITask_impl* fork() { return new lambda(dest_func, obj, arg1, arg2, arg3, arg4); } - }; - return Task(new lambda(func, obj, arg1, arg2, arg3, arg4)); - } - - template - static Task gen(RET (T::*func)(FARG1, FARG2, FARG3, FARG4, FARG5), - T* obj, - ARG1 arg1, - ARG2 arg2, - ARG3 arg3, - ARG4 arg4, - ARG5 arg5) { - struct lambda : public ITask_impl { - RET (T::*dest_func)(FARG1, FARG2, FARG3, FARG4, FARG5); - T* obj; - ARG1 arg1; - ARG2 arg2; - ARG3 arg3; - ARG4 arg4; - ARG5 arg5; - lambda(RET (T::*func)(FARG1, FARG2, FARG3, FARG4, FARG5), - T* obj, - const ARG1& arg1, - const ARG2& arg2, - const ARG3& arg3, - const ARG4& arg4, - const ARG5& arg5) - : dest_func(func), obj(obj), arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4), arg5(arg5) {} - virtual void run() { (obj->*dest_func)(arg1, arg2, arg3, arg4, arg5); } - virtual ITask_impl* fork() { return new lambda(dest_func, obj, arg1, arg2, arg3, arg4, arg5); } - }; - return Task(new lambda(func, obj, arg1, arg2, arg3, arg4, arg5)); - } - - template - static Task gen(RET (T::*func)(FARG1, FARG2, FARG3, FARG4, FARG5, FARG6), - T* obj, - ARG1 arg1, - ARG2 arg2, - ARG3 arg3, - ARG4 arg4, - ARG5 arg5, - ARG6 arg6) { - struct lambda : public ITask_impl { - RET (T::*dest_func)(FARG1, FARG2, FARG3, FARG4, FARG5, FARG6); - T* obj; - ARG1 arg1; - ARG2 arg2; - ARG3 arg3; - ARG4 arg4; - ARG5 arg5; - ARG6 arg6; - lambda(RET (T::*func)(FARG1, FARG2, FARG3, FARG4, FARG5, FARG6), - T* obj, - const ARG1& arg1, - const ARG2& arg2, - const ARG3& arg3, - const ARG4& arg4, - const ARG5& arg5, - const ARG6& arg6) - : dest_func(func), obj(obj), arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4), arg5(arg5), arg6(arg6) {} - virtual void run() { (obj->*dest_func)(arg1, arg2, arg3, arg4, arg5, arg6); } - virtual ITask_impl* fork() { return new lambda(dest_func, obj, arg1, arg2, arg3, arg4, arg5, arg6); } - }; - return Task(new lambda(func, obj, arg1, arg2, arg3, arg4, arg5, arg6)); - } - - template - static Task gen(RET (T::*func)(FARG1, FARG2, FARG3, FARG4, FARG5, FARG6, FARG7), - T* obj, - ARG1 arg1, - ARG2 arg2, - ARG3 arg3, - ARG4 arg4, - ARG5 arg5, - ARG6 arg6, - ARG7 arg7) { - struct lambda : public ITask_impl { - RET (T::*dest_func)(FARG1, FARG2, FARG3, FARG4, FARG5, FARG6, FARG7); - T* obj; - ARG1 arg1; - ARG2 arg2; - ARG3 arg3; - ARG4 arg4; - ARG5 arg5; - ARG6 arg6; - ARG7 arg7; - lambda(RET (T::*func)(FARG1, FARG2, FARG3, FARG4, FARG5, FARG6, FARG7), - T* obj, - const ARG1& arg1, - const ARG2& arg2, - const ARG3& arg3, - const ARG4& arg4, - const ARG5& arg5, - const ARG6& arg6, - const ARG7& arg7) - : dest_func(func), - obj(obj), - arg1(arg1), - arg2(arg2), - arg3(arg3), - arg4(arg4), - arg5(arg5), - arg6(arg6), - arg7(arg7) {} - virtual void run() { (obj->*dest_func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7); } - virtual ITask_impl* fork() { return new lambda(dest_func, obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7); } - }; - return Task(new lambda(func, obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7)); - } - - template - static Task gen(RET (T::*func)(FARG1, FARG2, FARG3, FARG4, FARG5, FARG6, FARG7, FARG8), - T* obj, - ARG1 arg1, - ARG2 arg2, - ARG3 arg3, - ARG4 arg4, - ARG5 arg5, - ARG6 arg6, - ARG7 arg7, - ARG8 arg8) { - struct lambda : public ITask_impl { - RET(T::*dest_func) - (FARG1, FARG2, FARG3, FARG4, FARG5, FARG6, FARG7, FARG8); - T* obj; - ARG1 arg1; - ARG2 arg2; - ARG3 arg3; - ARG4 arg4; - ARG5 arg5; - ARG6 arg6; - ARG7 arg7; - ARG8 arg8; - lambda(RET (T::*func)(FARG1, FARG2, FARG3, FARG4, FARG5, FARG6, FARG7, FARG8), - T* obj, - const ARG1& arg1, - const ARG2& arg2, - const ARG3& arg3, - const ARG4& arg4, - const ARG5& arg5, - const ARG6& arg6, - const ARG7& arg7, - const ARG8& arg8) - : dest_func(func), - obj(obj), - arg1(arg1), - arg2(arg2), - arg3(arg3), - arg4(arg4), - arg5(arg5), - arg6(arg6), - arg7(arg7), - arg8(arg8) {} - virtual void run() { (obj->*dest_func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } - virtual ITask_impl* fork() { return new lambda(dest_func, obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } - }; - return Task(new lambda(func, obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); - } - - template - static Task gen(RET (T::*func)(FARG1, FARG2, FARG3, FARG4, FARG5, FARG6, FARG7, FARG8, FARG9), - T* obj, - ARG1 arg1, - ARG2 arg2, - ARG3 arg3, - ARG4 arg4, - ARG5 arg5, - ARG6 arg6, - ARG7 arg7, - ARG8 arg8, - ARG9 arg9) { - struct lambda : public ITask_impl { - RET(T::*dest_func) - (FARG1, FARG2, FARG3, FARG4, FARG5, FARG6, FARG7, FARG8, FARG9); - T* obj; - ARG1 arg1; - ARG2 arg2; - ARG3 arg3; - ARG4 arg4; - ARG5 arg5; - ARG6 arg6; - ARG7 arg7; - ARG8 arg8; - ARG9 arg9; - lambda(RET (T::*func)(FARG1, FARG2, FARG3, FARG4, FARG5, FARG6, FARG7, FARG8, FARG9), - T* obj, - const ARG1& arg1, - const ARG2& arg2, - const ARG3& arg3, - const ARG4& arg4, - const ARG5& arg5, - const ARG6& arg6, - const ARG7& arg7, - const ARG8& arg8, - const ARG9& arg9) - : dest_func(func), - obj(obj), - arg1(arg1), - arg2(arg2), - arg3(arg3), - arg4(arg4), - arg5(arg5), - arg6(arg6), - arg7(arg7), - arg8(arg8), - arg9(arg9) {} - virtual void run() { (obj->*dest_func)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); } - virtual ITask_impl* fork() { - return new lambda(dest_func, obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - }; - return Task(new lambda(func, obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)); - } -}; - -// m_flag; - disruptorLFQ* m_disruptorLFQ; - boost::mutex m_publishLock; -}; - -//getCode()); - switch (request->getCode()) { - case CHECK_TRANSACTION_STATE: - return checkTransactionState(addr, request); - break; - case NOTIFY_CONSUMER_IDS_CHANGED: - return notifyConsumerIdsChanged(request); - break; - case RESET_CONSUMER_CLIENT_OFFSET: // oneWayRPC - return resetOffset(request); - case GET_CONSUMER_STATUS_FROM_CLIENT: - // return getConsumeStatus( request); - break; - case GET_CONSUMER_RUNNING_INFO: - return getConsumerRunningInfo(addr, request); - break; - case CONSUME_MESSAGE_DIRECTLY: - // return consumeMessageDirectly( request); - break; - default: - break; - } - return NULL; -} - -RemotingCommand* ClientRemotingProcessor::resetOffset(RemotingCommand* request) { - request->SetExtHeader(request->getCode()); - const MemoryBlock* pbody = request->GetBody(); - if (pbody->getSize()) { - ResetOffsetBody* offsetBody = ResetOffsetBody::Decode(pbody); - ResetOffsetRequestHeader* offsetHeader = (ResetOffsetRequestHeader*)request->getCommandHeader(); - if (offsetBody) { - m_mqClientFactory->resetOffset(offsetHeader->getGroup(), offsetHeader->getTopic(), offsetBody->getOffsetTable()); - } else { - LOG_ERROR("resetOffset failed as received data could not be unserialized"); - } - } - return NULL; // as resetOffset is oneWayRPC, do not need return any response -} - -std::map ResetOffsetBody::getOffsetTable() { - return m_offsetTable; -} - -void ResetOffsetBody::setOffsetTable(MQMessageQueue mq, int64 offset) { - m_offsetTable[mq] = offset; -} - -ResetOffsetBody* ResetOffsetBody::Decode(const MemoryBlock* mem) { - const char* const pData = static_cast(mem->getData()); - Json::Reader reader; - Json::Value root; - const char* begin = pData; - const char* end = pData + mem->getSize(); - - if (!reader.parse(begin, end, root, true)) { - LOG_ERROR("ResetOffsetBody::Decode fail"); - return NULL; - } - - ResetOffsetBody* rfb = new ResetOffsetBody(); - Json::Value qds = root["offsetTable"]; - for (unsigned int i = 0; i < qds.size(); i++) { - MQMessageQueue mq; - Json::Value qd = qds[i]; - mq.setBrokerName(qd["brokerName"].asString()); - mq.setQueueId(qd["queueId"].asInt()); - mq.setTopic(qd["topic"].asString()); - int64 offset = qd["offset"].asInt64(); - LOG_INFO("ResetOffsetBody brokerName:%s, queueID:%d, topic:%s, offset:%lld", mq.getBrokerName().c_str(), - mq.getQueueId(), mq.getTopic().c_str(), offset); - rfb->setOffsetTable(mq, offset); - } - return rfb; -} - -RemotingCommand* ClientRemotingProcessor::getConsumerRunningInfo(const string& addr, RemotingCommand* request) { - request->SetExtHeader(request->getCode()); - GetConsumerRunningInfoRequestHeader* requestHeader = - (GetConsumerRunningInfoRequestHeader*)request->getCommandHeader(); - LOG_INFO("getConsumerRunningInfo:%s", requestHeader->getConsumerGroup().c_str()); - - RemotingCommand* pResponse = - new RemotingCommand(request->getCode(), "CPP", request->getVersion(), request->getOpaque(), request->getFlag(), - request->getRemark(), NULL); - - unique_ptr runningInfo( - m_mqClientFactory->consumerRunningInfo(requestHeader->getConsumerGroup())); - if (runningInfo) { - if (requestHeader->isJstackEnable()) { - /*string jstack = UtilAll::jstack(); - consumerRunningInfo->setJstack(jstack);*/ - } - pResponse->setCode(SUCCESS_VALUE); - string body = runningInfo->encode(); - pResponse->SetBody(body.c_str(), body.length()); - pResponse->setMsgBody(body); - } else { - pResponse->setCode(SYSTEM_ERROR); - pResponse->setRemark("The Consumer Group not exist in this consumer"); - } - - SessionCredentials sessionCredentials; - m_mqClientFactory->getSessionCredentialFromConsumer(requestHeader->getConsumerGroup(), sessionCredentials); - ClientRPCHook rpcHook(sessionCredentials); - rpcHook.doBeforeRequest(addr, *pResponse); - pResponse->Encode(); - return pResponse; -} - -RemotingCommand* ClientRemotingProcessor::notifyConsumerIdsChanged(RemotingCommand* request) { - request->SetExtHeader(request->getCode()); - NotifyConsumerIdsChangedRequestHeader* requestHeader = - (NotifyConsumerIdsChangedRequestHeader*)request->getCommandHeader(); - if (requestHeader == nullptr) { - LOG_ERROR("notifyConsumerIdsChanged requestHeader null"); - return NULL; - } - string group = requestHeader->getGroup(); - LOG_INFO("notifyConsumerIdsChanged:%s", group.c_str()); - m_mqClientFactory->doRebalanceByConsumerGroup(requestHeader->getGroup()); - return NULL; -} - -RemotingCommand* ClientRemotingProcessor::checkTransactionState(const std::string& addr, RemotingCommand* request) { - if (!request) { - LOG_ERROR("checkTransactionState request null"); - return nullptr; - } - - LOG_INFO("checkTransactionState addr:%s, request: %s", addr.data(), request->ToString().data()); - - request->SetExtHeader(request->getCode()); - CheckTransactionStateRequestHeader* requestHeader = (CheckTransactionStateRequestHeader*)request->getCommandHeader(); - if (!requestHeader) { - LOG_ERROR("checkTransactionState CheckTransactionStateRequestHeader requestHeader null"); - return nullptr; - } - LOG_INFO("checkTransactionState request: %s", requestHeader->toString().data()); - - const MemoryBlock* block = request->GetBody(); - if (block && block->getSize() > 0) { - std::vector mqvec; - MQDecoder::decodes(block, mqvec); - if (mqvec.size() == 0) { - LOG_ERROR("checkTransactionState decodes MQMessageExt fail, request:%s", requestHeader->toString().data()); - return nullptr; - } - - MQMessageExt& messageExt = mqvec[0]; - string transactionId = messageExt.getProperty(MQMessage::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX); - if (transactionId != "") { - messageExt.setTransactionId(transactionId); - } - - m_mqClientFactory->checkTransactionState(addr, messageExt, *requestHeader); - } else { - LOG_ERROR("checkTransactionState getbody null or size 0, request Header:%s", requestHeader->toString().data()); - } - return nullptr; -} - -} // namespace rocketmq diff --git a/src/transport/ClientRemotingProcessor.h b/src/transport/ClientRemotingProcessor.h deleted file mode 100644 index c88b8bb4b..000000000 --- a/src/transport/ClientRemotingProcessor.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -* 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 __CLIENTREMOTINGPROCESSOR_H__ -#define __CLIENTREMOTINGPROCESSOR_H__ - -#include "MQMessageQueue.h" -#include "MQProtos.h" -#include "RemotingCommand.h" - -namespace rocketmq { - -class MQClientFactory; -class ClientRemotingProcessor { - public: - ClientRemotingProcessor(MQClientFactory* mqClientFactory); - virtual ~ClientRemotingProcessor(); - - RemotingCommand* processRequest(const string& addr, RemotingCommand* request); - RemotingCommand* resetOffset(RemotingCommand* request); - RemotingCommand* getConsumerRunningInfo(const string& addr, RemotingCommand* request); - RemotingCommand* notifyConsumerIdsChanged(RemotingCommand* request); - RemotingCommand* checkTransactionState(const string& addr, RemotingCommand* request); - - private: - MQClientFactory* m_mqClientFactory; -}; - -class ResetOffsetBody { - public: - ResetOffsetBody() {} - virtual ~ResetOffsetBody() { m_offsetTable.clear(); } - void setOffsetTable(MQMessageQueue mq, int64 offset); - std::map getOffsetTable(); - static ResetOffsetBody* Decode(const MemoryBlock* mem); - - private: - std::map m_offsetTable; -}; - -class CheckTransactionStateBody { - public: - CheckTransactionStateBody() {} - virtual ~CheckTransactionStateBody() { m_offsetTable.clear(); } - void setOffsetTable(MQMessageQueue mq, int64 offset); - std::map getOffsetTable(); - static ResetOffsetBody* Decode(const MemoryBlock* mem); - - private: - std::map m_offsetTable; -}; -} - -#endif diff --git a/src/transport/EventLoop.cpp b/src/transport/EventLoop.cpp index 3d674056d..23ace973d 100644 --- a/src/transport/EventLoop.cpp +++ b/src/transport/EventLoop.cpp @@ -16,13 +16,16 @@ */ #include "EventLoop.h" -#if !defined(WIN32) && !defined(__APPLE__) -#include -#endif - #include +#ifndef WIN32 +#include +#else +#include +#endif + #include "Logging.h" +#include "SocketUtil.h" #include "UtilAll.h" namespace rocketmq { @@ -33,7 +36,7 @@ EventLoop* EventLoop::GetDefaultEventLoop() { } EventLoop::EventLoop(const struct event_config* config, bool run_immediately) - : m_eventBase(nullptr), m_loopThread(nullptr), _is_running(false) { + : m_eventBase(nullptr), m_loopThread("EventLoop"), _is_running(false) { // tell libevent support multi-threads #ifdef WIN32 evthread_use_windows_threads(); @@ -48,13 +51,15 @@ EventLoop::EventLoop(const struct event_config* config, bool run_immediately) } if (m_eventBase == nullptr) { - // failure... + // FIXME: failure... LOG_ERROR("Failed to create event base!"); - return; + exit(-1); } evthread_make_base_notifiable(m_eventBase); + m_loopThread.set_target(&EventLoop::runLoop, this); + if (run_immediately) { start(); } @@ -63,6 +68,8 @@ EventLoop::EventLoop(const struct event_config* config, bool run_immediately) EventLoop::~EventLoop() { stop(); + freeBufferEvent(); + if (m_eventBase != nullptr) { event_base_free(m_eventBase); m_eventBase = nullptr; @@ -70,60 +77,69 @@ EventLoop::~EventLoop() { } void EventLoop::start() { - if (m_loopThread == nullptr) { - // start event loop -#if !defined(WIN32) && !defined(__APPLE__) - string taskName = UtilAll::getProcessName(); - prctl(PR_SET_NAME, "EventLoop", 0, 0, 0); -#endif - m_loopThread = new std::thread(&EventLoop::runLoop, this); -#if !defined(WIN32) && !defined(__APPLE__) - prctl(PR_SET_NAME, taskName.c_str(), 0, 0, 0); -#endif + if (!_is_running) { + _is_running = true; + m_loopThread.start(); } } void EventLoop::stop() { - if (m_loopThread != nullptr /*&& m_loopThread.joinable()*/) { + if (_is_running) { _is_running = false; - m_loopThread->join(); - - delete m_loopThread; - m_loopThread = nullptr; + m_loopThread.join(); } } void EventLoop::runLoop() { - _is_running = true; - while (_is_running) { - int ret; - - ret = event_base_dispatch(m_eventBase); - // ret = event_base_loop(m_eventBase, EVLOOP_NONBLOCK); + freeBufferEvent(); + int ret = event_base_dispatch(m_eventBase); if (ret == 1) { // no event std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } + + freeBufferEvent(); } +#if ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP +void EventLoop::freeBufferEvent() { + while (true) { + auto event = _free_queue.pop_front(); + if (event == nullptr) { + break; + } + bufferevent_free(*event); + } +} + +void EventLoop::freeBufferEvent(struct bufferevent* event) { + _free_queue.push_back(event); +} +#else +void EventLoop::freeBufferEvent() {} +#endif // ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP + #define OPT_UNLOCK_CALLBACKS (BEV_OPT_DEFER_CALLBACKS | BEV_OPT_UNLOCK_CALLBACKS) BufferEvent* EventLoop::createBufferEvent(socket_t fd, int options) { struct bufferevent* event = bufferevent_socket_new(m_eventBase, fd, options); if (event == nullptr) { + auto ev_errno = EVUTIL_SOCKET_ERROR(); + LOG_ERROR_NEW("create bufferevent failed: {}", evutil_socket_error_to_string(ev_errno)); return nullptr; } bool unlock = (options & OPT_UNLOCK_CALLBACKS) == OPT_UNLOCK_CALLBACKS; - return new BufferEvent(event, unlock); + return new BufferEvent(event, unlock, this); } -BufferEvent::BufferEvent(struct bufferevent* event, bool unlockCallbacks) - : m_bufferEvent(event), +BufferEvent::BufferEvent(struct bufferevent* event, bool unlockCallbacks, EventLoop* loop) + : m_eventLoop(loop), + m_bufferEvent(event), m_unlockCallbacks(unlockCallbacks), m_readCallback(nullptr), m_writeCallback(nullptr), @@ -138,8 +154,11 @@ BufferEvent::BufferEvent(struct bufferevent* event, bool unlockCallbacks) BufferEvent::~BufferEvent() { if (m_bufferEvent != nullptr) { - // free function will set all callbacks to NULL first. +#if ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP + m_eventLoop->freeBufferEvent(m_bufferEvent); +#else bufferevent_free(m_bufferEvent); +#endif // ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP m_bufferEvent = nullptr; } } @@ -171,16 +190,18 @@ void BufferEvent::setCallback(BufferEventDataCallback readCallback, void BufferEvent::read_callback(struct bufferevent* bev, void* ctx) { auto event = static_cast(ctx); - if (event->m_unlockCallbacks) + if (event->m_unlockCallbacks) { bufferevent_lock(event->m_bufferEvent); + } BufferEventDataCallback callback = event->m_readCallback; std::shared_ptr transport = event->m_callbackTransport.lock(); - if (event->m_unlockCallbacks) + if (event->m_unlockCallbacks) { bufferevent_unlock(event->m_bufferEvent); + } - if (callback) { + if (callback != nullptr) { callback(event, transport.get()); } } @@ -188,16 +209,18 @@ void BufferEvent::read_callback(struct bufferevent* bev, void* ctx) { void BufferEvent::write_callback(struct bufferevent* bev, void* ctx) { auto event = static_cast(ctx); - if (event->m_unlockCallbacks) + if (event->m_unlockCallbacks) { bufferevent_lock(event->m_bufferEvent); + } BufferEventDataCallback callback = event->m_writeCallback; std::shared_ptr transport = event->m_callbackTransport.lock(); - if (event->m_unlockCallbacks) + if (event->m_unlockCallbacks) { bufferevent_unlock(event->m_bufferEvent); + } - if (callback) { + if (callback != nullptr) { callback(event, transport.get()); } } @@ -208,32 +231,48 @@ static std::string buildPeerAddrPort(socket_t fd) { getpeername(fd, (struct sockaddr*)&addr, &len); - LOG_DEBUG("socket: %d, addr: %s, port: %d", fd, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); - std::string addrPort(inet_ntoa(addr.sin_addr)); - addrPort.append(":"); - addrPort.append(UtilAll::to_string(ntohs(addr.sin_port))); + std::string addrPort = socketAddress2IPPort((struct sockaddr*)&addr); + LOG_DEBUG("socket: %d, addr: %s", fd, addrPort); return addrPort; } +int BufferEvent::connect(const struct sockaddr* addr, int socklen) { + m_peerAddrPort = socketAddress2IPPort(addr); + return bufferevent_socket_connect(m_bufferEvent, (struct sockaddr*)addr, socklen); +} + +int BufferEvent::close() { + bufferevent_lock(m_bufferEvent); + auto fd = bufferevent_getfd(m_bufferEvent); + int ret = -1; + if (fd >= 0) { + ret = evutil_closesocket(fd); + } + bufferevent_unlock(m_bufferEvent); + return ret; +} + void BufferEvent::event_callback(struct bufferevent* bev, short what, void* ctx) { auto event = static_cast(ctx); - if (what & BEV_EVENT_CONNECTED) { - socket_t fd = event->getfd(); - event->m_peerAddrPort = buildPeerAddrPort(fd); - } + // if (what & BEV_EVENT_CONNECTED) { + // socket_t fd = event->getfd(); + // event->m_peerAddrPort = buildPeerAddrPort(fd); + // } - if (event->m_unlockCallbacks) + if (event->m_unlockCallbacks) { bufferevent_lock(event->m_bufferEvent); + } BufferEventEventCallback callback = event->m_eventCallback; std::shared_ptr transport = event->m_callbackTransport.lock(); - if (event->m_unlockCallbacks) + if (event->m_unlockCallbacks) { bufferevent_unlock(event->m_bufferEvent); + } - if (callback) { + if (callback != nullptr) { callback(event, what, transport.get()); } } diff --git a/src/transport/EventLoop.h b/src/transport/EventLoop.h index c974479f0..c6a2924de 100644 --- a/src/transport/EventLoop.h +++ b/src/transport/EventLoop.h @@ -17,13 +17,21 @@ #ifndef __EVENTLOOP_H__ #define __EVENTLOOP_H__ -#include -#include - #include #include #include +#include + +#ifndef ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP +#define ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP 1 +#endif // ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP + +#if ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP +#include "concurrent/concurrent_queue.hpp" +#endif // ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOPƒ + +#include "concurrent/thread.hpp" #include "noncopyable.h" using socket_t = evutil_socket_t; @@ -43,16 +51,28 @@ class EventLoop : public noncopyable { void start(); void stop(); + bool isRunning() { return _is_running; } + BufferEvent* createBufferEvent(socket_t fd, int options); private: void runLoop(); + void freeBufferEvent(); + +#if ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP + void freeBufferEvent(struct bufferevent* event); + friend BufferEvent; +#endif // ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP private: struct event_base* m_eventBase; - std::thread* m_loopThread; + thread m_loopThread; bool _is_running; // aotmic is unnecessary + +#if ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP + concurrent_queue _free_queue; +#endif // ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP }; class TcpTransport; @@ -61,6 +81,10 @@ using BufferEventDataCallback = void (*)(BufferEvent* event, TcpTransport* trans using BufferEventEventCallback = void (*)(BufferEvent* event, short what, TcpTransport* transport); class BufferEvent : public noncopyable { + private: + BufferEvent(struct bufferevent* event, bool unlockCallbacks, EventLoop* loop); + friend EventLoop; + public: virtual ~BufferEvent(); @@ -74,10 +98,10 @@ class BufferEvent : public noncopyable { } int enable(short event) { return bufferevent_enable(m_bufferEvent, event); } + int disable(short event) { return bufferevent_disable(m_bufferEvent, event); } - int connect(const struct sockaddr* addr, int socklen) { - return bufferevent_socket_connect(m_bufferEvent, (struct sockaddr*)addr, socklen); - } + int connect(const struct sockaddr* addr, int socklen); + int close(); int write(const void* data, size_t size) { return bufferevent_write(m_bufferEvent, data, size); } @@ -89,17 +113,15 @@ class BufferEvent : public noncopyable { socket_t getfd() const { return bufferevent_getfd(m_bufferEvent); } - std::string getPeerAddrPort() const { return m_peerAddrPort; } + const std::string& getPeerAddrPort() const { return m_peerAddrPort; } private: - BufferEvent(struct bufferevent* event, bool unlockCallbacks); - friend EventLoop; - static void read_callback(struct bufferevent* bev, void* ctx); static void write_callback(struct bufferevent* bev, void* ctx); static void event_callback(struct bufferevent* bev, short what, void* ctx); private: + EventLoop* m_eventLoop; struct bufferevent* m_bufferEvent; const bool m_unlockCallbacks; @@ -108,10 +130,10 @@ class BufferEvent : public noncopyable { BufferEventEventCallback m_eventCallback; std::weak_ptr m_callbackTransport; // avoid reference cycle - // cache properties + // cached properties std::string m_peerAddrPort; }; } // namespace rocketmq -#endif //__EVENTLOOP_H__ +#endif // __EVENTLOOP_H__ diff --git a/src/common/sync_http_client.h b/src/transport/RequestProcessor.h similarity index 71% rename from src/common/sync_http_client.h rename to src/transport/RequestProcessor.h index 983660595..68e76f346 100644 --- a/src/common/sync_http_client.h +++ b/src/transport/RequestProcessor.h @@ -14,16 +14,20 @@ * 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_ +#ifndef __REQUEST_PROCESSOR_H__ +#define __REQUEST_PROCESSOR_H__ -#include +#include "RemotingCommand.h" namespace rocketmq { -class Url; -extern bool SyncfetchNsAddr(const Url& url_s, std::string& body); +class RequestProcessor { + public: + virtual ~RequestProcessor() = default; -} // namespace ons + virtual RemotingCommand* processRequest(const std::string& addr, RemotingCommand* request) = 0; +}; -#endif // ROCKETMQ_CLIENT4CPP__SYNC_HTTP_CLIENT_H_ +} // namespace rocketmq + +#endif // __REQUEST_PROCESSOR_H__ diff --git a/src/transport/ResponseFuture.cpp b/src/transport/ResponseFuture.cpp index b0b261391..2bd723b44 100755 --- a/src/transport/ResponseFuture.cpp +++ b/src/transport/ResponseFuture.cpp @@ -16,167 +16,105 @@ */ #include "ResponseFuture.h" -#include - -#include "Logging.h" -#include "TcpRemotingClient.h" +#include "UtilAll.h" namespace rocketmq { -// eventLock(m_defaultEventLock); - if (!m_haveResponse) { - if (timeoutMillis <= 0) { - timeoutMillis = m_timeout; - } - if (m_defaultEvent.wait_for(eventLock, std::chrono::milliseconds(timeoutMillis)) == std::cv_status::timeout) { - LOG_WARN("waitResponse of code:%d with opaque:%d timeout", m_requestCode, m_opaque); - m_haveResponse = true; - } + m_countDownLatch(nullptr) { + if (nullptr == invokeCallback) { + m_countDownLatch.reset(new latch(1)); } - return m_pResponseCommand; } -bool ResponseFuture::setResponse(RemotingCommand* pResponseCommand) { - std::unique_lock eventLock(m_defaultEventLock); +ResponseFuture::~ResponseFuture() {} - if (m_haveResponse) { - return false; - } - - m_pResponseCommand = pResponseCommand; - m_haveResponse = true; - - if (!getAsyncFlag()) { - m_defaultEvent.notify_all(); +void ResponseFuture::releaseThreadCondition() { + if (m_countDownLatch != nullptr) { + m_countDownLatch->count_down(); } - - return true; } -const bool ResponseFuture::getAsyncFlag() { - return m_bAsync; +bool ResponseFuture::hasInvokeCallback() { + // if m_invokeCallback is set, this is an async future. + return m_invokeCallback != nullptr; } -bool ResponseFuture::isSendRequestOK() const { - return m_sendRequestOK; -} - -void ResponseFuture::setSendRequestOK(bool sendRequestOK) { - m_sendRequestOK = sendRequestOK; +InvokeCallback* ResponseFuture::releaseInvokeCallback() { + return m_invokeCallback.release(); } -int ResponseFuture::getOpaque() const { - return m_opaque; -} - -int ResponseFuture::getRequestCode() const { - return m_requestCode; +void ResponseFuture::executeInvokeCallback() noexcept { + if (m_invokeCallback != nullptr) { + m_invokeCallback->operationComplete(this); + } } -void ResponseFuture::invokeCompleteCallback() { - if (m_pCallbackWrap == nullptr) { - deleteAndZero(m_pResponseCommand); - return; - } else { - m_pCallbackWrap->operationComplete(this, true); +std::unique_ptr ResponseFuture::waitResponse(int timeoutMillis) { + if (m_countDownLatch != nullptr) { + if (timeoutMillis <= 0) { + timeoutMillis = m_timeoutMillis; + } + m_countDownLatch->wait(timeoutMillis, time_unit::milliseconds); } + return std::move(m_responseCommand); } -void ResponseFuture::invokeExceptionCallback() { - if (m_pCallbackWrap == nullptr) { - LOG_ERROR("m_pCallbackWrap is NULL, critical error"); - return; - } else { - // here no need retrySendTimes process because of it have timeout - LOG_ERROR("send msg, callback timeout, opaque:%d, sendTimes:%d, maxRetryTimes:%d", getOpaque(), getRetrySendTimes(), - getMaxRetrySendTimes()); - - m_pCallbackWrap->onException(); +void ResponseFuture::putResponse(std::unique_ptr responseCommand) { + m_responseCommand = std::move(responseCommand); + if (m_countDownLatch != nullptr) { + m_countDownLatch->count_down(); } } -bool ResponseFuture::isTimeOut() const { - int64 diff = UtilAll::currentTimeMillis() - m_beginTimestamp; - // m_timeout; +std::unique_ptr ResponseFuture::getResponseCommand() { + return std::move(m_responseCommand); } -int ResponseFuture::getMaxRetrySendTimes() const { - return m_maxRetrySendTimes; -} -int ResponseFuture::getRetrySendTimes() const { - return m_retrySendTimes; +void ResponseFuture::setResponseCommand(std::unique_ptr responseCommand) { + m_responseCommand = std::move(responseCommand); } -void ResponseFuture::setMaxRetrySendTimes(int maxRetryTimes) { - m_maxRetrySendTimes = maxRetryTimes; -} -void ResponseFuture::setRetrySendTimes(int retryTimes) { - m_retrySendTimes = retryTimes; +int64_t ResponseFuture::getBeginTimestamp() { + return m_beginTimestamp; } -void ResponseFuture::setBrokerAddr(const std::string& brokerAddr) { - m_brokerAddr = brokerAddr; +int64_t ResponseFuture::getTimeoutMillis() { + return m_timeoutMillis; } -std::string ResponseFuture::getBrokerAddr() const { - return m_brokerAddr; +bool ResponseFuture::isTimeout() const { + auto diff = UtilAll::currentTimeMillis() - m_beginTimestamp; + return diff > m_timeoutMillis; } -void ResponseFuture::setRequestCommand(const RemotingCommand& requestCommand) { - m_requestCommand = requestCommand; +int64_t ResponseFuture::leftTime() const { + auto diff = UtilAll::currentTimeMillis() - m_beginTimestamp; + auto left = m_timeoutMillis - diff; + return left < 0 ? 0 : left; } -const RemotingCommand& ResponseFuture::getRequestCommand() { - return m_requestCommand; + +bool ResponseFuture::isSendRequestOK() const { + return m_sendRequestOK; } -int64 ResponseFuture::leftTime() const { - int64 diff = UtilAll::currentTimeMillis() - m_beginTimestamp; - return m_timeout - diff; +void ResponseFuture::setSendRequestOK(bool sendRequestOK) { + m_sendRequestOK = sendRequestOK; } -RemotingCommand* ResponseFuture::getCommand() const { - return m_pResponseCommand; +int ResponseFuture::getOpaque() const { + return m_opaque; } -AsyncCallbackWrap* ResponseFuture::getAsyncCallbackWrap() { - return m_pCallbackWrap; +int ResponseFuture::getRequestCode() const { + return m_requestCode; } -// -#include +#include "concurrent/latch.hpp" -#include "AsyncCallbackWrap.h" +#include "InvokeCallback.h" #include "RemotingCommand.h" -#include "UtilAll.h" namespace rocketmq { -typedef enum AsyncCallbackStatus { - ASYNC_CALLBACK_STATUS_INIT = 0, - ASYNC_CALLBACK_STATUS_RESPONSE = 1, - ASYNC_CALLBACK_STATUS_TIMEOUT = 2 -} AsyncCallbAackStatus; - -class TcpRemotingClient; -// waitResponse(int timeoutMillis = 0); + void putResponse(std::unique_ptr responseCommand); + + // for async request + std::unique_ptr getResponseCommand(); + void setResponseCommand(std::unique_ptr responseCommand); + + int64_t getBeginTimestamp(); + int64_t getTimeoutMillis(); + bool isTimeout() const; + int64_t leftTime() const; bool isSendRequestOK() const; - void setSendRequestOK(bool sendRequestOK); + void setSendRequestOK(bool sendRequestOK = true); + int getRequestCode() const; int getOpaque() const; - // m_invokeCallback; - AsyncCallbackStatus m_asyncCallbackStatus; - std::mutex m_asyncCallbackLock; + std::unique_ptr m_responseCommand; - bool m_haveResponse; - std::mutex m_defaultEventLock; - std::condition_variable m_defaultEvent; - - int64 m_beginTimestamp; + int64_t m_beginTimestamp; bool m_sendRequestOK; - RemotingCommand* m_pResponseCommand; // m_countDownLatch; // use for synchronization rpc }; -// +#include +#include + +#include + +#ifndef WIN32 +#include +#include +#include +#endif + +#include "ByteOrder.h" +#include "MQClientException.h" + namespace rocketmq { -//sa_family == AF_INET) { + struct sockaddr_in* sin = (struct sockaddr_in*)addr; + std::ostringstream ipport; + ipport << socketAddress2String(addr) << ":" << ntohs(sin->sin_port); + return ipport.str(); + } else if (addr->sa_family == AF_INET6) { + // struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr; + throw std::runtime_error("don't support ipv6."); + } else { + throw std::runtime_error("don't support non-inet Address families."); + } +} - string ipport = tmp; - return ipport; +void socketAddress2IPPort(const struct sockaddr* addr, int& host, int& port) { + if (addr->sa_family == AF_INET) { + struct sockaddr_in* sin = (struct sockaddr_in*)addr; + host = ntohl(sin->sin_addr.s_addr); + port = ntohs(sin->sin_port); + } else if (addr->sa_family == AF_INET6) { + // struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr; + throw std::runtime_error("don't support ipv6."); + } else { + throw std::runtime_error("don't support non-inet Address families."); + } } -void socketAddress2IPPort(sockaddr addr, int& host, int& port) { - struct sockaddr_in sa; - memcpy(&sa, &addr, sizeof(sockaddr)); +/** + * converts an address from network format to presentation format (a.b.c.d) + */ +std::string socketAddress2String(const struct sockaddr* addr) { + if (NULL == addr) { + return std::string(); + } - host = ntohl(sa.sin_addr.s_addr); - port = ntohs(sa.sin_port); -} + char buf[128]; + const char* address = NULL; + + if (addr->sa_family == AF_INET) { + struct sockaddr_in* sin = (struct sockaddr_in*)addr; + address = evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf)); + } else if (addr->sa_family == AF_INET6) { + struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr; + address = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf)); + } -string socketAddress2String(sockaddr addr) { - sockaddr_in in; - memcpy(&in, &addr, sizeof(sockaddr)); + if (address != NULL) { + return address; + } - return inet_ntoa(in.sin_addr); + return std::string(); } -string getHostName(sockaddr addr) { - sockaddr_in in; - memcpy(&in, &addr, sizeof(sockaddr)); +/** + * get the hostname of address + */ +std::string getHostName(const struct sockaddr* addr) { + if (NULL == addr) { + return std::string(); + } - struct hostent* remoteHost = gethostbyaddr((char*)&(in.sin_addr), 4, AF_INET); - char** alias = remoteHost->h_aliases; - if (*alias != 0) { - return *alias; - } else { - return inet_ntoa(in.sin_addr); + struct hostent* host = NULL; + if (addr->sa_family == AF_INET) { + struct sockaddr_in* sin = (struct sockaddr_in*)addr; + host = ::gethostbyaddr((char*)&sin->sin_addr, sizeof(sin->sin_addr), AF_INET); + } else if (addr->sa_family == AF_INET6) { + struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr; + host = ::gethostbyaddr((char*)&sin6->sin6_addr, sizeof(sin6->sin6_addr), AF_INET6); + } + + if (host != NULL) { + char** alias = host->h_aliases; + if (*alias != NULL) { + return *alias; + } } + + return socketAddress2String(addr); } -uint64 swapll(uint64 v) { -#ifdef ENDIANMODE_BIG - return v; -#else - uint64 ret = ((v << 56) | ((v & 0xff00) << 40) | ((v & 0xff0000) << 24) | ((v & 0xff000000) << 8) | - ((v >> 8) & 0xff000000) | ((v >> 24) & 0xff0000) | ((v >> 40) & 0xff00) | (v >> 56)); +std::string lookupNameServers(const std::string& hostname) { + if (hostname.empty()) { + return "127.0.0.1"; + } + + std::string ip; - return ret; -#endif + struct evutil_addrinfo hints; + struct evutil_addrinfo* answer = NULL; + + /* Build the hints to tell getaddrinfo how to act. */ + memset(&hints, 0, sizeof(hints)); + // hints.ai_family = AF_UNSPEC; /* v4 or v6 is fine. */ + hints.ai_family = AF_INET; /* v4 only. */ + hints.ai_socktype = SOCK_STREAM; /* We want stream socket*/ + hints.ai_protocol = IPPROTO_TCP; /* We want a TCP socket */ + hints.ai_flags = EVUTIL_AI_ADDRCONFIG; /* Only return addresses we can use. */ + + // Look up the hostname. + int err = evutil_getaddrinfo(hostname.c_str(), NULL, &hints, &answer); + if (err != 0) { + std::string info = "Failed to resolve host name(" + hostname + "): " + evutil_gai_strerror(err); + THROW_MQEXCEPTION(UnknownHostException, info, -1); + } + + for (struct evutil_addrinfo* addressInfo = answer; addressInfo != NULL; addressInfo = addressInfo->ai_next) { + ip = socketAddress2String(addressInfo->ai_addr); + if (!ip.empty()) { + break; + } + } + + evutil_freeaddrinfo(answer); + + return ip; } -uint64 h2nll(uint64 v) { - return swapll(v); +uint64_t h2nll(uint64_t v) { + return ByteOrder::swapIfLittleEndian(v); } -uint64 n2hll(uint64 v) { - return swapll(v); +uint64_t n2hll(uint64_t v) { + return ByteOrder::swapIfLittleEndian(v); } -} // +#include +#include + +#ifndef WIN32 +#include +#else #include -#include #pragma comment(lib, "ws2_32.lib") -#else -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #endif -#include "UtilAll.h" - namespace rocketmq { -// -#if !defined(WIN32) && !defined(__APPLE__) -#include -#endif #include "Logging.h" #include "MemoryOutputStream.h" -#include "TopAddressing.h" #include "UtilAll.h" namespace rocketmq { -//interrupt(); - m_timerServiceThread->join(); - removeAllTimerCallback(); + m_timeoutExecutor.shutdown(); { - std::lock_guard lock(m_tcpTableLock); - for (const auto& trans : m_tcpTable) { + std::lock_guard lock(m_transportTableMutex); + for (const auto& trans : m_transportTable) { trans.second->disconnect(trans.first); } - m_tcpTable.clear(); + m_transportTable.clear(); } - m_handleService.stop(); - m_handleThreadPool.join_all(); + m_handleExecutor.shutdown(); - m_dispatchService.stop(); - m_dispatchThreadPool.join_all(); + m_dispatchExecutor.shutdown(); { - std::lock_guard lock(m_futureTableLock); + std::lock_guard lock(m_futureTableMutex); for (const auto& future : m_futureTable) { - if (future.second) { - if (!future.second->getAsyncFlag()) { - future.second->releaseThreadCondition(); - } + if (future.second != nullptr) { + future.second->executeInvokeCallback(); } } + m_futureTable.clear(); } - LOG_ERROR("TcpRemotingClient::stopAllTcpTransportThread End, m_tcpTable:%lu", m_tcpTable.size()); + LOG_INFO_NEW("TcpRemotingClient::shutdown End, m_transportTable:{}", m_transportTable.size()); +} + +void TcpRemotingClient::registerRPCHook(std::shared_ptr rpcHook) { + if (rpcHook != nullptr) { + for (auto& hook : m_rpcHooks) { + if (hook == rpcHook) { + return; + } + } + + m_rpcHooks.push_back(rpcHook); + } } -void TcpRemotingClient::updateNameServerAddressList(const string& addrs) { - LOG_INFO("updateNameServerAddressList: [%s]", addrs.c_str()); +void TcpRemotingClient::updateNameServerAddressList(const std::string& addrs) { + LOG_INFO_NEW("updateNameServerAddressList: [{}]", addrs); if (addrs.empty()) { return; } - std::unique_lock lock(m_namesrvLock, std::try_to_lock); - if (!lock.owns_lock()) { - if (!lock.try_lock_for(std::chrono::seconds(10))) { - LOG_ERROR("updateNameServerAddressList get timed_mutex timeout"); - return; - } + if (!UtilAll::try_lock_for(m_namesrvLock, 1000 * 10)) { + LOG_ERROR_NEW("updateNameServerAddressList get timed_mutex timeout"); + return; } + std::lock_guard lock(m_namesrvLock, std::adopt_lock); - // clear first; + // clear first m_namesrvAddrList.clear(); - vector out; + std::vector out; UtilAll::Split(out, addrs, ";"); - for (auto addr : out) { + for (auto& addr : out) { UtilAll::Trim(addr); - string hostName; + std::string hostName; short portNumber; if (UtilAll::SplitURL(addr, hostName, portNumber)) { - LOG_INFO("update Namesrv:%s", addr.c_str()); + LOG_INFO_NEW("update Namesrv:{}", addr); m_namesrvAddrList.push_back(addr); } else { - LOG_INFO("This may be invalid namer server: [%s]", addr.c_str()); + LOG_INFO_NEW("This may be invalid namer server: [{}]", addr); } } - out.clear(); } -bool TcpRemotingClient::invokeHeartBeat(const string& addr, RemotingCommand& request, int timeoutMillis) { - std::shared_ptr pTcp = GetTransport(addr, true); - if (pTcp != nullptr) { - int code = request.getCode(); - int opaque = request.getOpaque(); +void TcpRemotingClient::scanResponseTablePeriodically() { + try { + scanResponseTable(); + } catch (std::exception& e) { + LOG_ERROR_NEW("scanResponseTable exception: {}", e.what()); + } + + // next round + m_timeoutExecutor.schedule(std::bind(&TcpRemotingClient::scanResponseTablePeriodically, this), 1000, + time_unit::milliseconds); +} - std::shared_ptr responseFuture(new ResponseFuture(code, opaque, this, timeoutMillis)); - addResponseFuture(opaque, responseFuture); +void TcpRemotingClient::scanResponseTable() { + std::vector> rfList; - if (SendCommand(pTcp, request)) { - responseFuture->setSendRequestOK(true); - unique_ptr pRsp(responseFuture->waitResponse()); - if (pRsp == nullptr) { - LOG_ERROR("wait response timeout of heartbeat, so closeTransport of addr:%s", addr.c_str()); - // avoid responseFuture leak; - findAndDeleteResponseFuture(opaque); - CloseTransport(addr, pTcp); - return false; - } else if (pRsp->getCode() == SUCCESS_VALUE) { - return true; + { + std::lock_guard lock(m_futureTableMutex); + auto now = UtilAll::currentTimeMillis(); + for (auto it = m_futureTable.begin(); it != m_futureTable.end();) { + auto& rep = it->second; // NOTE: rep is a reference + if (rep->getBeginTimestamp() + rep->getTimeoutMillis() + 1000 <= now) { + LOG_WARN_NEW("remove timeout request, code:{}, opaque:{}", rep->getRequestCode(), rep->getOpaque()); + rfList.push_back(rep); + it = m_futureTable.erase(it); } else { - LOG_WARN("get error response:%d of heartbeat to addr:%s", pRsp->getCode(), addr.c_str()); - return false; + ++it; + } + } + } + + for (auto rf : rfList) { + if (rf->hasInvokeCallback()) { + m_handleExecutor.submit(std::bind(&ResponseFuture::executeInvokeCallback, rf)); + } + } +} + +std::unique_ptr TcpRemotingClient::invokeSync(const std::string& addr, + RemotingCommand& request, + int timeoutMillis) throw(RemotingException) { + auto beginStartTime = UtilAll::currentTimeMillis(); + TcpTransportPtr channel = GetTransport(addr, true); + if (channel != nullptr) { + try { + doBeforeRpcHooks(addr, request, true); + auto costTime = UtilAll::currentTimeMillis() - beginStartTime; + if (timeoutMillis <= 0 || timeoutMillis < costTime) { + THROW_MQEXCEPTION(RemotingTimeoutException, "invokeSync call timeout", -1); } + std::unique_ptr response(invokeSyncImpl(channel, request, timeoutMillis)); + doAfterRpcHooks(addr, request, response.get(), false); + return response; + } catch (const RemotingSendRequestException& e) { + LOG_WARN_NEW("invokeSync: send request exception, so close the channel[{}]", channel->getPeerAddrAndPort()); + CloseTransport(addr, channel); + throw e; + } catch (const RemotingTimeoutException& e) { + int code = request.getCode(); + if (code != GET_CONSUMER_LIST_BY_GROUP) { + CloseTransport(addr, channel); + LOG_WARN_NEW("invokeSync: close socket because of timeout, {}ms, {}", timeoutMillis, + channel->getPeerAddrAndPort()); + } + LOG_WARN_NEW("invokeSync: wait response timeout exception, the channel[{}]", channel->getPeerAddrAndPort()); + throw e; + } + } else { + THROW_MQEXCEPTION(RemotingConnectException, "connect to <" + addr + "> failed", -1); + } +} + +std::unique_ptr TcpRemotingClient::invokeSyncImpl( + TcpTransportPtr channel, + RemotingCommand& request, + int64_t timeoutMillis) throw(RemotingTimeoutException, RemotingSendRequestException) { + int code = request.getCode(); + int opaque = request.getOpaque(); + + std::shared_ptr responseFuture(new ResponseFuture(code, opaque, timeoutMillis)); + addResponseFuture(opaque, responseFuture); + + if (SendCommand(channel, request)) { + responseFuture->setSendRequestOK(true); + } else { + responseFuture->setSendRequestOK(false); + + findAndDeleteResponseFuture(opaque); + responseFuture->putResponse(nullptr); + + LOG_WARN_NEW("send a request command to channel <{}> failed.", channel->getPeerAddrAndPort()); + } + + std::unique_ptr response(responseFuture->waitResponse()); + if (nullptr == response) { + if (responseFuture->isSendRequestOK()) { + THROW_MQEXCEPTION(RemotingTimeoutException, + "wait response on the addr <" + channel->getPeerAddrAndPort() + "> timeout", -1); } else { - // avoid responseFuture leak; - findAndDeleteResponseFuture(opaque); - CloseTransport(addr, pTcp); + THROW_MQEXCEPTION(RemotingSendRequestException, "send request to <" + channel->getPeerAddrAndPort() + "> failed", + -1); + } + } + + return response; +} + +void TcpRemotingClient::invokeAsync(const std::string& addr, + RemotingCommand& request, + InvokeCallback* invokeCallback, + int64_t timeoutMillis) throw(RemotingException) { + auto beginStartTime = UtilAll::currentTimeMillis(); + TcpTransportPtr channel = GetTransport(addr, true); + if (channel != nullptr) { + try { + doBeforeRpcHooks(addr, request, true); + auto costTime = UtilAll::currentTimeMillis() - beginStartTime; + if (timeoutMillis <= 0 || timeoutMillis < costTime) { + THROW_MQEXCEPTION(RemotingTooMuchRequestException, "invokeAsync call timeout", -1); + } + invokeAsyncImpl(channel, request, timeoutMillis, invokeCallback); + } catch (const RemotingSendRequestException& e) { + LOG_WARN_NEW("invokeAsync: send request exception, so close the channel[{}]", channel->getPeerAddrAndPort()); + CloseTransport(addr, channel); + throw e; } + } else { + THROW_MQEXCEPTION(RemotingConnectException, "connect to <" + addr + "> failed", -1); } - return false; } -RemotingCommand* TcpRemotingClient::invokeSync(const string& addr, RemotingCommand& request, int timeoutMillis) { - LOG_DEBUG("InvokeSync:", addr.c_str()); - std::shared_ptr pTcp = GetTransport(addr, true); - if (pTcp != nullptr) { - int code = request.getCode(); - int opaque = request.getOpaque(); +void TcpRemotingClient::invokeAsyncImpl(TcpTransportPtr channel, + RemotingCommand& request, + int64_t timeoutMillis, + InvokeCallback* invokeCallback) throw(RemotingSendRequestException) { + int code = request.getCode(); + int opaque = request.getOpaque(); - std::shared_ptr responseFuture(new ResponseFuture(code, opaque, this, timeoutMillis)); - addResponseFuture(opaque, responseFuture); + // delete in callback + std::shared_ptr responseFuture(new ResponseFuture(code, opaque, timeoutMillis, invokeCallback)); + addResponseFuture(opaque, responseFuture); - if (SendCommand(pTcp, request)) { + try { + if (SendCommand(channel, request)) { responseFuture->setSendRequestOK(true); - RemotingCommand* pRsp = responseFuture->waitResponse(); - if (pRsp == nullptr) { - if (code != GET_CONSUMER_LIST_BY_GROUP) { - LOG_WARN("wait response timeout or get NULL response of code:%d, so closeTransport of addr:%s", code, - addr.c_str()); - CloseTransport(addr, pTcp); + } else { + // requestFail + responseFuture = findAndDeleteResponseFuture(opaque); + if (responseFuture != nullptr) { + responseFuture->setSendRequestOK(false); + responseFuture->putResponse(nullptr); + if (responseFuture->hasInvokeCallback()) { + m_handleExecutor.submit(std::bind(&ResponseFuture::executeInvokeCallback, responseFuture)); } - // avoid responseFuture leak; - findAndDeleteResponseFuture(opaque); - return nullptr; - } else { - return pRsp; } - } else { - // avoid responseFuture leak; - findAndDeleteResponseFuture(opaque); - CloseTransport(addr, pTcp); + + LOG_WARN_NEW("send a request command to channel <{}> failed.", channel->getPeerAddrAndPort()); } + } catch (const std::exception& e) { + LOG_WARN_NEW("send a request command to channel <{}> Exception.\n{}", channel->getPeerAddrAndPort(), e.what()); + THROW_MQEXCEPTION(RemotingSendRequestException, "send request to <" + channel->getPeerAddrAndPort() + "> failed", + -1); } - LOG_DEBUG("InvokeSync [%s] Failed: Cannot Get Transport.", addr.c_str()); - return nullptr; } -bool TcpRemotingClient::invokeAsync(const string& addr, - RemotingCommand& request, - AsyncCallbackWrap* callback, - int64 timeoutMillis, - int maxRetrySendTimes, - int retrySendTimes) { - std::shared_ptr pTcp = GetTransport(addr, true); - if (pTcp != nullptr) { - int code = request.getCode(); - int opaque = request.getOpaque(); - - // delete in callback - std::shared_ptr responseFuture( - new ResponseFuture(code, opaque, this, timeoutMillis, true, callback)); - responseFuture->setMaxRetrySendTimes(maxRetrySendTimes); - responseFuture->setRetrySendTimes(retrySendTimes); - responseFuture->setBrokerAddr(addr); - responseFuture->setRequestCommand(request); - addResponseFuture(opaque, responseFuture); - - // timeout monitor - boost::asio::deadline_timer* t = - new boost::asio::deadline_timer(m_timerService, boost::posix_time::milliseconds(timeoutMillis)); - addTimerCallback(t, opaque); - t->async_wait( - boost::bind(&TcpRemotingClient::handleAsyncRequestTimeout, this, boost::asio::placeholders::error, opaque)); - - // even if send failed, asyncTimerThread will trigger next pull request or report send msg failed - if (SendCommand(pTcp, request)) { - LOG_DEBUG("invokeAsync success, addr:%s, code:%d, opaque:%d", addr.c_str(), code, opaque); - responseFuture->setSendRequestOK(true); +void TcpRemotingClient::invokeOneway(const std::string& addr, RemotingCommand& request) throw(RemotingException) { + TcpTransportPtr channel = GetTransport(addr, true); + if (channel != nullptr) { + try { + doBeforeRpcHooks(addr, request, true); + invokeOnewayImpl(channel, request); + } catch (const RemotingSendRequestException& e) { + LOG_WARN_NEW("invokeOneway: send request exception, so close the channel[{}]", channel->getPeerAddrAndPort()); + CloseTransport(addr, channel); + throw e; } - return true; + } else { + THROW_MQEXCEPTION(RemotingConnectException, "connect to <" + addr + "> failed", -1); } +} - LOG_ERROR("invokeAsync failed of addr:%s", addr.c_str()); - return false; +void TcpRemotingClient::invokeOnewayImpl(TcpTransportPtr channel, + RemotingCommand& request) throw(RemotingSendRequestException) { + request.markOnewayRPC(); + try { + if (!SendCommand(channel, request)) { + LOG_WARN_NEW("send a request command to channel <{}> failed.", channel->getPeerAddrAndPort()); + } + } catch (const std::exception& e) { + LOG_WARN_NEW("send a request command to channel <{}> Exception.\n{}", channel->getPeerAddrAndPort(), e.what()); + THROW_MQEXCEPTION(RemotingSendRequestException, "send request to <" + channel->getPeerAddrAndPort() + "> failed", + -1); + } } -void TcpRemotingClient::invokeOneway(const string& addr, RemotingCommand& request) { - // pTcp = GetTransport(addr, true); - if (pTcp != nullptr) { - request.markOnewayRPC(); - if (SendCommand(pTcp, request)) { - LOG_DEBUG("invokeOneway success. addr:%s, code:%d", addr.c_str(), request.getCode()); - } else { - LOG_WARN("invokeOneway failed. addr:%s, code:%d", addr.c_str(), request.getCode()); +void TcpRemotingClient::doBeforeRpcHooks(const std::string& addr, RemotingCommand& request, bool toSent) { + if (m_rpcHooks.size() > 0) { + for (auto& rpcHook : m_rpcHooks) { + rpcHook->doBeforeRequest(addr, request, toSent); + } + } +} + +void TcpRemotingClient::doAfterRpcHooks(const std::string& addr, + RemotingCommand& request, + RemotingCommand* response, + bool toSent) { + if (m_rpcHooks.size() > 0) { + for (auto& rpcHook : m_rpcHooks) { + rpcHook->doAfterResponse(addr, request, response, toSent); } - } else { - LOG_WARN("invokeOneway failed: NULL transport. addr:%s, code:%d", addr.c_str(), request.getCode()); } } -std::shared_ptr TcpRemotingClient::GetTransport(const string& addr, bool needResponse) { +TcpTransportPtr TcpRemotingClient::GetTransport(const std::string& addr, bool needResponse) { if (addr.empty()) { - LOG_DEBUG("GetTransport of NameServer"); + LOG_DEBUG_NEW("GetTransport of NameServer"); return CreateNameServerTransport(needResponse); } return CreateTransport(addr, needResponse); } -std::shared_ptr TcpRemotingClient::CreateTransport(const string& addr, bool needResponse) { - std::shared_ptr tts; +TcpTransportPtr TcpRemotingClient::CreateTransport(const std::string& addr, bool needResponse) { + TcpTransportPtr channel; { - // try get m_tcpLock util m_tcpTransportTryLockTimeout to avoid blocking - // long time, if could not get m_tcpLock, return NULL - std::unique_lock lock(m_tcpTableLock, std::try_to_lock); - if (!lock.owns_lock()) { - if (!lock.try_lock_for(std::chrono::seconds(m_tcpTransportTryLockTimeout))) { - LOG_ERROR("GetTransport of:%s get timed_mutex timeout", addr.c_str()); - std::shared_ptr pTcp; - return pTcp; - } + // try get m_tcpLock util m_tcpTransportTryLockTimeout to avoid blocking long time, + // if could not get m_transportTableMutex, return NULL + if (!UtilAll::try_lock_for(m_transportTableMutex, 1000 * m_tcpTransportTryLockTimeout)) { + LOG_ERROR_NEW("GetTransport of:{} get timed_mutex timeout", addr); + return TcpTransportPtr(); } + std::lock_guard lock(m_transportTableMutex, std::adopt_lock); // check for reuse - if (m_tcpTable.find(addr) != m_tcpTable.end()) { - std::shared_ptr tcp = m_tcpTable[addr]; - - if (tcp) { - TcpConnectStatus connectStatus = tcp->getTcpConnectStatus(); - if (connectStatus == TCP_CONNECT_STATUS_SUCCESS) { - return tcp; - } else if (connectStatus == TCP_CONNECT_STATUS_WAIT) { - std::shared_ptr pTcp; - return pTcp; - } else if (connectStatus == TCP_CONNECT_STATUS_FAILED) { - LOG_ERROR("tcpTransport with server disconnected, erase server:%s", addr.c_str()); - tcp->disconnect(addr); // avoid coredump when connection with broker was broken - m_tcpTable.erase(addr); - } else { - LOG_ERROR("go to fault state, erase:%s from tcpMap, and reconnect it", addr.c_str()); - m_tcpTable.erase(addr); + auto iter = m_transportTable.find(addr); + if (iter != m_transportTable.end()) { + channel = iter->second; + if (channel != nullptr) { + TcpConnectStatus connectStatus = channel->getTcpConnectStatus(); + switch (connectStatus) { + // case TCP_CONNECT_STATUS_CREATED: + case TCP_CONNECT_STATUS_CONNECTED: + return channel; + case TCP_CONNECT_STATUS_CONNECTING: + // wait server answer, return dummy + return TcpTransportPtr(); + case TCP_CONNECT_STATUS_FAILED: + LOG_ERROR_NEW("tcpTransport with server disconnected, erase server:{}", addr); + channel->disconnect(addr); // avoid coredump when connection with broker was broken + m_transportTable.erase(addr); + break; + default: // TCP_CONNECT_STATUS_CLOSED + LOG_ERROR_NEW("go to CLOSED state, erase:{} from transportTable, and reconnect it", addr); + m_transportTable.erase(addr); + break; } } } - //connect(addr, 0); // use non-block - if (connectStatus != TCP_CONNECT_STATUS_WAIT) { - LOG_WARN("can not connect to:%s", addr.c_str()); - tts->disconnect(addr); - std::shared_ptr pTcp; - return pTcp; + // create new transport, then connect server + channel = TcpTransport::CreateTransport(this, callback); + TcpConnectStatus connectStatus = channel->connect(addr, 0); // use non-block + if (connectStatus != TCP_CONNECT_STATUS_CONNECTING) { + LOG_WARN_NEW("can not connect to:{}", addr); + channel->disconnect(addr); + return TcpTransportPtr(); } else { // even if connecting failed finally, this server transport will be erased by next CreateTransport - m_tcpTable[addr] = tts; + m_transportTable[addr] = channel; } } - TcpConnectStatus connectStatus = tts->waitTcpConnectEvent(static_cast(m_tcpConnectTimeout)); - if (connectStatus != TCP_CONNECT_STATUS_SUCCESS) { - LOG_WARN("can not connect to server:%s", addr.c_str()); - tts->disconnect(addr); - std::shared_ptr pTcp; - return pTcp; + // waiting... + TcpConnectStatus connectStatus = channel->waitTcpConnectEvent(static_cast(m_tcpConnectTimeout)); + if (connectStatus != TCP_CONNECT_STATUS_CONNECTED) { + LOG_WARN_NEW("can not connect to server:{}", addr); + channel->disconnect(addr); + return TcpTransportPtr(); } else { - LOG_INFO("connect server with addr:%s success", addr.c_str()); - return tts; + LOG_INFO_NEW("connect server with addr:{} success", addr); + return channel; } } -std::shared_ptr TcpRemotingClient::CreateNameServerTransport(bool needResponse) { +TcpTransportPtr TcpRemotingClient::CreateNameServerTransport(bool needResponse) { // m_namesrvLock was added to avoid operation of nameServer was blocked by // m_tcpLock, it was used by single Thread mostly, so no performance impact // try get m_tcpLock until m_tcpTransportTryLockTimeout to avoid blocking long // time, if could not get m_namesrvlock, return NULL - LOG_DEBUG("--CreateNameserverTransport--"); - std::unique_lock lock(m_namesrvLock, std::try_to_lock); - if (!lock.owns_lock()) { - if (!lock.try_lock_for(std::chrono::seconds(m_tcpTransportTryLockTimeout))) { - LOG_ERROR("CreateNameserverTransport get timed_mutex timeout"); - std::shared_ptr pTcp; - return pTcp; - } + LOG_DEBUG_NEW("--CreateNameserverTransport--"); + if (!UtilAll::try_lock_for(m_namesrvLock, 1000 * m_tcpTransportTryLockTimeout)) { + LOG_ERROR_NEW("CreateNameserverTransport get timed_mutex timeout"); + return TcpTransportPtr(); } + std::lock_guard lock(m_namesrvLock, std::adopt_lock); if (!m_namesrvAddrChoosed.empty()) { - std::shared_ptr pTcp = CreateTransport(m_namesrvAddrChoosed, true); - if (pTcp) - return pTcp; - else + TcpTransportPtr channel = CreateTransport(m_namesrvAddrChoosed, true); + if (channel != nullptr) { + return channel; + } else { m_namesrvAddrChoosed.clear(); + } } for (unsigned i = 0; i < m_namesrvAddrList.size(); i++) { unsigned int index = m_namesrvIndex++ % m_namesrvAddrList.size(); - LOG_INFO("namesrvIndex is:%d, index:%d, namesrvaddrlist size:" SIZET_FMT "", m_namesrvIndex, index, - m_namesrvAddrList.size()); - std::shared_ptr pTcp = CreateTransport(m_namesrvAddrList[index], true); - if (pTcp) { + LOG_INFO_NEW("namesrvIndex is:{}, index:{}, namesrvaddrlist size:{}", m_namesrvIndex, index, + m_namesrvAddrList.size()); + TcpTransportPtr channel = CreateTransport(m_namesrvAddrList[index], true); + if (channel != nullptr) { m_namesrvAddrChoosed = m_namesrvAddrList[index]; - return pTcp; + return channel; } } - std::shared_ptr pTcp; - return pTcp; + return TcpTransportPtr(); } -bool TcpRemotingClient::CloseTransport(const string& addr, std::shared_ptr pTcp) { +bool TcpRemotingClient::CloseTransport(const std::string& addr, TcpTransportPtr channel) { if (addr.empty()) { - return CloseNameServerTransport(pTcp); + return CloseNameServerTransport(channel); } - std::unique_lock lock(m_tcpTableLock, std::try_to_lock); - if (!lock.owns_lock()) { - if (!lock.try_lock_for(std::chrono::seconds(m_tcpTransportTryLockTimeout))) { - LOG_ERROR("CloseTransport of:%s get timed_mutex timeout", addr.c_str()); - return false; - } + if (!UtilAll::try_lock_for(m_transportTableMutex, 1000 * m_tcpTransportTryLockTimeout)) { + LOG_ERROR_NEW("CloseTransport of:{} get timed_mutex timeout", addr); + return false; } + std::lock_guard lock(m_transportTableMutex, std::adopt_lock); - LOG_ERROR("CloseTransport of:%s", addr.c_str()); + LOG_ERROR_NEW("CloseTransport of:{}", addr); bool removeItemFromTable = true; - if (m_tcpTable.find(addr) != m_tcpTable.end()) { - if (m_tcpTable[addr]->getStartTime() != pTcp->getStartTime()) { - LOG_INFO("tcpTransport with addr:%s has been closed before, and has been created again, nothing to do", - addr.c_str()); + if (m_transportTable.find(addr) != m_transportTable.end()) { + if (m_transportTable[addr]->getStartTime() != channel->getStartTime()) { + LOG_INFO_NEW("tcpTransport with addr:{} has been closed before, and has been created again, nothing to do", addr); removeItemFromTable = false; } } else { - LOG_INFO("tcpTransport with addr:%s had been removed from tcpTable before", addr.c_str()); + LOG_INFO_NEW("tcpTransport with addr:{} had been removed from tcpTable before", addr); removeItemFromTable = false; } if (removeItemFromTable) { - LOG_WARN("closeTransport: disconnect:%s with state:%d", addr.c_str(), m_tcpTable[addr]->getTcpConnectStatus()); - if (m_tcpTable[addr]->getTcpConnectStatus() == TCP_CONNECT_STATUS_SUCCESS) - m_tcpTable[addr]->disconnect(addr); // avoid coredump when connection with server was broken - LOG_WARN("closeTransport: erase broker: %s", addr.c_str()); - m_tcpTable.erase(addr); + LOG_WARN_NEW("closeTransport: erase broker: {}", addr); + m_transportTable.erase(addr); + } + + LOG_WARN_NEW("closeTransport: disconnect:{} with state:{}", addr, channel->getTcpConnectStatus()); + if (channel->getTcpConnectStatus() != TCP_CONNECT_STATUS_CLOSED) { + channel->disconnect(addr); // avoid coredump when connection with server was broken } - LOG_ERROR("CloseTransport of:%s end", addr.c_str()); + LOG_ERROR_NEW("CloseTransport of:{} end", addr); return removeItemFromTable; } -bool TcpRemotingClient::CloseNameServerTransport(std::shared_ptr pTcp) { - std::unique_lock lock(m_namesrvLock, std::try_to_lock); - if (!lock.owns_lock()) { - if (!lock.try_lock_for(std::chrono::seconds(m_tcpTransportTryLockTimeout))) { - LOG_ERROR("CreateNameServerTransport get timed_mutex timeout"); - return false; - } +bool TcpRemotingClient::CloseNameServerTransport(TcpTransportPtr channel) { + if (!UtilAll::try_lock_for(m_namesrvLock, 1000 * m_tcpTransportTryLockTimeout)) { + LOG_ERROR_NEW("CloseNameServerTransport get timed_mutex timeout"); + return false; } + std::lock_guard lock(m_namesrvLock, std::adopt_lock); - string addr = m_namesrvAddrChoosed; + std::string addr = m_namesrvAddrChoosed; - bool removeItemFromTable = CloseTransport(addr, pTcp); + bool removeItemFromTable = CloseTransport(addr, channel); if (removeItemFromTable) { m_namesrvAddrChoosed.clear(); } @@ -446,128 +502,138 @@ bool TcpRemotingClient::CloseNameServerTransport(std::shared_ptr p return removeItemFromTable; } -bool TcpRemotingClient::SendCommand(std::shared_ptr pTts, RemotingCommand& msg) { - const MemoryBlock* pHead = msg.GetHead(); - const MemoryBlock* pBody = msg.GetBody(); - - unique_ptr buffer(new MemoryOutputStream(1024)); - if (pHead->getSize() > 0) { - buffer->write(pHead->getData(), static_cast(pHead->getSize())); - } - if (pBody->getSize() > 0) { - buffer->write(pBody->getData(), static_cast(pBody->getSize())); - } - - const char* pData = static_cast(buffer->getData()); - size_t len = buffer->getDataSize(); - return pTts->sendMessage(pData, len); +bool TcpRemotingClient::SendCommand(TcpTransportPtr channel, RemotingCommand& msg) { + MemoryBlockPtr3 package(msg.encode()); + return channel->sendMessage(package->getData(), package->getSize()); } -void TcpRemotingClient::static_messageReceived(void* context, const MemoryBlock& mem, const string& addr) { - auto* pTcpRemotingClient = reinterpret_cast(context); - if (pTcpRemotingClient) - pTcpRemotingClient->messageReceived(mem, addr); +void TcpRemotingClient::MessageReceived(void* context, MemoryBlockPtr3& mem, const std::string& addr) { + auto* client = reinterpret_cast(context); + if (client != nullptr) { + client->messageReceived(mem, addr); + } } -void TcpRemotingClient::messageReceived(const MemoryBlock& mem, const string& addr) { - m_dispatchService.post(boost::bind(&TcpRemotingClient::ProcessData, this, mem, addr)); +void TcpRemotingClient::messageReceived(MemoryBlockPtr3& mem, const std::string& addr) { + m_dispatchExecutor.submit( + std::bind(&TcpRemotingClient::processMessageReceived, this, MemoryBlockPtr2(std::move(mem)), addr)); } -void TcpRemotingClient::ProcessData(const MemoryBlock& mem, const string& addr) { - RemotingCommand* pRespondCmd = nullptr; +void TcpRemotingClient::processMessageReceived(MemoryBlockPtr2& mem, const std::string& addr) { + std::unique_ptr cmd; try { - pRespondCmd = RemotingCommand::Decode(mem); + cmd.reset(RemotingCommand::Decode(mem)); } catch (...) { - LOG_ERROR("processData error"); + LOG_ERROR_NEW("processMessageReceived error"); return; } - int opaque = pRespondCmd->getOpaque(); - - //isResponseType()) { - std::shared_ptr pFuture = findAndDeleteResponseFuture(opaque); - if (!pFuture) { - LOG_DEBUG("responseFuture was deleted by timeout of opaque:%d", opaque); - deleteAndZero(pRespondCmd); - return; - } - - LOG_DEBUG("find_response opaque:%d", opaque); - processResponseCommand(pRespondCmd, pFuture); + if (cmd->isResponseType()) { + processResponseCommand(std::move(cmd)); } else { - m_handleService.post(boost::bind(&TcpRemotingClient::processRequestCommand, this, pRespondCmd, addr)); - } -} - -void TcpRemotingClient::processResponseCommand(RemotingCommand* pCmd, std::shared_ptr pFuture) { - int code = pFuture->getRequestCode(); - pCmd->SetExtHeader(code); // set head, for response use - - int opaque = pCmd->getOpaque(); - LOG_DEBUG("processResponseCommand, code:%d, opaque:%d, maxRetryTimes:%d, retrySendTimes:%d", code, opaque, - pFuture->getMaxRetrySendTimes(), pFuture->getRetrySendTimes()); + class task_adaptor { + public: + task_adaptor(TcpRemotingClient* client, std::unique_ptr cmd, const std::string& addr) + : client_(client), cmd_(cmd.release()), addr_(addr) {} + task_adaptor(const task_adaptor& other) : client_(other.client_), cmd_(other.cmd_), addr_(other.addr_) { + // force move + const_cast(&other)->cmd_ = nullptr; + } + task_adaptor(task_adaptor&& other) : client_(other.client_), cmd_(other.cmd_), addr_(other.addr_) { + other.cmd_ = nullptr; + } + ~task_adaptor() { delete cmd_; } - if (!pFuture->setResponse(pCmd)) { - // this branch is unreachable normally. - LOG_WARN("response already timeout of opaque:%d", opaque); - deleteAndZero(pCmd); - return; - } + void operator()() { + std::unique_ptr requestCommand(cmd_); + cmd_ = nullptr; + client_->processRequestCommand(std::move(requestCommand), addr_); + } - if (pFuture->getAsyncFlag()) { - cancelTimerCallback(opaque); + private: + TcpRemotingClient* client_; + RemotingCommand* cmd_; + std::string addr_; + }; - m_handleService.post(boost::bind(&ResponseFuture::invokeCompleteCallback, pFuture)); + m_handleExecutor.submit(task_adaptor(this, std::move(cmd), addr)); } } -void TcpRemotingClient::handleAsyncRequestTimeout(const boost::system::error_code& e, int opaque) { - if (e == boost::asio::error::operation_aborted) { - LOG_DEBUG("handleAsyncRequestTimeout aborted opaque:%d, e_code:%d, msg:%s", opaque, e.value(), e.message().data()); - return; - } - - LOG_DEBUG("handleAsyncRequestTimeout opaque:%d, e_code:%d, msg:%s", opaque, e.value(), e.message().data()); - - std::shared_ptr pFuture(findAndDeleteResponseFuture(opaque)); - if (pFuture) { - LOG_ERROR("no response got for opaque:%d", opaque); - eraseTimerCallback(opaque); - if (pFuture->getAsyncCallbackWrap()) { - m_handleService.post(boost::bind(&ResponseFuture::invokeExceptionCallback, pFuture)); +void TcpRemotingClient::processResponseCommand(std::unique_ptr responseCommand) { + int opaque = responseCommand->getOpaque(); + std::shared_ptr responseFuture = findAndDeleteResponseFuture(opaque); + if (responseFuture != nullptr) { + int code = responseFuture->getRequestCode(); + LOG_DEBUG_NEW("processResponseCommand, opaque:{}, code:{}", opaque, code); + + if (responseFuture->hasInvokeCallback()) { + responseFuture->setResponseCommand(std::move(responseCommand)); + // bind shared_ptr can save object's life + m_handleExecutor.submit(std::bind(&ResponseFuture::executeInvokeCallback, responseFuture)); + } else { + responseFuture->putResponse(std::move(responseCommand)); } + } else { + LOG_DEBUG_NEW("responseFuture was deleted by timeout of opaque:{}", opaque); } } -void TcpRemotingClient::processRequestCommand(RemotingCommand* pCmd, const string& addr) { - unique_ptr pRequestCommand(pCmd); - int requestCode = pRequestCommand->getCode(); - if (m_requestTable.find(requestCode) == m_requestTable.end()) { - LOG_ERROR("can_not_find request:%d processor", requestCode); - } else { - unique_ptr pResponse(m_requestTable[requestCode]->processRequest(addr, pRequestCommand.get())); - if (!pRequestCommand->isOnewayRPC()) { - if (pResponse) { - pResponse->setOpaque(pRequestCommand->getOpaque()); - pResponse->markResponseType(); - pResponse->Encode(); - - invokeOneway(addr, *pResponse); +void TcpRemotingClient::processRequestCommand(std::unique_ptr requestCommand, + const std::string& addr) { + int requestCode = requestCommand->getCode(); + auto iter = m_processorTable.find(requestCode); + if (iter != m_processorTable.end()) { + try { + auto& processor = iter->second; + + doBeforeRpcHooks(addr, *requestCommand, false); + std::unique_ptr response(processor->processRequest(addr, requestCommand.get())); + doAfterRpcHooks(addr, *requestCommand, response.get(), true); + + if (!requestCommand->isOnewayRPC()) { + if (response != nullptr) { + response->setOpaque(requestCommand->getOpaque()); + response->markResponseType(); + + try { + TcpTransportPtr channel = GetTransport(addr, true); + if (channel != nullptr) { + if (!SendCommand(channel, *response)) { + LOG_WARN_NEW("send a response command to channel <{}> failed.", channel->getPeerAddrAndPort()); + } + } + } catch (std::exception& e) { + LOG_ERROR_NEW("process request over, but response failed. {}", e.what()); + } + } else { + } + } + } catch (std::exception& e) { + LOG_ERROR_NEW("process request exception. {}", e.what()); + + if (!requestCommand->isOnewayRPC()) { + // TODO: send SYSTEM_ERROR response } } + } else { + std::string error = "request type " + UtilAll::to_string(requestCommand->getCode()) + " not supported"; + + // TODO: send REQUEST_CODE_NOT_SUPPORTED response + + LOG_ERROR_NEW("{} {}", addr, error); } } void TcpRemotingClient::addResponseFuture(int opaque, std::shared_ptr pFuture) { - std::lock_guard lock(m_futureTableLock); + std::lock_guard lock(m_futureTableMutex); m_futureTable[opaque] = pFuture; } -// Note: after call this function, shared_ptr of m_syncFutureTable[opaque] will +// Note: after call this function, shared_ptr of m_futureTable[opaque] will // be erased, so caller must ensure the life cycle of returned shared_ptr; std::shared_ptr TcpRemotingClient::findAndDeleteResponseFuture(int opaque) { - std::lock_guard lock(m_futureTableLock); + std::lock_guard lock(m_futureTableMutex); std::shared_ptr pResponseFuture; if (m_futureTable.find(opaque) != m_futureTable.end()) { pResponseFuture = m_futureTable[opaque]; @@ -576,66 +642,11 @@ std::shared_ptr TcpRemotingClient::findAndDeleteResponseFuture(i return pResponseFuture; } -void TcpRemotingClient::registerProcessor(MQRequestCode requestCode, ClientRemotingProcessor* clientRemotingProcessor) { - if (m_requestTable.find(requestCode) != m_requestTable.end()) - m_requestTable.erase(requestCode); - m_requestTable[requestCode] = clientRemotingProcessor; -} - -void TcpRemotingClient::addTimerCallback(boost::asio::deadline_timer* t, int opaque) { - std::lock_guard lock(m_asyncTimerTableLock); - if (m_asyncTimerTable.find(opaque) != m_asyncTimerTable.end()) { - LOG_DEBUG("addTimerCallback:erase timerCallback opaque:%lld", opaque); - boost::asio::deadline_timer* old_t = m_asyncTimerTable[opaque]; - m_asyncTimerTable.erase(opaque); - try { - old_t->cancel(); - } catch (const std::exception& ec) { - LOG_WARN("encounter exception when cancel old timer: %s", ec.what()); - } - delete old_t; - } - m_asyncTimerTable[opaque] = t; -} - -void TcpRemotingClient::eraseTimerCallback(int opaque) { - std::lock_guard lock(m_asyncTimerTableLock); - if (m_asyncTimerTable.find(opaque) != m_asyncTimerTable.end()) { - LOG_DEBUG("eraseTimerCallback: opaque:%lld", opaque); - boost::asio::deadline_timer* t = m_asyncTimerTable[opaque]; - m_asyncTimerTable.erase(opaque); - delete t; - } -} - -void TcpRemotingClient::cancelTimerCallback(int opaque) { - std::lock_guard lock(m_asyncTimerTableLock); - if (m_asyncTimerTable.find(opaque) != m_asyncTimerTable.end()) { - LOG_DEBUG("cancelTimerCallback: opaque:%lld", opaque); - boost::asio::deadline_timer* t = m_asyncTimerTable[opaque]; - m_asyncTimerTable.erase(opaque); - try { - t->cancel(); - } catch (const std::exception& ec) { - LOG_WARN("encounter exception when cancel timer: %s", ec.what()); - } - delete t; - } -} - -void TcpRemotingClient::removeAllTimerCallback() { - std::lock_guard lock(m_asyncTimerTableLock); - for (const auto& timer : m_asyncTimerTable) { - boost::asio::deadline_timer* t = timer.second; - try { - t->cancel(); - } catch (const std::exception& ec) { - LOG_WARN("encounter exception when cancel timer: %s", ec.what()); - } - delete t; +void TcpRemotingClient::registerProcessor(MQRequestCode requestCode, RequestProcessor* requestProcessor) { + if (m_processorTable.find(requestCode) != m_processorTable.end()) { + m_processorTable.erase(requestCode); } - m_asyncTimerTable.clear(); + m_processorTable[requestCode] = requestProcessor; } -// +#include #include +#include +#include -#include -#include -#include -#include +#include "concurrent/executor.hpp" -#include "ClientRemotingProcessor.h" +#include "MQClientException.h" +#include "MQProtos.h" +#include "RPCHook.h" #include "RemotingCommand.h" +#include "RequestProcessor.h" #include "ResponseFuture.h" #include "SocketUtil.h" #include "TcpTransport.h" namespace rocketmq { -// rpcHook); - // delete outsite; - virtual RemotingCommand* invokeSync(const string& addr, RemotingCommand& request, int timeoutMillis = 3000); + void updateNameServerAddressList(const std::string& addrs); - virtual bool invokeAsync(const string& addr, - RemotingCommand& request, - AsyncCallbackWrap* cbw, - int64 timeoutMilliseconds, - int maxRetrySendTimes = 1, - int retrySendTimes = 1); + std::unique_ptr invokeSync(const std::string& addr, + RemotingCommand& request, + int timeoutMillis = 3000) throw(RemotingException); - virtual void invokeOneway(const string& addr, RemotingCommand& request); + void invokeAsync(const std::string& addr, + RemotingCommand& request, + InvokeCallback* invokeCallback, + int64_t timeoutMillis) throw(RemotingException); - virtual void registerProcessor(MQRequestCode requestCode, ClientRemotingProcessor* clientRemotingProcessor); + void invokeOneway(const std::string& addr, RemotingCommand& request) throw(RemotingException); - private: - static void static_messageReceived(void* context, const MemoryBlock& mem, const string& addr); - - void messageReceived(const MemoryBlock& mem, const string& addr); - void ProcessData(const MemoryBlock& mem, const string& addr); - void processRequestCommand(RemotingCommand* pCmd, const string& addr); - void processResponseCommand(RemotingCommand* pCmd, std::shared_ptr pFuture); - void handleAsyncRequestTimeout(const boost::system::error_code& e, int opaque); - - std::shared_ptr GetTransport(const string& addr, bool needResponse); - std::shared_ptr CreateTransport(const string& addr, bool needResponse); - std::shared_ptr CreateNameServerTransport(bool needResponse); + void registerProcessor(MQRequestCode requestCode, RequestProcessor* requestProcessor); - bool CloseTransport(const string& addr, std::shared_ptr pTcp); - bool CloseNameServerTransport(std::shared_ptr pTcp); - - bool SendCommand(std::shared_ptr pTts, RemotingCommand& msg); + std::vector getNameServerAddressList() { return m_namesrvAddrList; } + private: + static bool SendCommand(TcpTransportPtr channel, RemotingCommand& msg); + static void MessageReceived(void* context, MemoryBlockPtr3& mem, const std::string& addr); + + void messageReceived(MemoryBlockPtr3& mem, const std::string& addr); + void processMessageReceived(MemoryBlockPtr2& mem, const std::string& addr); + void processRequestCommand(std::unique_ptr cmd, const std::string& addr); + void processResponseCommand(std::unique_ptr cmd); + + // timeout daemon + void scanResponseTablePeriodically(); + void scanResponseTable(); + + TcpTransportPtr GetTransport(const std::string& addr, bool needResponse); + TcpTransportPtr CreateTransport(const std::string& addr, bool needResponse); + TcpTransportPtr CreateNameServerTransport(bool needResponse); + + bool CloseTransport(const std::string& addr, TcpTransportPtr channel); + bool CloseNameServerTransport(TcpTransportPtr channel); + + std::unique_ptr invokeSyncImpl(TcpTransportPtr channel, + RemotingCommand& request, + int64_t timeoutMillis) throw(RemotingTimeoutException, + RemotingSendRequestException); + void invokeAsyncImpl(TcpTransportPtr channel, + RemotingCommand& request, + int64_t timeoutMillis, + InvokeCallback* invokeCallback) throw(RemotingSendRequestException); + void invokeOnewayImpl(TcpTransportPtr channel, RemotingCommand& request) throw(RemotingSendRequestException); + + // rpc hook + void doBeforeRpcHooks(const std::string& addr, RemotingCommand& request, bool toSent); + void doAfterRpcHooks(const std::string& addr, RemotingCommand& request, RemotingCommand* response, bool toSent); + + // future management void addResponseFuture(int opaque, std::shared_ptr pFuture); std::shared_ptr findAndDeleteResponseFuture(int opaque); - void addTimerCallback(boost::asio::deadline_timer* t, int opaque); - void eraseTimerCallback(int opaque); - void cancelTimerCallback(int opaque); - void removeAllTimerCallback(); - - void boost_asio_work(); - private: - using RequestMap = map; - using TcpMap = map>; - using ResMap = map>; - using AsyncTimerMap = map; + using ProcessorMap = std::map; + using TransportMap = std::map>; + using FutureMap = std::map>; - RequestMap m_requestTable; + ProcessorMap m_processorTable; // code -> processor - TcpMap m_tcpTable; //tcp; - std::timed_mutex m_tcpTableLock; + TransportMap m_transportTable; // addr -> transport + std::timed_mutex m_transportTableMutex; - ResMap m_futureTable; //future; - std::mutex m_futureTableLock; + FutureMap m_futureTable; // opaque -> future + std::mutex m_futureTableMutex; - AsyncTimerMap m_asyncTimerTable; - std::mutex m_asyncTimerTableLock; + // FIXME: not strict thread-safe in abnormal scence + std::vector> m_rpcHooks; // for Acl / ONS - int m_dispatchThreadNum; - int m_pullThreadNum; uint64_t m_tcpConnectTimeout; // ms uint64_t m_tcpTransportTryLockTimeout; // s - // m_namesrvAddrList; - string m_namesrvAddrChoosed; + std::vector m_namesrvAddrList; + std::string m_namesrvAddrChoosed; unsigned int m_namesrvIndex; - boost::asio::io_service m_dispatchService; - boost::asio::io_service::work m_dispatchServiceWork; - boost::thread_group m_dispatchThreadPool; - - boost::asio::io_service m_handleService; - boost::asio::io_service::work m_handleServiceWork; - boost::thread_group m_handleThreadPool; - - boost::asio::io_service m_timerService; - unique_ptr m_timerServiceThread; + thread_pool_executor m_dispatchExecutor; + thread_pool_executor m_handleExecutor; + scheduled_thread_pool_executor m_timeoutExecutor; }; -// // for socket(), bind(), and connect()... #endif +#include "ByteOrder.h" #include "Logging.h" #include "TcpRemotingClient.h" #include "UtilAll.h" namespace rocketmq { -//setCallback(nullptr, nullptr, nullptr, nullptr); +TcpConnectStatus TcpTransport::closeBufferEvent() { + // closeBufferEvent is idempotent. + if (setTcpConnectEvent(TCP_CONNECT_STATUS_CLOSED) != TCP_CONNECT_STATUS_CLOSED) { + if (m_event != nullptr) { + m_event->disable(EV_READ | EV_WRITE); // this is need for avoid block on event_base_dispatch. + // close the socket!!! + m_event->close(); + } } - - // then, release BufferEvent - m_event.reset(); -} - -void TcpTransport::setTcpConnectStatus(TcpConnectStatus connectStatus) { - m_tcpConnectStatus = connectStatus; + return TCP_CONNECT_STATUS_CLOSED; } TcpConnectStatus TcpTransport::getTcpConnectStatus() { @@ -67,10 +63,10 @@ TcpConnectStatus TcpTransport::getTcpConnectStatus() { } TcpConnectStatus TcpTransport::waitTcpConnectEvent(int timeoutMillis) { - if (m_tcpConnectStatus == TCP_CONNECT_STATUS_WAIT) { - std::unique_lock eventLock(m_connectEventLock); - if (!m_connectEvent.wait_for(eventLock, std::chrono::milliseconds(timeoutMillis), - [&] { return m_tcpConnectStatus != TCP_CONNECT_STATUS_WAIT; })) { + if (m_tcpConnectStatus == TCP_CONNECT_STATUS_CONNECTING) { + std::unique_lock lock(m_statusMutex); + if (!m_statusEvent.wait_for(lock, std::chrono::milliseconds(timeoutMillis), + [&] { return m_tcpConnectStatus != TCP_CONNECT_STATUS_CONNECTING; })) { LOG_INFO("connect timeout"); } } @@ -78,136 +74,140 @@ TcpConnectStatus TcpTransport::waitTcpConnectEvent(int timeoutMillis) { } // internal method -void TcpTransport::setTcpConnectEvent(TcpConnectStatus connectStatus) { - TcpConnectStatus baseStatus = m_tcpConnectStatus.exchange(connectStatus, std::memory_order_relaxed); - if (baseStatus == TCP_CONNECT_STATUS_WAIT) { +TcpConnectStatus TcpTransport::setTcpConnectEvent(TcpConnectStatus connectStatus) { + TcpConnectStatus oldStatus = m_tcpConnectStatus.exchange(connectStatus, std::memory_order_relaxed); + if (oldStatus == TCP_CONNECT_STATUS_CONNECTING) { // awake waiting thread - m_connectEvent.notify_all(); + m_statusEvent.notify_all(); } + return oldStatus; } -u_long TcpTransport::getInetAddr(string& hostname) { - u_long addr = inet_addr(hostname.c_str()); +bool TcpTransport::setTcpConnectEventIf(TcpConnectStatus& expectedStatus, TcpConnectStatus newStatus) { + bool isSuccessed = m_tcpConnectStatus.compare_exchange_strong(expectedStatus, newStatus); + if (expectedStatus == TCP_CONNECT_STATUS_CONNECTING) { + // awake waiting thread + m_statusEvent.notify_all(); + } + return isSuccessed; +} +u_long TcpTransport::resolveInetAddr(std::string& hostname) { + // TODO: support ipv6 + u_long addr = inet_addr(hostname.c_str()); if (INADDR_NONE == addr) { - constexpr size_t length = 128; - struct evutil_addrinfo hints; - struct evutil_addrinfo* answer = NULL; - /* Build the hints to tell getaddrinfo how to act. */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; /* v4 or v6 is fine. */ - // Look up the hostname. - int err = evutil_getaddrinfo(hostname.c_str(), NULL, &hints, &answer); - if (err != 0) { - string info = "Failed to resolve host name(" + hostname + "): " + evutil_gai_strerror(err); - THROW_MQEXCEPTION(MQClientException, info, -1); - } - - struct evutil_addrinfo* addressInfo; - for (addressInfo = answer; addressInfo; addressInfo = addressInfo->ai_next) { - char buf[length]; - const char* address = NULL; - if (addressInfo->ai_family == AF_INET) { - struct sockaddr_in* sin = (struct sockaddr_in*)addressInfo->ai_addr; - address = evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, length); - } else if (addressInfo->ai_family == AF_INET6) { - struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addressInfo->ai_addr; - address = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, length); - } - if (address) { - addr = inet_addr(address); - if (addr != INADDR_NONE) { - break; - } - } - } + auto ip = lookupNameServers(hostname); + addr = inet_addr(ip.c_str()); } - return addr; } -void TcpTransport::disconnect(const string& addr) { +void TcpTransport::disconnect(const std::string& addr) { // disconnect is idempotent. - std::lock_guard lock(m_eventLock); - if (getTcpConnectStatus() != TCP_CONNECT_STATUS_INIT) { - LOG_INFO("disconnect:%s start. event:%p", addr.c_str(), m_event.get()); - freeBufferEvent(); - setTcpConnectEvent(TCP_CONNECT_STATUS_INIT); - LOG_INFO("disconnect:%s completely", addr.c_str()); - } + LOG_INFO_NEW("disconnect:{} start. event:{}", addr, (void*)m_event.get()); + closeBufferEvent(); + LOG_INFO_NEW("disconnect:{} completely", addr); } -TcpConnectStatus TcpTransport::connect(const string& strServerURL, int timeoutMillis) { - string hostname; +TcpConnectStatus TcpTransport::connect(const std::string& strServerURL, int timeoutMillis) { + std::string hostname; short port; - LOG_DEBUG("connect to [%s].", strServerURL.c_str()); + + LOG_INFO_NEW("connect to [{}].", strServerURL); if (!UtilAll::SplitURL(strServerURL, hostname, port)) { - LOG_INFO("connect to [%s] failed, Invalid url.", strServerURL.c_str()); - return TCP_CONNECT_STATUS_FAILED; + LOG_ERROR_NEW("connect to [{}] failed, Invalid url.", strServerURL); + return closeBufferEvent(); } - { - std::lock_guard lock(m_eventLock); - + TcpConnectStatus curStatus = TCP_CONNECT_STATUS_CREATED; + if (setTcpConnectEventIf(curStatus, TCP_CONNECT_STATUS_CONNECTING)) { + // TODO: support ipv6 struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; - sin.sin_addr.s_addr = getInetAddr(hostname); + try { + sin.sin_addr.s_addr = resolveInetAddr(hostname); + } catch (UnknownHostException& e) { + // throw exception if dns failed. + LOG_WARN_NEW("{}", e.what()); + return closeBufferEvent(); + } sin.sin_port = htons(port); - m_event.reset(EventLoop::GetDefaultEventLoop()->createBufferEvent(-1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE)); - m_event->setCallback(readNextMessageIntCallback, nullptr, eventCallback, shared_from_this()); + // create BufferEvent + m_event.reset( + EventLoop::GetDefaultEventLoop()->createBufferEvent(-1, /* BEV_OPT_CLOSE_ON_FREE | */ BEV_OPT_THREADSAFE)); + if (nullptr == m_event) { + LOG_ERROR_NEW("create BufferEvent failed"); + return closeBufferEvent(); + } + + // then, configure BufferEvent + m_event->setCallback(ReadCallback, nullptr, EventCallback, shared_from_this()); m_event->setWatermark(EV_READ, 4, 0); m_event->enable(EV_READ | EV_WRITE); - setTcpConnectStatus(TCP_CONNECT_STATUS_WAIT); if (m_event->connect((struct sockaddr*)&sin, sizeof(sin)) < 0) { - LOG_INFO("connect to fd:%d failed", m_event->getfd()); - freeBufferEvent(); - setTcpConnectStatus(TCP_CONNECT_STATUS_FAILED); - return TCP_CONNECT_STATUS_FAILED; + LOG_WARN_NEW("connect to fd:{} failed", m_event->getfd()); + return closeBufferEvent(); } + } else { + return curStatus; } if (timeoutMillis <= 0) { - LOG_INFO("try to connect to fd:%d, addr:%s", m_event->getfd(), hostname.c_str()); - return TCP_CONNECT_STATUS_WAIT; + LOG_INFO_NEW("try to connect to fd:{}, addr:{}", m_event->getfd(), hostname); + return TCP_CONNECT_STATUS_CONNECTING; } TcpConnectStatus connectStatus = waitTcpConnectEvent(timeoutMillis); - if (connectStatus != TCP_CONNECT_STATUS_SUCCESS) { - LOG_WARN("can not connect to server:%s", strServerURL.c_str()); - - std::lock_guard lock(m_eventLock); - freeBufferEvent(); - setTcpConnectStatus(TCP_CONNECT_STATUS_FAILED); - return TCP_CONNECT_STATUS_FAILED; + if (connectStatus != TCP_CONNECT_STATUS_CONNECTED) { + LOG_WARN_NEW("can not connect to server:{}", strServerURL); + return closeBufferEvent(); } - return TCP_CONNECT_STATUS_SUCCESS; + return TCP_CONNECT_STATUS_CONNECTED; } -void TcpTransport::eventCallback(BufferEvent* event, short what, TcpTransport* transport) { +void TcpTransport::EventCallback(BufferEvent* event, short what, TcpTransport* transport) { socket_t fd = event->getfd(); LOG_INFO("eventcb: received event:%x on fd:%d", what, fd); if (what & BEV_EVENT_CONNECTED) { LOG_INFO("eventcb: connect to fd:%d successfully", fd); + int val; + // disable Nagle - int val = 1; - setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val)); - transport->setTcpConnectEvent(TCP_CONNECT_STATUS_SUCCESS); - } else if (what & (BEV_EVENT_ERROR | BEV_EVENT_EOF | BEV_EVENT_READING | BEV_EVENT_WRITING)) { + val = 1; + if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val)) < 0) { + LOG_WARN_NEW("eventcb: disable Nagle failed. fd:{}", fd); + } + + // disable Keep-Alive + val = 0; + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&val, sizeof(val)) < 0) { + LOG_WARN_NEW("eventcb: disable Keep-Alive failed. fd:{}", fd); + } + + TcpConnectStatus curStatus = TCP_CONNECT_STATUS_CONNECTING; + transport->setTcpConnectEventIf(curStatus, TCP_CONNECT_STATUS_CONNECTED); + } else if (what & (BEV_EVENT_ERROR | BEV_EVENT_EOF)) { LOG_INFO("eventcb: received error event cb:%x on fd:%d", what, fd); // if error, stop callback. - event->setCallback(nullptr, nullptr, nullptr, nullptr); - transport->setTcpConnectEvent(TCP_CONNECT_STATUS_FAILED); + TcpConnectStatus curStatus = transport->getTcpConnectStatus(); + while (curStatus != TCP_CONNECT_STATUS_CLOSED && curStatus != TCP_CONNECT_STATUS_FAILED) { + if (transport->setTcpConnectEventIf(curStatus, TCP_CONNECT_STATUS_FAILED)) { + event->setCallback(nullptr, nullptr, nullptr, nullptr); + break; + } + curStatus = transport->getTcpConnectStatus(); + } } else { LOG_ERROR("eventcb: received error event:%d on fd:%d", what, fd); } } -void TcpTransport::readNextMessageIntCallback(BufferEvent* event, TcpTransport* transport) { +void TcpTransport::ReadCallback(BufferEvent* event, TcpTransport* transport) { /* This callback is invoked when there is data to read on bev. */ // protocol:
@@ -220,59 +220,54 @@ void TcpTransport::readNextMessageIntCallback(BufferEvent* event, TcpTransport* struct evbuffer* input = event->getInput(); while (1) { + // glance at first 4 byte to get package length struct evbuffer_iovec v[4]; int n = evbuffer_peek(input, 4, NULL, v, sizeof(v) / sizeof(v[0])); - char hdr[4]; - char* p = hdr; + uint32_t packageLength; // first 4 bytes, which indicates 1st part of protocol + char* p = (char*)&packageLength; size_t needed = 4; - for (int idx = 0; idx < n; idx++) { - if (needed > 0) { - size_t tmp = needed < v[idx].iov_len ? needed : v[idx].iov_len; - memcpy(p, v[idx].iov_base, tmp); - p += tmp; - needed -= tmp; - } else { - break; - } + for (int idx = 0; idx < n && needed > 0; idx++) { + size_t s = needed < v[idx].iov_len ? needed : v[idx].iov_len; + memcpy(p, v[idx].iov_base, s); + p += s; + needed -= s; } if (needed > 0) { - LOG_DEBUG("too little data received with sum = %d", 4 - needed); + LOG_DEBUG_NEW("too little data received with {} byte(s)", 4 - needed); return; } - uint32 totalLenOfOneMsg = *(uint32*)hdr; // first 4 bytes, which indicates 1st part of protocol - uint32 msgLen = ntohl(totalLenOfOneMsg); + uint32_t msgLen = ByteOrder::swapIfLittleEndian(packageLength); // same as ntohl() size_t recvLen = evbuffer_get_length(input); if (recvLen >= msgLen + 4) { - LOG_DEBUG("had received all data. msgLen:%d, from:%d, recvLen:%d", msgLen, event->getfd(), recvLen); + LOG_DEBUG_NEW("had received all data. msgLen:{}, from:{}, recvLen:{}", msgLen, event->getfd(), recvLen); } else { - LOG_DEBUG("didn't received whole. msgLen:%d, from:%d, recvLen:%d", msgLen, event->getfd(), recvLen); + LOG_DEBUG_NEW("didn't received whole. msgLen:{}, from:{}, recvLen:{}", msgLen, event->getfd(), recvLen); return; // consider large data which was not received completely by now } if (msgLen > 0) { - MemoryBlock msg(msgLen, true); + MemoryBlockPtr3 msg(new MemoryPool(msgLen, true)); - event->read(hdr, 4); // skip length field - event->read(msg.getData(), msgLen); + event->read(&packageLength, 4); // skip length field + event->read(msg->getData(), msgLen); transport->messageReceived(msg, event->getPeerAddrPort()); } } } -void TcpTransport::messageReceived(const MemoryBlock& mem, const std::string& addr) { +void TcpTransport::messageReceived(MemoryBlockPtr3& mem, const std::string& addr) { if (m_readCallback != nullptr) { m_readCallback(m_tcpRemotingClient, mem, addr); } } -bool TcpTransport::sendMessage(const char* pData, size_t len) { - std::lock_guard lock(m_eventLock); - if (getTcpConnectStatus() != TCP_CONNECT_STATUS_SUCCESS) { +bool TcpTransport::sendMessage(const char* data, size_t len) { + if (getTcpConnectStatus() != TCP_CONNECT_STATUS_CONNECTED) { return false; } @@ -280,12 +275,11 @@ bool TcpTransport::sendMessage(const char* pData, size_t len) { do not need to consider large data which could not send by once, as bufferevent could handle this case; */ - return m_event != nullptr && m_event->write(pData, len) == 0; + return m_event != nullptr && m_event->write(data, len) == 0; } -const string TcpTransport::getPeerAddrAndPort() { - std::lock_guard lock(m_eventLock); - return m_event ? m_event->getPeerAddrPort() : ""; +const std::string& TcpTransport::getPeerAddrAndPort() { + return m_event != nullptr ? m_event->getPeerAddrPort() : null; } const uint64_t TcpTransport::getStartTime() const { diff --git a/src/transport/TcpTransport.h b/src/transport/TcpTransport.h index bff23ddfc..7b9a44d7d 100755 --- a/src/transport/TcpTransport.h +++ b/src/transport/TcpTransport.h @@ -21,30 +21,31 @@ #include #include +#include "DataBlock.h" #include "EventLoop.h" -#include "dataBlock.h" namespace rocketmq { -// { +typedef std::shared_ptr TcpTransportPtr; + +class TcpTransport : public noncopyable, public std::enable_shared_from_this { public: - static std::shared_ptr CreateTransport(TcpRemotingClient* pTcpRemotingClient, - TcpTransportReadCallback handle = nullptr) { + static TcpTransportPtr CreateTransport(TcpRemotingClient* client, TcpTransportReadCallback handle = nullptr) { // transport must be managed by smart pointer - std::shared_ptr transport(new TcpTransport(pTcpRemotingClient, handle)); - return transport; + return TcpTransportPtr(new TcpTransport(client, handle)); } virtual ~TcpTransport(); @@ -55,39 +56,41 @@ class TcpTransport : public std::enable_shared_from_this { TcpConnectStatus getTcpConnectStatus(); bool sendMessage(const char* pData, size_t len); - const std::string getPeerAddrAndPort(); + const std::string& getPeerAddrAndPort(); const uint64_t getStartTime() const; private: - TcpTransport(TcpRemotingClient* pTcpRemotingClient, TcpTransportReadCallback handle = nullptr); + // don't instance object directly. + TcpTransport(TcpRemotingClient* client, TcpTransportReadCallback callback = nullptr); + + // buffer + static void ReadCallback(BufferEvent* event, TcpTransport* transport); + static void EventCallback(BufferEvent* event, short what, TcpTransport* transport); - static void readNextMessageIntCallback(BufferEvent* event, TcpTransport* transport); - static void eventCallback(BufferEvent* event, short what, TcpTransport* transport); + void messageReceived(MemoryBlockPtr3& mem, const std::string& addr); - void messageReceived(const MemoryBlock& mem, const std::string& addr); - void freeBufferEvent(); // not thread-safe + TcpConnectStatus closeBufferEvent(); // not thread-safe - void setTcpConnectEvent(TcpConnectStatus connectStatus); - void setTcpConnectStatus(TcpConnectStatus connectStatus); + TcpConnectStatus setTcpConnectEvent(TcpConnectStatus connectStatus); + bool setTcpConnectEventIf(TcpConnectStatus& expectStatus, TcpConnectStatus connectStatus); - u_long getInetAddr(std::string& hostname); + // convert host to binary + u_long resolveInetAddr(std::string& hostname); private: uint64_t m_startTime; std::shared_ptr m_event; // NOTE: use m_event in callback is unsafe. - std::mutex m_eventLock; - std::atomic m_tcpConnectStatus; - std::mutex m_connectEventLock; - std::condition_variable m_connectEvent; + std::atomic m_tcpConnectStatus; + std::mutex m_statusMutex; + std::condition_variable m_statusEvent; - //registerProcessor(CHECK_TRANSACTION_STATE, m_processor); - m_pRemotingClient->registerProcessor(RESET_CONSUMER_CLIENT_OFFSET, m_processor); - m_pRemotingClient->registerProcessor(GET_CONSUMER_STATUS_FROM_CLIENT, m_processor); - m_pRemotingClient->registerProcessor(GET_CONSUMER_RUNNING_INFO, m_processor); - m_pRemotingClient->registerProcessor(NOTIFY_CONSUMER_IDS_CHANGED, m_processor); - m_pRemotingClient->registerProcessor(CONSUME_MESSAGE_DIRECTLY, m_processor); - } -}; -class MockMQClientAPIImplUtil { - public: - static MockMQClientAPIImplUtil* GetInstance() { - static MockMQClientAPIImplUtil instance; - return &instance; - } - MockMQClientAPIImpl* GetGtestMockClientAPIImpl() { - if (m_impl != nullptr) { - return m_impl; - } - string cid = "testClientId"; - int ptN = 1; - uint64_t tct = 3000; - uint64_t ttt = 3000; - string un = "central"; - SessionCredentials sc; - ClientRemotingProcessor* pp = new ClientRemotingProcessor(nullptr); - MockMQClientAPIImpl* impl = new MockMQClientAPIImpl(cid, pp, ptN, tct, ttt, un); - MockTcpRemotingClient* pClient = new MockTcpRemotingClient(ptN, tct, ttt); - impl->reInitRemoteClient(pClient); - m_impl = impl; - m_pClient = pClient; - return impl; - } - MockTcpRemotingClient* GetGtestMockRemotingClient() { return m_pClient; } - MockMQClientAPIImpl* m_impl = nullptr; - MockTcpRemotingClient* m_pClient = nullptr; -}; - -TEST(MQClientAPIImplTest, getMaxOffset) { - SessionCredentials sc; - MockMQClientAPIImpl* impl = MockMQClientAPIImplUtil::GetInstance()->GetGtestMockClientAPIImpl(); - Mock::AllowLeak(impl); - MockTcpRemotingClient* pClient = MockMQClientAPIImplUtil::GetInstance()->GetGtestMockRemotingClient(); - Mock::AllowLeak(pClient); - GetMaxOffsetResponseHeader* pHead = new GetMaxOffsetResponseHeader(); - pHead->offset = 4096; - RemotingCommand* pCommandFailed = new RemotingCommand(SYSTEM_ERROR, nullptr); - RemotingCommand* pCommandSuccuss = new RemotingCommand(SUCCESS_VALUE, pHead); - EXPECT_CALL(*pClient, invokeSync(_, _, _)) - .Times(3) - .WillOnce(Return(nullptr)) - .WillOnce(Return(pCommandFailed)) - .WillOnce(Return(pCommandSuccuss)); - EXPECT_ANY_THROW(impl->getMaxOffset("127.0.0.0:10911", "testTopic", 0, 1000, sc)); - EXPECT_ANY_THROW(impl->getMaxOffset("127.0.0.0:10911", "testTopic", 0, 1000, sc)); - int64 offset = impl->getMaxOffset("127.0.0.0:10911", "testTopic", 0, 1000, sc); - EXPECT_EQ(4096, offset); -} - -TEST(MQClientAPIImplTest, getMinOffset) { - SessionCredentials sc; - MockMQClientAPIImpl* impl = MockMQClientAPIImplUtil::GetInstance()->GetGtestMockClientAPIImpl(); - Mock::AllowLeak(impl); - MockTcpRemotingClient* pClient = MockMQClientAPIImplUtil::GetInstance()->GetGtestMockRemotingClient(); - Mock::AllowLeak(pClient); - GetMinOffsetResponseHeader* pHead = new GetMinOffsetResponseHeader(); - pHead->offset = 2048; - RemotingCommand* pCommandFailed = new RemotingCommand(SYSTEM_ERROR, nullptr); - RemotingCommand* pCommandSuccuss = new RemotingCommand(SUCCESS_VALUE, pHead); - EXPECT_CALL(*pClient, invokeSync(_, _, _)) - .Times(3) - .WillOnce(Return(nullptr)) - .WillOnce(Return(pCommandFailed)) - .WillOnce(Return(pCommandSuccuss)); - EXPECT_ANY_THROW(impl->getMinOffset("127.0.0.0:10911", "testTopic", 0, 1000, sc)); - EXPECT_ANY_THROW(impl->getMinOffset("127.0.0.0:10911", "testTopic", 0, 1000, sc)); - int64 offset = impl->getMinOffset("127.0.0.0:10911", "testTopic", 0, 1000, sc); - EXPECT_EQ(2048, offset); -} - -TEST(MQClientAPIImplTest, sendMessage) { - string cid = "testClientId"; - SessionCredentials sc; - MockMQClientAPIImpl* impl = MockMQClientAPIImplUtil::GetInstance()->GetGtestMockClientAPIImpl(); - Mock::AllowLeak(impl); - MockTcpRemotingClient* pClient = MockMQClientAPIImplUtil::GetInstance()->GetGtestMockRemotingClient(); - Mock::AllowLeak(pClient); - - SendMessageResponseHeader* pHead = new SendMessageResponseHeader(); - pHead->msgId = "MessageID"; - pHead->queueId = 1; - pHead->queueOffset = 409600; - RemotingCommand* pCommandSync = new RemotingCommand(SUCCESS_VALUE, pHead); - EXPECT_CALL(*pClient, invokeSync(_, _, _)).Times(1).WillOnce(Return(pCommandSync)); - MQMessage message("testTopic", "Hello, RocketMQ"); - string unique_msgId = "UniqMessageID"; - message.setProperty(MQMessage::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX, unique_msgId); - SendMessageRequestHeader* requestHeader = new SendMessageRequestHeader(); - requestHeader->producerGroup = cid; - requestHeader->topic = (message.getTopic()); - requestHeader->defaultTopic = DEFAULT_TOPIC; - requestHeader->defaultTopicQueueNums = 4; - requestHeader->bornTimestamp = UtilAll::currentTimeMillis(); - SendResult result = - impl->sendMessage("127.0.0.0:10911", "testBroker", message, requestHeader, 100, 1, ComMode_SYNC, nullptr, sc); - EXPECT_EQ(result.getSendStatus(), SEND_OK); - EXPECT_EQ(result.getMsgId(), unique_msgId); - EXPECT_EQ(result.getQueueOffset(), 409600); - EXPECT_EQ(result.getOffsetMsgId(), "MessageID"); - EXPECT_EQ(result.getMessageQueue().getBrokerName(), "testBroker"); - EXPECT_EQ(result.getMessageQueue().getTopic(), "testTopic"); -} - -TEST(MQClientAPIImplTest, consumerSendMessageBack) { - SessionCredentials sc; - MQMessageExt msg; - MockMQClientAPIImpl* impl = MockMQClientAPIImplUtil::GetInstance()->GetGtestMockClientAPIImpl(); - Mock::AllowLeak(impl); - MockTcpRemotingClient* pClient = MockMQClientAPIImplUtil::GetInstance()->GetGtestMockRemotingClient(); - Mock::AllowLeak(pClient); - RemotingCommand* pCommandFailed = new RemotingCommand(SYSTEM_ERROR, nullptr); - RemotingCommand* pCommandSuccuss = new RemotingCommand(SUCCESS_VALUE, nullptr); - EXPECT_CALL(*pClient, invokeSync(_, _, _)) - .Times(3) - .WillOnce(Return(nullptr)) - .WillOnce(Return(pCommandFailed)) - .WillOnce(Return(pCommandSuccuss)); - EXPECT_ANY_THROW(impl->consumerSendMessageBack("127.0.0.0:10911", msg, "testGroup", 0, 1000, 16, sc)); - EXPECT_ANY_THROW(impl->consumerSendMessageBack("127.0.0.0:10911", msg, "testGroup", 0, 1000, 16, sc)); - EXPECT_NO_THROW(impl->consumerSendMessageBack("127.0.0.0:10911", msg, "testGroup", 0, 1000, 16, sc)); -} - -int main(int argc, char* argv[]) { - InitGoogleMock(&argc, argv); - testing::GTEST_FLAG(filter) = "MQClientAPIImplTest.*"; - return RUN_ALL_TESTS(); -} diff --git a/test/src/MQClientFactoryTest.cpp b/test/src/MQClientFactoryTest.cpp deleted file mode 100644 index 11490e58f..000000000 --- a/test/src/MQClientFactoryTest.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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 - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "MQClientFactory.h" - -using namespace std; -using namespace rocketmq; -using rocketmq::MQClientFactory; -using rocketmq::TopicRouteData; -using testing::_; -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; -using testing::Return; - -class MockMQClientAPIImpl : public MQClientAPIImpl { - public: - MockMQClientAPIImpl(const string& mqClientId, - ClientRemotingProcessor* clientRemotingProcessor, - int pullThreadNum, - uint64_t tcpConnectTimeout, - uint64_t tcpTransportTryLockTimeout, - string unitName) - : MQClientAPIImpl(mqClientId, - clientRemotingProcessor, - pullThreadNum, - tcpConnectTimeout, - tcpTransportTryLockTimeout, - unitName) {} - - MOCK_METHOD5(getMinOffset, int64(const string&, const string&, int, int, const SessionCredentials&)); - MOCK_METHOD3(getTopicRouteInfoFromNameServer, TopicRouteData*(const string&, int, const SessionCredentials&)); -}; -class MockMQClientFactory : public MQClientFactory { - public: - MockMQClientFactory(const string& mqClientId, - int pullThreadNum, - uint64_t tcpConnectTimeout, - uint64_t tcpTransportTryLockTimeout, - string unitName) - : MQClientFactory(mqClientId, pullThreadNum, tcpConnectTimeout, tcpTransportTryLockTimeout, unitName) {} - void reInitClientImpl(MQClientAPIImpl* pImpl) { m_pClientAPIImpl.reset(pImpl); } - void reInitRemotingProcessor(ClientRemotingProcessor* pImpl) { m_pClientRemotingProcessor.reset(pImpl); } - ClientRemotingProcessor* getRemotingProcessor() { return m_pClientRemotingProcessor.release(); } -}; - -TEST(MQClientFactoryTest, minOffset) { - string clientId = "testClientId"; - int pullThreadNum = 1; - uint64_t tcpConnectTimeout = 3000; - uint64_t tcpTransportTryLockTimeout = 3000; - string unitName = "central"; - MockMQClientFactory* factory = - new MockMQClientFactory(clientId, pullThreadNum, tcpConnectTimeout, tcpTransportTryLockTimeout, unitName); - MockMQClientAPIImpl* pImpl = new MockMQClientAPIImpl(clientId, factory->getRemotingProcessor(), pullThreadNum, - tcpConnectTimeout, tcpTransportTryLockTimeout, unitName); - factory->reInitClientImpl(pImpl); - MQMessageQueue mq; - mq.setTopic("testTopic"); - mq.setBrokerName("testBroker"); - mq.setQueueId(1); - SessionCredentials session_credentials; - - TopicRouteData* pData = new TopicRouteData(); - pData->setOrderTopicConf("OrderTopicConf"); - QueueData qd; - qd.brokerName = "testBroker"; - qd.readQueueNums = 8; - qd.writeQueueNums = 8; - qd.perm = 1; - pData->getQueueDatas().push_back(qd); - BrokerData bd; - bd.brokerName = "testBroker"; - bd.brokerAddrs[0] = "127.0.0.1:10091"; - bd.brokerAddrs[1] = "127.0.0.2:10092"; - pData->getBrokerDatas().push_back(bd); - - EXPECT_CALL(*pImpl, getMinOffset(_, _, _, _, _)).Times(1).WillOnce(Return(1024)); - EXPECT_CALL(*pImpl, getTopicRouteInfoFromNameServer(_, _, _)).Times(1).WillOnce(Return(pData)); - int64 offset = factory->minOffset(mq, session_credentials); - EXPECT_EQ(1024, offset); - delete factory; -} - -int main(int argc, char* argv[]) { - InitGoogleMock(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/src/MQClientManagerTest.cpp b/test/src/MQClientManagerTest.cpp deleted file mode 100644 index 830be4684..000000000 --- a/test/src/MQClientManagerTest.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 -#include - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "MQClientManager.h" - -using namespace std; -using namespace rocketmq; -using rocketmq::MQClientFactory; -using rocketmq::MQClientManager; -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; -using testing::Return; - -TEST(MQClientManagerTest, getClientFactory) { - string clientId = "testClientId"; - string unitName = "central"; - MQClientFactory* factory = MQClientManager::getInstance()->getMQClientFactory(clientId, 1, 1000, 3000, unitName); - MQClientFactory* factory2 = MQClientManager::getInstance()->getMQClientFactory(clientId, 1, 1000, 3000, unitName); - EXPECT_EQ(factory, factory2); - - MQClientManager::getInstance()->removeClientFactory(clientId); -} -TEST(MQClientManagerTest, removeClientFactory) { - string clientId = "testClientId"; - MQClientManager::getInstance()->removeClientFactory(clientId); -} -int main(int argc, char* argv[]) { - InitGoogleMock(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/src/producer/StringIdMakerTest.cpp b/test/src/StringIdMakerTest.cpp similarity index 100% rename from test/src/producer/StringIdMakerTest.cpp rename to test/src/StringIdMakerTest.cpp diff --git a/test/src/common/MQVersionTest.cpp b/test/src/common/MQVersionTest.cpp deleted file mode 100644 index 587339bef..000000000 --- a/test/src/common/MQVersionTest.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "MQVersion.h" - -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; -using testing::Return; - -using rocketmq::MQVersion; -using rocketmq::RocketMQCPPClientVersion; - -TEST(MQVersionTest, Version2String) { - for (int v = MQVersion::V3_0_0_SNAPSHOT; v <= MQVersion::HIGHER_VERSION; v++) { - EXPECT_STREQ(MQVersion::GetVersionDesc(v), RocketMQCPPClientVersion[v]); - } - EXPECT_STREQ(MQVersion::GetVersionDesc(-100), MQVersion::GetVersionDesc(MQVersion::V3_0_0_SNAPSHOT)); - EXPECT_STREQ(MQVersion::GetVersionDesc(MQVersion::V4_6_0), "V4_6_0"); - EXPECT_STREQ(MQVersion::GetVersionDesc(MQVersion::HIGHER_VERSION + 100), - MQVersion::GetVersionDesc(MQVersion::HIGHER_VERSION)); -} - -int main(int argc, char* argv[]) { - InitGoogleMock(&argc, argv); - testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "MQVersionTest.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; -} diff --git a/test/src/common/UrlTest.cpp b/test/src/common/UrlTest.cpp deleted file mode 100644 index 636c2dee2..000000000 --- a/test/src/common/UrlTest.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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 -#include -#include "CCommon.h" -#include "CMQException.h" -#include "CMessage.h" -#include "CProducer.h" -#include "CSendResult.h" -#include "TopicConfig.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "url.h" - -#include - -#include -#include "CCommon.h" -#include "CMQException.h" -#include "CMessage.h" -#include "CProducer.h" -#include "CSendResult.h" - -using namespace std; -using rocketmq::TopicConfig; -using rocketmq::Url; -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; -using testing::Return; - -class MockTopicConfig : public TopicConfig { - public: - MOCK_METHOD0(getReadQueueNums, int()); -}; - -TEST(Url, Url) { - Url url_s("172.17.0.2:9876"); - EXPECT_EQ(url_s.protocol_, "172.17.0.2:9876"); - - Url url_z("https://www.aliyun.com/RocketMQ?5.0"); - EXPECT_EQ(url_z.protocol_, "https"); - EXPECT_EQ(url_z.host_, "www.aliyun.com"); - EXPECT_EQ(url_z.port_, "80"); - EXPECT_EQ(url_z.path_, "/RocketMQ"); - EXPECT_EQ(url_z.query_, "5.0"); - - Url url_path("https://www.aliyun.com:9876/RocketMQ?5.0"); - EXPECT_EQ(url_path.port_, "9876"); - MockTopicConfig topicConfig; - EXPECT_CALL(topicConfig, getReadQueueNums()).WillRepeatedly(Return(-1)); - int nums = topicConfig.getReadQueueNums(); - cout << nums << endl; -} - -int main(int argc, char* argv[]) { - InitGoogleMock(&argc, argv); - testing::GTEST_FLAG(filter) = "Url.Url"; - int itestts = RUN_ALL_TESTS(); - ; - return itestts; -} diff --git a/test/src/common/VirtualEnvUtilTest.cpp b/test/src/common/VirtualEnvUtilTest.cpp index 1300c90d5..f02889cf7 100644 --- a/test/src/common/VirtualEnvUtilTest.cpp +++ b/test/src/common/VirtualEnvUtilTest.cpp @@ -29,36 +29,23 @@ using testing::Return; using rocketmq::VirtualEnvUtil; +VirtualEnvUtil virtualEnvUtil; + TEST(virtualEnvUtil, buildWithProjectGroup) { string origin = "origin"; - string originWithGroupA = "origin%PROJECT_testGroupA%"; - string originWithGroupB = "origin%PROJECT_testGroupB%"; - string originWithGroupAB = "origin%PROJECT_testGroupA%%PROJECT_testGroupB%"; - string projectGroupA = "testGroupA"; - string projectGroupB = "testGroupB"; - EXPECT_EQ(VirtualEnvUtil::buildWithProjectGroup(origin, string()), origin); - EXPECT_EQ(VirtualEnvUtil::buildWithProjectGroup(origin, projectGroupA), originWithGroupA); - EXPECT_EQ(VirtualEnvUtil::buildWithProjectGroup(originWithGroupA, projectGroupA), originWithGroupA); - EXPECT_EQ(VirtualEnvUtil::buildWithProjectGroup(originWithGroupA, projectGroupB), originWithGroupAB); -} + string projectGroup; + EXPECT_EQ(virtualEnvUtil.buildWithProjectGroup(origin, string()), origin); -TEST(virtualEnvUtil, clearProjectGroup) { - string origin = "origin"; - string originWithGroup = "origin%PROJECT_testGroup%"; - string projectGroup = "testGroup"; - string projectGroupB = "testGroupB"; - EXPECT_EQ(VirtualEnvUtil::clearProjectGroup(origin, string()), origin); - EXPECT_EQ(VirtualEnvUtil::clearProjectGroup(originWithGroup, string()), originWithGroup); - EXPECT_EQ(VirtualEnvUtil::clearProjectGroup(originWithGroup, projectGroupB), originWithGroup); - EXPECT_EQ(VirtualEnvUtil::clearProjectGroup(origin, projectGroup), origin); - EXPECT_EQ(VirtualEnvUtil::clearProjectGroup(originWithGroup, projectGroup), origin); + EXPECT_EQ(virtualEnvUtil.buildWithProjectGroup(origin, string("123")), origin); } +TEST(virtualEnvUtil, clearProjectGroup) {} + int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "virtualEnvUtil.*"; - int iTest = RUN_ALL_TESTS(); - return iTest; + testing::GTEST_FLAG(filter) = "messageExt.init"; + int itestts = RUN_ALL_TESTS(); + return itestts; } diff --git a/test/src/extern/CMessageTest.cpp b/test/src/extern/CMessageTest.cpp index 19d78c203..f6da8fa84 100644 --- a/test/src/extern/CMessageTest.cpp +++ b/test/src/extern/CMessageTest.cpp @@ -27,36 +27,6 @@ using testing::Return; using rocketmq::MQMessage; -TEST(cmessages, originMessage) { - CMessage* message = CreateMessage(NULL); - EXPECT_STREQ(GetOriginMessageTopic(message), ""); - - SetMessageTopic(message, "testTopic"); - EXPECT_STREQ(GetOriginMessageTopic(message), "testTopic"); - - SetMessageTags(message, "testTags"); - EXPECT_STREQ(GetOriginMessageTags(message), "testTags"); - - SetMessageKeys(message, "testKeys"); - EXPECT_STREQ(GetOriginMessageKeys(message), "testKeys"); - - SetMessageBody(message, "testBody"); - EXPECT_STREQ(GetOriginMessageBody(message), "testBody"); - - SetMessageProperty(message, "testKey", "testValue"); - EXPECT_STREQ(GetOriginMessageProperty(message, "testKey"), "testValue"); - - SetDelayTimeLevel(message, 1); - EXPECT_EQ(GetOriginDelayTimeLevel(message), 1); - - EXPECT_EQ(DestroyMessage(message), OK); - - CMessage* message2 = CreateMessage("testTwoTopic"); - EXPECT_STREQ(GetOriginMessageTopic(message2), "testTwoTopic"); - - EXPECT_EQ(DestroyMessage(message2), OK); -} - TEST(cmessages, info) { CMessage* message = CreateMessage(NULL); MQMessage* mqMessage = (MQMessage*)message; @@ -105,7 +75,7 @@ TEST(cmessages, null) { int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); - // testing::GTEST_FLAG(filter) = "cmessages.*"; + testing::GTEST_FLAG(filter) = "cmessages.null"; int itestts = RUN_ALL_TESTS(); return itestts; } diff --git a/test/src/extern/CProducerTest.cpp b/test/src/extern/CProducerTest.cpp index 14f999930..1491e5156 100644 --- a/test/src/extern/CProducerTest.cpp +++ b/test/src/extern/CProducerTest.cpp @@ -67,17 +67,14 @@ void cSendExceptionCallbackFunc(CMQException e) {} TEST(cProducer, SendMessageAsync) { MockDefaultMQProducer* mockProducer = new MockDefaultMQProducer("testGroup"); - CProducer* cProducer = CreateProducer("testGroup"); - // cProducer= mockProducer; - DefaultMQProducer** aProducer = (DefaultMQProducer**)cProducer; - aProducer[0] = mockProducer; + CProducer* cProducer = (CProducer*)mockProducer; CMessage* msg = (CMessage*)new MQMessage(); EXPECT_EQ(SendMessageAsync(NULL, NULL, NULL, NULL), NULL_POINTER); EXPECT_EQ(SendMessageAsync(cProducer, NULL, NULL, NULL), NULL_POINTER); EXPECT_EQ(SendMessageAsync(cProducer, msg, CSendSuccessCallbackFunc, NULL), NULL_POINTER); - // EXPECT_CALL(*mockProducer, send(_, _)).Times(1); + EXPECT_CALL(*mockProducer, send(_, _)).Times(1); EXPECT_EQ(SendMessageAsync(cProducer, msg, CSendSuccessCallbackFunc, cSendExceptionCallbackFunc), OK); Mock::AllowLeak(mockProducer); DestroyMessage(msg); @@ -89,11 +86,7 @@ int QueueSelectorCallbackFunc(int size, CMessage* msg, void* arg) { TEST(cProducer, sendMessageOrderly) { MockDefaultMQProducer* mockProducer = new MockDefaultMQProducer("testGroup"); - // CProducer* cProducer = (CProducer*)mockProducer; - CProducer* cProducer = CreateOrderlyProducer("testGroup"); - // cProducer= mockProducer; - DefaultMQProducer** aProducer = (DefaultMQProducer**)cProducer; - aProducer[0] = mockProducer; + CProducer* cProducer = (CProducer*)mockProducer; CMessage* msg = (CMessage*)new MQMessage(); MQMessageQueue messageQueue; @@ -113,11 +106,7 @@ TEST(cProducer, sendMessageOrderly) { TEST(cProducer, sendOneway) { MockDefaultMQProducer* mockProducer = new MockDefaultMQProducer("testGroup"); - // CProducer* cProducer = (CProducer*)mockProducer; - CProducer* cProducer = CreateProducer("testGroup"); - // cProducer= mockProducer; - DefaultMQProducer** aProducer = (DefaultMQProducer**)cProducer; - aProducer[0] = mockProducer; + CProducer* cProducer = (CProducer*)mockProducer; CMessage* msg = (CMessage*)new MQMessage(); EXPECT_EQ(SendMessageOneway(NULL, NULL), NULL_POINTER); @@ -131,11 +120,8 @@ TEST(cProducer, sendOneway) { TEST(cProducer, sendMessageSync) { MockDefaultMQProducer* mockProducer = new MockDefaultMQProducer("testGroup"); - // CProducer* cProducer = (CProducer*)mockProducer; - CProducer* cProducer = CreateProducer("testGroup"); - // cProducer= mockProducer; - DefaultMQProducer** aProducer = (DefaultMQProducer**)cProducer; - aProducer[0] = mockProducer; + CProducer* cProducer = (CProducer*)mockProducer; + MQMessage* mqMessage = new MQMessage(); CMessage* msg = (CMessage*)mqMessage; CSendResult* result; @@ -176,11 +162,8 @@ TEST(cProducer, sendMessageSync) { TEST(cProducer, infoMock) { MockDefaultMQProducer* mockProducer = new MockDefaultMQProducer("testGroup"); - // CProducer* cProducer = (CProducer*)mockProducer; - CProducer* cProducer = CreateProducer("testGroup"); - // cProducer= mockProducer; - DefaultMQProducer** aProducer = (DefaultMQProducer**)cProducer; - aProducer[0] = mockProducer; + CProducer* cProducer = (CProducer*)mockProducer; + EXPECT_CALL(*mockProducer, start()).Times(1); EXPECT_EQ(StartProducer(cProducer), OK); @@ -197,18 +180,13 @@ TEST(cProducer, infoMock) { TEST(cProducer, info) { CProducer* cProducer = CreateProducer("groupTest"); - // DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)cProducer; - DefaultMQProducer** aProducer = (DefaultMQProducer**)cProducer; - DefaultMQProducer* defaultMQProducer = aProducer[0]; + DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)cProducer; EXPECT_TRUE(cProducer != NULL); EXPECT_EQ(defaultMQProducer->getGroupName(), "groupTest"); EXPECT_EQ(SetProducerNameServerAddress(cProducer, "127.0.0.1:9876"), OK); EXPECT_EQ(defaultMQProducer->getNamesrvAddr(), "127.0.0.1:9876"); - EXPECT_EQ(SetProducerNameServerDomain(cProducer, "domain"), OK); - EXPECT_EQ(defaultMQProducer->getNamesrvDomain(), "domain"); - EXPECT_EQ(SetProducerGroupName(cProducer, "testGroup"), OK); EXPECT_EQ(defaultMQProducer->getGroupName(), "testGroup"); @@ -236,7 +214,6 @@ TEST(cProducer, null) { EXPECT_EQ(StartProducer(NULL), NULL_POINTER); EXPECT_EQ(ShutdownProducer(NULL), NULL_POINTER); EXPECT_EQ(SetProducerNameServerAddress(NULL, NULL), NULL_POINTER); - EXPECT_EQ(SetProducerNameServerDomain(NULL, NULL), NULL_POINTER); EXPECT_EQ(SetProducerGroupName(NULL, NULL), NULL_POINTER); EXPECT_EQ(SetProducerInstanceName(NULL, NULL), NULL_POINTER); EXPECT_EQ(SetProducerSessionCredentials(NULL, NULL, NULL, NULL), NULL_POINTER); diff --git a/test/src/extern/CPullConsumerTest.cpp b/test/src/extern/CPullConsumerTest.cpp index bbdbbae90..b55b99e05 100644 --- a/test/src/extern/CPullConsumerTest.cpp +++ b/test/src/extern/CPullConsumerTest.cpp @@ -65,10 +65,11 @@ TEST(cpullConsumer, pull) { MockDefaultMQPullConsumer* mqPullConsumer = new MockDefaultMQPullConsumer("groudId"); CPullConsumer* pullConsumer = (CPullConsumer*)mqPullConsumer; - CMessageQueue cMessageQueue; - strncpy(cMessageQueue.topic, "testTopic", 8); - strncpy(cMessageQueue.brokerName, "testBroker", 9); - cMessageQueue.queueId = 1; + CMessageQueue* cMessageQueue; + cMessageQueue = (CMessageQueue*)malloc(sizeof(CMessageQueue)); + strncpy(cMessageQueue->topic, "testTopic", 8); + strncpy(cMessageQueue->brokerName, "testBroker", 9); + cMessageQueue->queueId = 1; PullResult timeOutPullResult(PullStatus::BROKER_TIMEOUT, 1, 2, 3); @@ -87,30 +88,34 @@ TEST(cpullConsumer, pull) { } PullResult foundPullResult(PullStatus::FOUND, 1, 2, 3, src); + EXPECT_CALL(*mqPullConsumer, pull(_, _, _, _)) .WillOnce(Return(timeOutPullResult)) .WillOnce(Return(noNewMsgPullResult)) .WillOnce(Return(noMatchedMsgPullResult)) .WillOnce(Return(offsetIllegalPullResult)) .WillOnce(Return(defaultPullResult)) - //.WillOnce(Return(timeOutPullResult)) //will not called - .WillOnce(Return(foundPullResult)); - CPullResult timeOutcPullResult = Pull(pullConsumer, &cMessageQueue, "123123", 0, 0); + /*.WillOnce(Return(timeOutPullResult))*/.WillOnce(Return(foundPullResult)); + + CPullResult timeOutcPullResult = Pull(pullConsumer, cMessageQueue, "123123", 0, 0); EXPECT_EQ(timeOutcPullResult.pullStatus, E_BROKER_TIMEOUT); - CPullResult noNewMsgcPullResult = Pull(pullConsumer, &cMessageQueue, "123123", 0, 0); + + CPullResult noNewMsgcPullResult = Pull(pullConsumer, cMessageQueue, "123123", 0, 0); EXPECT_EQ(noNewMsgcPullResult.pullStatus, E_NO_NEW_MSG); - CPullResult noMatchedMsgcPullResult = Pull(pullConsumer, &cMessageQueue, "123123", 0, 0); + CPullResult noMatchedMsgcPullResult = Pull(pullConsumer, cMessageQueue, "123123", 0, 0); EXPECT_EQ(noMatchedMsgcPullResult.pullStatus, E_NO_MATCHED_MSG); - CPullResult offsetIllegalcPullResult = Pull(pullConsumer, &cMessageQueue, "123123", 0, 0); + CPullResult offsetIllegalcPullResult = Pull(pullConsumer, cMessageQueue, "123123", 0, 0); EXPECT_EQ(offsetIllegalcPullResult.pullStatus, E_OFFSET_ILLEGAL); - CPullResult defaultcPullResult = Pull(pullConsumer, &cMessageQueue, "123123", 0, 0); + CPullResult defaultcPullResult = Pull(pullConsumer, cMessageQueue, "123123", 0, 0); EXPECT_EQ(defaultcPullResult.pullStatus, E_NO_NEW_MSG); - CPullResult exceptionPullResult = Pull(pullConsumer, &cMessageQueue, NULL, 0, 0); + + CPullResult exceptionPullResult = Pull(pullConsumer, cMessageQueue, NULL, 0, 0); EXPECT_EQ(exceptionPullResult.pullStatus, E_BROKER_TIMEOUT); - CPullResult foundcPullResult = Pull(pullConsumer, &cMessageQueue, "123123", 0, 0); + + CPullResult foundcPullResult = Pull(pullConsumer, cMessageQueue, "123123", 0, 0); EXPECT_EQ(foundcPullResult.pullStatus, E_FOUND); delete mqPullConsumer; @@ -158,9 +163,6 @@ TEST(cpullConsumer, init) { EXPECT_EQ(SetPullConsumerNameServerAddress(pullConsumer, "127.0.0.1:10091"), OK); EXPECT_EQ(defaultMQPullConsumer->getNamesrvAddr(), "127.0.0.1:10091"); - EXPECT_EQ(SetPullConsumerNameServerDomain(pullConsumer, "domain"), OK); - EXPECT_EQ(defaultMQPullConsumer->getNamesrvDomain(), "domain"); - EXPECT_EQ(SetPullConsumerSessionCredentials(pullConsumer, "accessKey", "secretKey", "channel"), OK); SessionCredentials sessionCredentials = defaultMQPullConsumer->getSessionCredentials(); EXPECT_EQ(sessionCredentials.getAccessKey(), "accessKey"); @@ -182,9 +184,6 @@ TEST(cpullConsumer, null) { EXPECT_EQ(SetPullConsumerNameServerAddress(pullConsumer, "127.0.0.1:10091"), OK); EXPECT_EQ(defaultMQPullConsumer->getNamesrvAddr(), "127.0.0.1:10091"); - EXPECT_EQ(SetPullConsumerNameServerDomain(pullConsumer, "domain"), OK); - EXPECT_EQ(defaultMQPullConsumer->getNamesrvDomain(), "domain"); - EXPECT_EQ(SetPullConsumerSessionCredentials(pullConsumer, "accessKey", "secretKey", "channel"), OK); SessionCredentials sessionCredentials = defaultMQPullConsumer->getSessionCredentials(); EXPECT_EQ(sessionCredentials.getAccessKey(), "accessKey"); diff --git a/test/src/extern/CPushConsumerTest.cpp b/test/src/extern/CPushConsumerTest.cpp index a2d2fc9fd..498f46f6d 100644 --- a/test/src/extern/CPushConsumerTest.cpp +++ b/test/src/extern/CPushConsumerTest.cpp @@ -88,9 +88,6 @@ TEST(cPushComsumer, info) { EXPECT_EQ(SetPushConsumerNameServerAddress(cpushConsumer, "127.0.0.1:9876"), OK); EXPECT_EQ(mqPushConsumer->getNamesrvAddr(), "127.0.0.1:9876"); - EXPECT_EQ(SetPushConsumerNameServerDomain(cpushConsumer, "domain"), OK); - EXPECT_EQ(mqPushConsumer->getNamesrvDomain(), "domain"); - EXPECT_EQ(Subscribe(cpushConsumer, "testTopic", "testSub"), OK); EXPECT_EQ(RegisterMessageCallbackOrderly(cpushConsumer, MessageCallBackFunc), OK); @@ -131,7 +128,6 @@ TEST(cPushComsumer, null) { EXPECT_EQ(SetPushConsumerGroupID(NULL, "testGroup"), NULL_POINTER); EXPECT_TRUE(GetPushConsumerGroupID(NULL) == NULL); EXPECT_EQ(SetPushConsumerNameServerAddress(NULL, NULL), NULL_POINTER); - EXPECT_EQ(SetPushConsumerNameServerDomain(NULL, NULL), NULL_POINTER); EXPECT_EQ(Subscribe(NULL, NULL, NULL), NULL_POINTER); EXPECT_EQ(RegisterMessageCallbackOrderly(NULL, NULL), NULL_POINTER); EXPECT_EQ(RegisterMessageCallbackOrderly(cpushConsumer, NULL), NULL_POINTER); diff --git a/test/src/message/MQDecoderTest.cpp b/test/src/message/MQDecoderTest.cpp index a92ba10fb..748d89c54 100644 --- a/test/src/message/MQDecoderTest.cpp +++ b/test/src/message/MQDecoderTest.cpp @@ -52,18 +52,17 @@ using rocketmq::SendMessageRequestHeader; using rocketmq::UtilAll; // TODO -TEST(decoder, messageId) { +TEST(decoders, messageId) { int host; int port; - int64 offset = 1234567890; string msgIdStr = - MQDecoder::createMessageId(rocketmq::IPPort2socketAddress(ntohl(inet_addr("127.0.0.1")), 10091), offset); + MQDecoder::createMessageId(rocketmq::IPPort2socketAddress(inet_addr("127.0.0.1"), 10091), (int64)1024); MQMessageId msgId = MQDecoder::decodeMessageId(msgIdStr); - EXPECT_EQ(msgId.getOffset(), offset); + EXPECT_EQ(msgId.getOffset(), 1024); rocketmq::socketAddress2IPPort(msgId.getAddress(), host, port); - EXPECT_EQ(host, ntohl(inet_addr("127.0.0.1"))); + EXPECT_EQ(host, inet_addr("127.0.0.1")); EXPECT_EQ(port, 10091); } @@ -100,16 +99,16 @@ TEST(decoder, decoder) { memoryOut->writeInt64BigEndian((int64)4096); mext.setBornTimestamp(4096); // 10 BORNHOST 56= 48+8 - memoryOut->writeIntBigEndian(ntohl(inet_addr("127.0.0.1"))); + memoryOut->writeIntBigEndian(inet_addr("127.0.0.1")); memoryOut->writeIntBigEndian(10091); - mext.setBornHost(rocketmq::IPPort2socketAddress(ntohl(inet_addr("127.0.0.1")), 10091)); + mext.setBornHost(rocketmq::IPPort2socketAddress(inet_addr("127.0.0.1"), 10091)); // 11 STORETIMESTAMP 64 =56+8 memoryOut->writeInt64BigEndian((int64)4096); mext.setStoreTimestamp(4096); // 12 STOREHOST 72 = 64+8 - memoryOut->writeIntBigEndian(ntohl(inet_addr("127.0.0.2"))); + memoryOut->writeIntBigEndian(inet_addr("127.0.0.2")); memoryOut->writeIntBigEndian(10092); - mext.setStoreHost(rocketmq::IPPort2socketAddress(ntohl(inet_addr("127.0.0.2")), 10092)); + mext.setStoreHost(rocketmq::IPPort2socketAddress(inet_addr("127.0.0.2"), 10092)); // 13 RECONSUMETIMES 76 = 72+4 mext.setReconsumeTimes(111111); memoryOut->writeIntBigEndian(mext.getReconsumeTimes()); diff --git a/test/src/message/MQMessageExtTest.cpp b/test/src/message/MQMessageExtTest.cpp index a1f989afa..df8303d55 100644 --- a/test/src/message/MQMessageExtTest.cpp +++ b/test/src/message/MQMessageExtTest.cpp @@ -132,7 +132,7 @@ TEST(messageExt, init) { int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); - testing::GTEST_FLAG(filter) = "messageExt.*"; + testing::GTEST_FLAG(filter) = "messageExt.init"; int itestts = RUN_ALL_TESTS(); return itestts; } diff --git a/test/src/message/MQMessageTest.cpp b/test/src/message/MQMessageTest.cpp index 100e73eb2..6c0165ac4 100644 --- a/test/src/message/MQMessageTest.cpp +++ b/test/src/message/MQMessageTest.cpp @@ -78,18 +78,16 @@ TEST(message, info) { EXPECT_EQ(message.getTopic(), ""); message.setTopic("testTopic"); EXPECT_EQ(message.getTopic(), "testTopic"); - string topic = "testTopic"; - const char* ctopic = topic.c_str(); - message.setTopic(ctopic, 5); + char* topic = "testTopic"; + message.setTopic(topic, 5); EXPECT_EQ(message.getTopic(), "testT"); EXPECT_EQ(message.getBody(), ""); message.setBody("testBody"); EXPECT_EQ(message.getBody(), "testBody"); - string body = "testBody"; - const char* b = body.c_str(); - message.setBody(b, 5); + char* body = "testBody"; + message.setBody(body, 5); EXPECT_EQ(message.getBody(), "testB"); string tags(message.getTags()); @@ -148,7 +146,7 @@ TEST(message, properties) { int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); - // testing::GTEST_FLAG(filter) = "message.info"; + testing::GTEST_FLAG(filter) = "message.info"; int itestts = RUN_ALL_TESTS(); return itestts; } diff --git a/test/src/protocol/CommandHeaderTest.cpp b/test/src/protocol/CommandHeaderTest.cpp index 6874adf2f..ee19e0e21 100644 --- a/test/src/protocol/CommandHeaderTest.cpp +++ b/test/src/protocol/CommandHeaderTest.cpp @@ -16,6 +16,7 @@ */ #include +#include #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -24,7 +25,11 @@ #include "json/writer.h" #include "CommandHeader.h" +#include "MQClientException.h" +#include "MessageSysFlag.h" +#include "UtilAll.h" #include "dataBlock.h" +#include "json/json.h" using std::shared_ptr; @@ -35,11 +40,9 @@ using testing::Return; using Json::FastWriter; using Json::Value; -using rocketmq::CheckTransactionStateRequestHeader; using rocketmq::CommandHeader; using rocketmq::ConsumerSendMsgBackRequestHeader; using rocketmq::CreateTopicRequestHeader; -using rocketmq::EndTransactionRequestHeader; using rocketmq::GetConsumerListByGroupRequestHeader; using rocketmq::GetConsumerListByGroupResponseBody; using rocketmq::GetConsumerListByGroupResponseHeader; @@ -61,371 +64,12 @@ using rocketmq::ResetOffsetRequestHeader; using rocketmq::SearchOffsetRequestHeader; using rocketmq::SearchOffsetResponseHeader; using rocketmq::SendMessageRequestHeader; -using rocketmq::SendMessageRequestHeaderV2; using rocketmq::SendMessageResponseHeader; using rocketmq::UnregisterClientRequestHeader; using rocketmq::UpdateConsumerOffsetRequestHeader; using rocketmq::ViewMessageRequestHeader; -TEST(commandHeader, ConsumerSendMsgBackRequestHeader) { - string group = "testGroup"; - int delayLevel = 2; - int64 offset = 3027; - bool unitMode = true; - string originMsgId = "testOriginMsgId"; - string originTopic = "testTopic"; - int maxReconsumeTimes = 12; - ConsumerSendMsgBackRequestHeader header; - header.group = group; - header.delayLevel = delayLevel; - header.offset = offset; - header.unitMode = unitMode; - header.originMsgId = originMsgId; - header.originTopic = originTopic; - header.maxReconsumeTimes = maxReconsumeTimes; - map requestMap; - header.SetDeclaredFieldOfCommandHeader(requestMap); - EXPECT_EQ(requestMap["group"], group); - EXPECT_EQ(requestMap["delayLevel"], "2"); - EXPECT_EQ(requestMap["offset"], "3027"); - EXPECT_EQ(requestMap["unitMode"], "1"); - EXPECT_EQ(requestMap["originMsgId"], originMsgId); - EXPECT_EQ(requestMap["originTopic"], originTopic); - EXPECT_EQ(requestMap["maxReconsumeTimes"], "12"); - - Value outData; - header.Encode(outData); - EXPECT_EQ(outData["group"], group); - EXPECT_EQ(outData["delayLevel"], 2); - EXPECT_EQ(outData["offset"], "3027"); - EXPECT_EQ(outData["unitMode"], "1"); - EXPECT_EQ(outData["originMsgId"], originMsgId); - EXPECT_EQ(outData["originTopic"], originTopic); - EXPECT_EQ(outData["maxReconsumeTimes"], 12); -} - -TEST(commandHeader, GetRouteInfoRequestHeader) { - GetRouteInfoRequestHeader header("testTopic"); - map requestMap; - header.SetDeclaredFieldOfCommandHeader(requestMap); - EXPECT_EQ(requestMap["topic"], "testTopic"); - - Value outData; - header.Encode(outData); - EXPECT_EQ(outData["topic"], "testTopic"); -} - -TEST(commandHeader, UnregisterClientRequestHeader) { - UnregisterClientRequestHeader header("testGroup", "testProducer", "testConsumer"); - map requestMap; - header.SetDeclaredFieldOfCommandHeader(requestMap); - EXPECT_EQ(requestMap["clientID"], "testGroup"); - EXPECT_EQ(requestMap["producerGroup"], "testProducer"); - EXPECT_EQ(requestMap["consumerGroup"], "testConsumer"); - - Value outData; - header.Encode(outData); - EXPECT_EQ(outData["clientID"], "testGroup"); - EXPECT_EQ(outData["producerGroup"], "testProducer"); - EXPECT_EQ(outData["consumerGroup"], "testConsumer"); -} - -TEST(commandHeader, CreateTopicRequestHeader) { - string topic = "testTopic"; - string defaultTopic = "defaultTopic"; - int readQueueNums = 4; - int writeQueueNums = 6; - int perm = 8; - string topicFilterType = "filterType"; - CreateTopicRequestHeader header; - header.topic = topic; - header.defaultTopic = defaultTopic; - header.readQueueNums = readQueueNums; - header.writeQueueNums = writeQueueNums; - header.perm = perm; - header.topicFilterType = topicFilterType; - map requestMap; - header.SetDeclaredFieldOfCommandHeader(requestMap); - EXPECT_EQ(requestMap["topic"], topic); - EXPECT_EQ(requestMap["defaultTopic"], defaultTopic); - EXPECT_EQ(requestMap["readQueueNums"], "4"); - EXPECT_EQ(requestMap["writeQueueNums"], "6"); - EXPECT_EQ(requestMap["perm"], "8"); - EXPECT_EQ(requestMap["topicFilterType"], topicFilterType); - - Value outData; - header.Encode(outData); - EXPECT_EQ(outData["topic"], topic); - EXPECT_EQ(outData["defaultTopic"], defaultTopic); - EXPECT_EQ(outData["readQueueNums"], readQueueNums); - EXPECT_EQ(outData["writeQueueNums"], writeQueueNums); - EXPECT_EQ(outData["perm"], perm); - EXPECT_EQ(outData["topicFilterType"], topicFilterType); -} - -TEST(commandHeader, CheckTransactionStateRequestHeader) { - CheckTransactionStateRequestHeader header(2000, 1000, "ABC", "DEF", "GHI"); - map requestMap; - header.SetDeclaredFieldOfCommandHeader(requestMap); - EXPECT_EQ(requestMap["msgId"], "ABC"); - EXPECT_EQ(requestMap["transactionId"], "DEF"); - EXPECT_EQ(requestMap["offsetMsgId"], "GHI"); - EXPECT_EQ(requestMap["commitLogOffset"], "1000"); - EXPECT_EQ(requestMap["tranStateTableOffset"], "2000"); - - Value value; - value["msgId"] = "ABC"; - value["transactionId"] = "DEF"; - value["offsetMsgId"] = "GHI"; - value["commitLogOffset"] = "1000"; - value["tranStateTableOffset"] = "2000"; - shared_ptr headerDecode( - static_cast(CheckTransactionStateRequestHeader::Decode(value))); - EXPECT_EQ(headerDecode->m_msgId, "ABC"); - EXPECT_EQ(headerDecode->m_commitLogOffset, 1000); - EXPECT_EQ(headerDecode->m_tranStateTableOffset, 2000); - EXPECT_EQ(headerDecode->toString(), header.toString()); -} - -TEST(commandHeader, EndTransactionRequestHeader) { - EndTransactionRequestHeader header("testProducer", 1000, 2000, 3000, true, "ABC", "DEF"); - map requestMap; - header.SetDeclaredFieldOfCommandHeader(requestMap); - EXPECT_EQ(requestMap["msgId"], "ABC"); - EXPECT_EQ(requestMap["transactionId"], "DEF"); - EXPECT_EQ(requestMap["producerGroup"], "testProducer"); - EXPECT_EQ(requestMap["tranStateTableOffset"], "1000"); - EXPECT_EQ(requestMap["commitLogOffset"], "2000"); - EXPECT_EQ(requestMap["commitOrRollback"], "3000"); - EXPECT_EQ(requestMap["fromTransactionCheck"], "1"); - - Value outData; - header.Encode(outData); - EXPECT_EQ(outData["msgId"], "ABC"); - EXPECT_EQ(outData["transactionId"], "DEF"); - EXPECT_EQ(outData["producerGroup"], "testProducer"); - EXPECT_EQ(outData["tranStateTableOffset"], "1000"); - EXPECT_EQ(outData["commitLogOffset"], "2000"); - EXPECT_EQ(outData["commitOrRollback"], "3000"); - EXPECT_EQ(outData["fromTransactionCheck"], "1"); - - EXPECT_NO_THROW(header.toString()); -} - -TEST(commandHeader, SendMessageRequestHeader) { - string producerGroup = "testProducer"; - string topic = "testTopic"; - string defaultTopic = "defaultTopic"; - int defaultTopicQueueNums = 1; - int queueId = 2; - int sysFlag = 3; - int64 bornTimestamp = 4; - int flag = 5; - string properties = "testProperty"; - int reconsumeTimes = 6; - bool unitMode = true; - bool batch = false; - - SendMessageRequestHeader header; - header.producerGroup = producerGroup; - header.topic = topic; - header.defaultTopic = defaultTopic; - header.defaultTopicQueueNums = defaultTopicQueueNums; - header.queueId = queueId; - header.sysFlag = sysFlag; - header.bornTimestamp = bornTimestamp; - header.flag = flag; - header.properties = properties; - header.reconsumeTimes = reconsumeTimes; - header.unitMode = unitMode; - header.batch = batch; - map requestMap; - header.SetDeclaredFieldOfCommandHeader(requestMap); - EXPECT_EQ(requestMap["topic"], topic); - EXPECT_EQ(requestMap["producerGroup"], producerGroup); - EXPECT_EQ(requestMap["defaultTopic"], defaultTopic); - EXPECT_EQ(requestMap["defaultTopicQueueNums"], "1"); - EXPECT_EQ(requestMap["queueId"], "2"); - EXPECT_EQ(requestMap["sysFlag"], "3"); - EXPECT_EQ(requestMap["bornTimestamp"], "4"); - EXPECT_EQ(requestMap["flag"], "5"); - EXPECT_EQ(requestMap["properties"], properties); - EXPECT_EQ(requestMap["reconsumeTimes"], "6"); - EXPECT_EQ(requestMap["unitMode"], "1"); - EXPECT_EQ(requestMap["batch"], "0"); - - Value outData; - header.Encode(outData); - EXPECT_EQ(outData["topic"], topic); - EXPECT_EQ(outData["producerGroup"], producerGroup); - EXPECT_EQ(outData["defaultTopic"], defaultTopic); - EXPECT_EQ(outData["defaultTopicQueueNums"], defaultTopicQueueNums); - EXPECT_EQ(outData["queueId"], queueId); - EXPECT_EQ(outData["sysFlag"], sysFlag); - EXPECT_EQ(outData["bornTimestamp"], "4"); - EXPECT_EQ(outData["flag"], flag); - EXPECT_EQ(outData["properties"], properties); - EXPECT_EQ(outData["reconsumeTimes"], "6"); - EXPECT_EQ(outData["unitMode"], "1"); - EXPECT_EQ(outData["batch"], "0"); -} - -TEST(commandHeader, SendMessageRequestHeaderV2) { - string producerGroup = "testProducer"; - string topic = "testTopic"; - string defaultTopic = "defaultTopic"; - int defaultTopicQueueNums = 1; - int queueId = 2; - int sysFlag = 3; - int64 bornTimestamp = 4; - int flag = 5; - string properties = "testProperty"; - int reconsumeTimes = 6; - bool unitMode = true; - bool batch = false; - - SendMessageRequestHeaderV2 header; - header.a = producerGroup; - header.b = topic; - header.c = defaultTopic; - header.d = defaultTopicQueueNums; - header.e = queueId; - header.f = sysFlag; - header.g = bornTimestamp; - header.h = flag; - header.i = properties; - header.j = reconsumeTimes; - header.k = unitMode; - header.m = batch; - map requestMap; - header.SetDeclaredFieldOfCommandHeader(requestMap); - EXPECT_EQ(requestMap["a"], producerGroup); - EXPECT_EQ(requestMap["b"], topic); - EXPECT_EQ(requestMap["c"], defaultTopic); - EXPECT_EQ(requestMap["d"], "1"); - EXPECT_EQ(requestMap["e"], "2"); - EXPECT_EQ(requestMap["f"], "3"); - EXPECT_EQ(requestMap["g"], "4"); - EXPECT_EQ(requestMap["h"], "5"); - EXPECT_EQ(requestMap["i"], properties); - EXPECT_EQ(requestMap["j"], "6"); - EXPECT_EQ(requestMap["k"], "1"); - EXPECT_EQ(requestMap["m"], "0"); - - Value outData; - header.Encode(outData); - EXPECT_EQ(outData["a"], producerGroup); - EXPECT_EQ(outData["b"], topic); - EXPECT_EQ(outData["c"], defaultTopic); - EXPECT_EQ(outData["d"], defaultTopicQueueNums); - EXPECT_EQ(outData["e"], queueId); - EXPECT_EQ(outData["f"], sysFlag); - EXPECT_EQ(outData["g"], "4"); - EXPECT_EQ(outData["h"], flag); - EXPECT_EQ(outData["i"], properties); - EXPECT_EQ(outData["j"], "6"); - EXPECT_EQ(outData["k"], "1"); - EXPECT_EQ(outData["m"], "0"); - - SendMessageRequestHeader v1; - header.CreateSendMessageRequestHeaderV1(v1); - EXPECT_EQ(v1.producerGroup, producerGroup); - EXPECT_EQ(v1.queueId, queueId); - EXPECT_EQ(v1.batch, batch); - - SendMessageRequestHeaderV2 v2(v1); - EXPECT_EQ(header.a, v2.a); - EXPECT_EQ(header.e, v2.e); - EXPECT_EQ(header.m, v2.m); - EXPECT_EQ(header.g, v2.g); -} - -TEST(commandHeader, SendMessageResponseHeader) { - SendMessageResponseHeader header; - header.msgId = "ABCDEFG"; - header.queueId = 1; - header.queueOffset = 2; - map requestMap; - header.SetDeclaredFieldOfCommandHeader(requestMap); - EXPECT_EQ(requestMap["msgId"], "ABCDEFG"); - EXPECT_EQ(requestMap["queueId"], "1"); - EXPECT_EQ(requestMap["queueOffset"], "2"); - - Value value; - value["msgId"] = "EFGHIJK"; - value["queueId"] = "3"; - value["queueOffset"] = "4"; - shared_ptr headerDecode( - static_cast(SendMessageResponseHeader::Decode(value))); - EXPECT_EQ(headerDecode->msgId, "EFGHIJK"); - EXPECT_EQ(headerDecode->queueId, 3); - EXPECT_EQ(headerDecode->queueOffset, 4); -} - -TEST(commandHeader, PullMessageRequestHeader) { - PullMessageRequestHeader header; - header.consumerGroup = "testConsumer"; - header.topic = "testTopic"; - header.queueId = 1; - header.maxMsgNums = 2; - header.sysFlag = 3; - header.subscription = "testSub"; - header.queueOffset = 4; - header.commitOffset = 5; - header.suspendTimeoutMillis = 6; - header.subVersion = 7; - map requestMap; - header.SetDeclaredFieldOfCommandHeader(requestMap); - EXPECT_EQ(requestMap["consumerGroup"], "testConsumer"); - EXPECT_EQ(requestMap["topic"], "testTopic"); - EXPECT_EQ(requestMap["queueId"], "1"); - EXPECT_EQ(requestMap["maxMsgNums"], "2"); - EXPECT_EQ(requestMap["sysFlag"], "3"); - EXPECT_EQ(requestMap["subscription"], "testSub"); - EXPECT_EQ(requestMap["queueOffset"], "4"); - EXPECT_EQ(requestMap["commitOffset"], "5"); - EXPECT_EQ(requestMap["suspendTimeoutMillis"], "6"); - EXPECT_EQ(requestMap["subVersion"], "7"); - - Value outData; - header.Encode(outData); - EXPECT_EQ(outData["consumerGroup"], "testConsumer"); - EXPECT_EQ(outData["topic"], "testTopic"); - EXPECT_EQ(outData["queueId"], 1); - EXPECT_EQ(outData["maxMsgNums"], 2); - EXPECT_EQ(outData["sysFlag"], 3); - EXPECT_EQ(outData["subscription"], "testSub"); - EXPECT_EQ(outData["queueOffset"], "4"); - EXPECT_EQ(outData["commitOffset"], "5"); - EXPECT_EQ(outData["suspendTimeoutMillis"], "6"); - EXPECT_EQ(outData["subVersion"], "7"); -} - -TEST(commandHeader, PullMessageResponseHeader) { - PullMessageResponseHeader header; - header.suggestWhichBrokerId = 100; - header.nextBeginOffset = 200; - header.minOffset = 3000; - header.maxOffset = 5000; - map requestMap; - header.SetDeclaredFieldOfCommandHeader(requestMap); - EXPECT_EQ(requestMap["suggestWhichBrokerId"], "100"); - EXPECT_EQ(requestMap["nextBeginOffset"], "200"); - EXPECT_EQ(requestMap["minOffset"], "3000"); - EXPECT_EQ(requestMap["maxOffset"], "5000"); - - Value value; - value["suggestWhichBrokerId"] = "5"; - value["nextBeginOffset"] = "102400"; - value["minOffset"] = "1"; - value["maxOffset"] = "123456789"; - shared_ptr headerDecode( - static_cast(PullMessageResponseHeader::Decode(value))); - EXPECT_EQ(headerDecode->suggestWhichBrokerId, 5); - EXPECT_EQ(headerDecode->nextBeginOffset, 102400); - EXPECT_EQ(headerDecode->minOffset, 1); - EXPECT_EQ(headerDecode->maxOffset, 123456789); -} +TEST(commandHeader, ConsumerSendMsgBackRequestHeader) {} TEST(commandHeader, GetConsumerListByGroupResponseBody) { Value value; diff --git a/test/src/protocol/ConsumerRunningInfoTest.cpp b/test/src/protocol/ConsumerRunningInfoTest.cpp index 70b305f11..fbea4b289 100644 --- a/test/src/protocol/ConsumerRunningInfoTest.cpp +++ b/test/src/protocol/ConsumerRunningInfoTest.cpp @@ -44,72 +44,81 @@ using rocketmq::MessageQueue; using rocketmq::ProcessQueueInfo; using rocketmq::SubscriptionData; -TEST(ConsumerRunningInfo, init) { - ConsumerRunningInfo info; +TEST(consumerRunningInfo, init) { + ConsumerRunningInfo consumerRunningInfo; + consumerRunningInfo.setJstack("jstack"); + EXPECT_EQ(consumerRunningInfo.getJstack(), "jstack"); - // jstack - info.setJstack("jstack"); - EXPECT_EQ(info.getJstack(), "jstack"); + EXPECT_TRUE(consumerRunningInfo.getProperties().empty()); - // property - EXPECT_TRUE(info.getProperties().empty()); - info.setProperty("testKey", "testValue"); - map properties = info.getProperties(); + consumerRunningInfo.setProperty("testKey", "testValue"); + map properties = consumerRunningInfo.getProperties(); EXPECT_EQ(properties["testKey"], "testValue"); - info.setProperties(map()); - EXPECT_TRUE(info.getProperties().empty()); - info.setProperty("testKey", "testValue"); - map properties2 = info.getProperties(); - EXPECT_EQ(properties2["testKey"], "testValue"); - - // subscription - EXPECT_TRUE(info.getSubscriptionSet().empty()); + + consumerRunningInfo.setProperties(map()); + EXPECT_TRUE(consumerRunningInfo.getProperties().empty()); + + EXPECT_TRUE(consumerRunningInfo.getSubscriptionSet().empty()); + vector subscriptionSet; - SubscriptionData sData1("testTopic", "testSub"); - sData1.putTagsSet("testTag"); - sData1.putCodeSet("11234"); - subscriptionSet.push_back(sData1); - SubscriptionData sData2("testTopic2", "testSub2"); - sData2.putTagsSet("testTag2"); - sData2.putCodeSet("21234"); - subscriptionSet.push_back(sData2); - info.setSubscriptionSet(subscriptionSet); - EXPECT_EQ(info.getSubscriptionSet().size(), 2); - - // mqtable - EXPECT_TRUE(info.getMqTable().empty()); - - MessageQueue messageQueue1("testTopic", "testBrokerA", 3); - ProcessQueueInfo processQueueInfo1; - processQueueInfo1.commitOffset = 1024; - info.setMqTable(messageQueue1, processQueueInfo1); - MessageQueue messageQueue2("testTopic", "testBrokerB", 4); - ProcessQueueInfo processQueueInfo2; - processQueueInfo2.cachedMsgCount = 1023; - info.setMqTable(messageQueue2, processQueueInfo2); - map mqTable = info.getMqTable(); - EXPECT_EQ(mqTable.size(), 2); - EXPECT_EQ(mqTable[messageQueue1].commitOffset, 1024); - EXPECT_EQ(mqTable[messageQueue2].cachedMsgCount, 1023); + subscriptionSet.push_back(SubscriptionData()); + + consumerRunningInfo.setSubscriptionSet(subscriptionSet); + EXPECT_EQ(consumerRunningInfo.getSubscriptionSet().size(), 1); + + EXPECT_TRUE(consumerRunningInfo.getMqTable().empty()); + + MessageQueue messageQueue("testTopic", "testBroker", 3); + ProcessQueueInfo processQueueInfo; + processQueueInfo.commitOffset = 1024; + consumerRunningInfo.setMqTable(messageQueue, processQueueInfo); + map mqTable = consumerRunningInfo.getMqTable(); + EXPECT_EQ(mqTable[messageQueue].commitOffset, processQueueInfo.commitOffset); // encode start - info.setProperty(ConsumerRunningInfo::PROP_NAMESERVER_ADDR, "127.0.0.1:9876"); - info.setProperty(ConsumerRunningInfo::PROP_THREADPOOL_CORE_SIZE, "core_size"); - info.setProperty(ConsumerRunningInfo::PROP_CONSUME_ORDERLY, "consume_orderly"); - info.setProperty(ConsumerRunningInfo::PROP_CONSUME_TYPE, "consume_type"); - info.setProperty(ConsumerRunningInfo::PROP_CLIENT_VERSION, "client_version"); - info.setProperty(ConsumerRunningInfo::PROP_CONSUMER_START_TIMESTAMP, "127"); - - // encode - string outStr = info.encode(); - EXPECT_GT(outStr.length(), 1); - EXPECT_NE(outStr.find("testTopic"), string::npos); + consumerRunningInfo.setProperty(ConsumerRunningInfo::PROP_NAMESERVER_ADDR, "127.0.0.1:9876"); + consumerRunningInfo.setProperty(ConsumerRunningInfo::PROP_THREADPOOL_CORE_SIZE, "core_size"); + consumerRunningInfo.setProperty(ConsumerRunningInfo::PROP_CONSUME_ORDERLY, "consume_orderly"); + consumerRunningInfo.setProperty(ConsumerRunningInfo::PROP_CONSUME_TYPE, "consume_type"); + consumerRunningInfo.setProperty(ConsumerRunningInfo::PROP_CLIENT_VERSION, "client_version"); + consumerRunningInfo.setProperty(ConsumerRunningInfo::PROP_CONSUMER_START_TIMESTAMP, "127"); + // TODO + /* string outstr = consumerRunningInfo.encode(); + std::cout<< outstr; + Value root; + Reader reader; + reader.parse(outstr.c_str(), root); + + EXPECT_EQ(root["jstack"].asString() , "jstack"); + + Json::Value outData = root["properties"]; + EXPECT_EQ(outData[ConsumerRunningInfo::PROP_NAMESERVER_ADDR].asString(),"127.0.0.1:9876"); + EXPECT_EQ( + outData[ConsumerRunningInfo::PROP_THREADPOOL_CORE_SIZE].asString(), + "core_size"); + EXPECT_EQ(outData[ConsumerRunningInfo::PROP_CONSUME_ORDERLY].asString(), + "consume_orderly"); + EXPECT_EQ(outData[ConsumerRunningInfo::PROP_CONSUME_TYPE].asString(), + "consume_type"); + EXPECT_EQ(outData[ConsumerRunningInfo::PROP_CLIENT_VERSION].asString(), + "client_version"); + EXPECT_EQ( + outData[ConsumerRunningInfo::PROP_CONSUMER_START_TIMESTAMP].asString(), + "127"); + + Json::Value subscriptionSetJson = root["subscriptionSet"]; + EXPECT_EQ(subscriptionSetJson[0], subscriptionSet[0].toJson()); + + Json::Value mqTableJson = root["mqTable"]; + EXPECT_EQ(mqTableJson[messageQueue.toJson().toStyledString()].asString(), + processQueueInfo.toJson().toStyledString()); +*/ } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "ConsumerRunningInfo.*"; - int iTests = RUN_ALL_TESTS(); - return iTests; + testing::GTEST_FLAG(filter) = "consumerRunningInfo.*"; + int itestts = RUN_ALL_TESTS(); + return itestts; } diff --git a/test/src/protocol/LockBatchBodyTest.cpp b/test/src/protocol/LockBatchBodyTest.cpp index 81f5e4f9a..9f8f3009f 100644 --- a/test/src/protocol/LockBatchBodyTest.cpp +++ b/test/src/protocol/LockBatchBodyTest.cpp @@ -67,27 +67,7 @@ TEST(lockBatchBody, LockBatchRequestBody) { EXPECT_EQ(root["consumerGroup"], "testGroup"); } -TEST(lockBatchBody, UnlockBatchRequestBody) { - UnlockBatchRequestBody uRB; - uRB.setClientId("testClient"); - EXPECT_EQ(uRB.getClientId(), "testClient"); - uRB.setConsumerGroup("testGroup"); - EXPECT_EQ(uRB.getConsumerGroup(), "testGroup"); - - // message queue - EXPECT_TRUE(uRB.getMqSet().empty()); - vector mqs; - MQMessageQueue mqA("testTopic", "testBrokerA", 1); - mqs.push_back(mqA); - MQMessageQueue mqB("testTopic", "testBrokerB", 2); - mqs.push_back(mqB); - uRB.setMqSet(mqs); - EXPECT_EQ(uRB.getMqSet().size(), 2); - string outData; - uRB.Encode(outData); - EXPECT_GT(outData.length(), 1); - EXPECT_NE(outData.find("testTopic"), string::npos); -} +TEST(lockBatchBody, UnlockBatchRequestBody) {} TEST(lockBatchBody, LockBatchResponseBody) { Json::Value root; diff --git a/test/src/transport/ClientRemotingProcessorTest.cpp b/test/src/transport/ClientRemotingProcessorTest.cpp index 3664d893f..5c906ebde 100644 --- a/test/src/transport/ClientRemotingProcessorTest.cpp +++ b/test/src/transport/ClientRemotingProcessorTest.cpp @@ -164,9 +164,8 @@ TEST(clientRemotingProcessor, resetOffset) { delete request; } -TEST(clientRemotingProcessor, getConsumerRunningInfoFailed) { +TEST(clientRemotingProcessorS, getConsumerRunningInfo) { MockMQClientFactory* factory = new MockMQClientFactory("testClientId", 4, 3000, 4000, "a"); - Mock::AllowLeak(factory); ConsumerRunningInfo* info = new ConsumerRunningInfo(); EXPECT_CALL(*factory, consumerRunningInfo(_)).Times(2).WillOnce(Return(info)).WillOnce(Return(info)); EXPECT_CALL(*factory, getSessionCredentialFromConsumer(_, _)) @@ -175,8 +174,6 @@ TEST(clientRemotingProcessor, getConsumerRunningInfoFailed) { GetConsumerRunningInfoRequestHeader* header = new GetConsumerRunningInfoRequestHeader(); header->setConsumerGroup("testGroup"); - header->setClientId("testClientId"); - header->setJstackEnable(false); RemotingCommand* request = new RemotingCommand(14, header); From 11bf3963c17de5c8ae82a8c8e3453bef8481b960 Mon Sep 17 00:00:00 2001 From: James Yin Date: Sat, 9 May 2020 17:04:22 +0800 Subject: [PATCH 02/62] feat: support Request-Reply. (#299) * rename for Camel-Case. * remove useless code. * access MQClientConfig by Proxy. * aliasing std::shared_ptr by RPCHookPtr. * expose "DataBlock.h" in include directory. * polish C api. * polish std::shared_ptr. * polish std::map. * polish MQException. * fixed typo. * polish SocketUtil. * feat: support Request-Reply. * pullTimeDelayMillsWhenException in PushConsumer * polish sockaddr. * polish network callback api. * polish MQProtos.h * fixed submitConsumeRequestLater. * polish ServiceState variable. * polish MQClientAPIImpl. * polish MQMessageListener * polish MQClientInstance * include missing header * use platform-independent type by cstdint * polish cmake script files. * fixed struct sockaddr * fixed missing header * update build.sh * fast return when select mq. * polish TopicPublishInfo. * fixed regex in Validatoors * polish pull message when slave no latest msg. * gcc 4.8 have regex bug. * polish TcpTransport * polish findConsumerIds * fixed memory leak in concurrent lib * polish BufferEvent * change log * fixed MQDecoder::createMessageId * update unit test * add coverage to CMakeLists.txt * polish TcpRemotingClient::CreateTransport * fixed TcpTransport * update CMakeLists.txt * update clang-format scripts --- .travis.yml | 4 +- .travis/check-git-clang-format.sh | 11 +- CMakeLists.txt | 179 +++--- build.sh | 137 ++-- cmake/BundleStaticLibrary.cmake | 2 +- cmake/FindJsoncpp.cmake | 59 +- cmake/FindLibevent.cmake | 26 +- example/AsyncProducer.cpp | 2 +- example/BatchProducer.cpp | 2 +- example/CMakeLists.txt | 26 +- example/OrderlyProducer.cpp | 2 +- example/PullConsumer.cpp | 2 +- example/PushConsumer.cpp | 2 +- example/RequestReply.cpp | 114 ++++ example/SyncProducer.cpp | 2 +- example/TransactionProducer.cpp | 2 +- example/common.h | 2 +- format.sh | 53 +- {src/common => include}/DataBlock.h | 18 +- include/DefaultMQProducer.h | 67 +- include/DefaultMQProducerConfig.h | 65 ++ include/DefaultMQProducerConfigProxy.h | 80 +++ include/DefaultMQPullConsumer.h | 18 +- include/DefaultMQPullConsumerConfig.h | 42 ++ include/DefaultMQPullConsumerConfigProxy.h | 48 ++ include/DefaultMQPushConsumer.h | 74 +-- include/DefaultMQPushConsumerConfig.h | 76 +++ include/DefaultMQPushConsumerConfigProxy.h | 96 +++ include/MQClientConfig.h | 71 +- include/MQClientConfigProxy.h | 73 +++ include/MQClientException.h | 101 ++- include/MQMessage.h | 1 + include/MQMessageConst.h | 7 + include/MQMessageExt.h | 17 +- include/MQMessageListener.h | 24 +- include/MQMessageQueue.h | 2 + include/MQProducer.h | 3 + include/MQPushConsumer.h | 2 + .../{DefaultMQConsumer.h => MessageUtil.h} | 23 +- include/PullResult.h | 11 +- include/RemotingCommand.h | 12 +- include/RequestCallback.h | 48 ++ include/RocketMQClient.h | 24 - include/SendCallback.h | 4 +- include/SessionCredentials.h | 6 + include/TransactionMQProducer.h | 23 +- include/TransactionMQProducerConfig.h | 39 ++ include/c/CMessage.h | 1 - include/c/CMessageExt.h | 1 - include/c/CProducer.h | 13 +- include/c/CPushConsumer.h | 5 +- package_rocketmq.mri | 22 - project/CMakeLists.txt | 25 +- src/ClientRemotingProcessor.cpp | 187 ++++-- src/ClientRemotingProcessor.h | 21 +- src/MQAdminImpl.cpp | 42 +- src/MQAdminImpl.h | 6 +- src/MQClientAPIImpl.cpp | 104 +-- src/MQClientAPIImpl.h | 19 +- ...lientConfig.cpp => MQClientConfigImpl.cpp} | 50 +- src/MQClientConfigImpl.h | 70 ++ src/MQClientImpl.cpp | 32 +- src/MQClientImpl.h | 18 +- src/MQClientInstance.cpp | 244 ++++--- src/MQClientInstance.h | 21 +- src/MQClientManager.cpp | 16 +- src/MQClientManager.h | 4 +- src/common/ClientErrorCode.h | 35 + src/common/ClientRPCHook.cpp | 19 +- src/common/DataBlock.cpp | 2 +- src/common/InputStream.cpp | 4 +- src/common/InputStream.h | 10 +- src/common/MQVersion.cpp | 4 +- src/common/MQVersion.h | 606 +----------------- src/common/MemoryInputStream.h | 9 +- src/common/MemoryOutputStream.cpp | 6 +- src/common/MemoryOutputStream.h | 11 +- src/common/NamesrvConfig.h | 14 +- src/common/OutputStream.cpp | 2 +- src/common/OutputStream.h | 11 +- src/common/SendCallbackWrap.cpp | 10 +- src/common/SubscriptionData.h | 8 +- src/common/TopicConfig.cpp | 2 +- src/common/UtilAll.cpp | 8 +- src/common/UtilAll.h | 4 + src/common/Validators.cpp | 32 +- src/concurrent/concurrent_queue.hpp | 15 +- src/concurrent/executor.hpp | 2 +- src/concurrent/executor_impl.hpp | 9 +- src/consumer/AllocateMQAveragely.h | 7 +- .../ConsumeMessageConcurrentlyService.cpp | 109 ++-- src/consumer/ConsumeMessageOrderlyService.cpp | 4 +- src/consumer/DefaultMQPullConsumer.cpp | 8 +- src/consumer/DefaultMQPullConsumerImpl.cpp | 5 +- src/consumer/DefaultMQPushConsumer.cpp | 27 +- .../DefaultMQPushConsumerConfigImpl.cpp | 125 ++++ .../DefaultMQPushConsumerConfigImpl.h | 81 +++ src/consumer/DefaultMQPushConsumerImpl.cpp | 41 +- src/consumer/DefaultMQPushConsumerImpl.h | 12 +- src/consumer/MessageQueueLock.hpp | 8 +- src/consumer/OffsetStore.cpp | 25 +- src/consumer/ProcessQueue.cpp | 9 +- src/consumer/PullAPIWrapper.cpp | 9 +- ...essageService.h => PullMessageService.hpp} | 9 +- src/consumer/PullResult.cpp | 12 + src/consumer/PullResultExt.h | 2 +- src/consumer/RebalanceImpl.cpp | 39 +- src/consumer/RebalanceImpl.h | 4 +- src/consumer/RebalancePushImpl.cpp | 2 +- src/consumer/SubscriptionData.cpp | 2 +- src/extern/CBatchMessage.cpp | 14 +- src/extern/CMessage.cpp | 64 +- src/extern/CMessageExt.cpp | 30 +- src/extern/CProducer.cpp | 240 ++++--- src/extern/CPullConsumer.cpp | 4 +- src/extern/CPushConsumer.cpp | 84 +-- src/message/MQDecoder.cpp | 26 +- src/message/MQDecoder.h | 3 +- src/message/MQMessage.cpp | 16 +- src/message/MQMessageExt.cpp | 49 +- src/message/MQMessageId.h | 14 +- src/message/MessageUtil.cpp | 60 ++ src/producer/CorrelationIdUtil.hpp | 37 ++ src/producer/DefaultMQProducer.cpp | 34 +- src/producer/DefaultMQProducerConfigImpl.cpp | 88 +++ src/producer/DefaultMQProducerConfigImpl.h | 63 ++ src/producer/DefaultMQProducerImpl.cpp | 130 +++- src/producer/DefaultMQProducerImpl.h | 16 +- src/producer/LatencyFaultTolerancyImpl.cpp | 2 +- src/producer/MQFaultStrategy.cpp | 6 +- src/producer/MQFaultStrategy.h | 2 +- src/producer/RequestFutureTable.cpp | 40 ++ src/producer/RequestFutureTable.h | 40 ++ src/producer/RequestResponseFuture.cpp | 104 +++ src/producer/RequestResponseFuture.h | 60 ++ src/producer/TopicPublishInfo.h | 53 +- src/producer/TransactionMQProducer.cpp | 29 +- .../TransactionMQProducerConfigImpl.cpp | 31 + .../TransactionMQProducerConfigImpl.h | 40 ++ src/protocol/MQProtos.h | 180 +----- src/protocol/ProcessQueueInfo.h | 1 - src/protocol/RemotingCommand.cpp | 37 +- src/protocol/RemotingSerializable.cpp | 1 + src/protocol/RequestCode.h | 144 +++++ src/protocol/ResponseCode.h | 74 +++ src/protocol/TopicRouteData.h | 27 +- src/protocol/{ => body}/LockBatchBody.cpp | 0 src/protocol/{ => body}/LockBatchBody.h | 0 src/protocol/body/ResetOffsetBody.cpp | 45 ++ src/protocol/body/ResetOffsetBody.h | 40 ++ src/protocol/{ => header}/CommandHeader.cpp | 38 +- src/protocol/{ => header}/CommandHeader.h | 10 +- .../header/ReplyMessageRequestHeader.cpp | 175 +++++ .../header/ReplyMessageRequestHeader.h | 92 +++ src/transport/EventLoop.cpp | 124 +--- src/transport/EventLoop.h | 42 +- src/transport/RequestProcessor.h | 3 +- src/transport/ResponseFuture.cpp | 4 +- src/transport/ResponseFuture.h | 8 +- src/transport/SocketUtil.cpp | 156 +++-- src/transport/SocketUtil.h | 13 +- src/transport/TcpRemotingClient.cpp | 382 ++++++----- src/transport/TcpRemotingClient.h | 37 +- src/transport/TcpTransport.cpp | 137 ++-- src/transport/TcpTransport.h | 53 +- test/CMakeLists.txt | 125 ++-- test/src/BatchMessageTest.cpp | 72 --- test/src/common/BigEndianTest.cpp | 85 +++ test/src/common/ClientRPCHookTest.cpp | 33 +- test/src/common/MemoryBlockTest.cpp | 150 ++--- test/src/common/MemoryOutputStreamTest.cpp | 111 ++-- test/src/common/NamesrvConfigTest.cpp | 21 +- .../{PermNametTest.cpp => PermNameTest.cpp} | 15 +- test/src/common/PullSysFlagTest.cpp | 15 +- test/src/common/TopicConfigTest.cpp | 26 +- test/src/common/ValidatorsTest.cpp | 55 +- test/src/common/VirtualEnvUtilTest.cpp | 31 +- test/src/common/big_endianTest.cpp | 100 --- test/src/extern/CMessageExtTest.cpp | 26 +- test/src/extern/CMessageTest.cpp | 34 +- test/src/extern/CProducerTest.cpp | 86 ++- test/src/extern/CPullConsumerTest.cpp | 71 +- test/src/extern/CPushConsumerTest.cpp | 104 ++- test/src/message/MQDecoderTest.cpp | 224 +++---- test/src/message/MQMessageExtTest.cpp | 159 +++-- test/src/message/MQMessageIdTest.cpp | 40 +- test/src/message/MQMessageQueueTest.cpp | 58 +- test/src/message/MQMessageTest.cpp | 85 +-- test/src/message/MessageBatchTest.cpp | 62 ++ .../MessageClientIDSetterTest.cpp} | 28 +- test/src/protocol/CommandHeaderTest.cpp | 131 ++-- test/src/protocol/ConsumerRunningInfoTest.cpp | 35 +- test/src/protocol/HeartbeatDataTest.cpp | 25 +- test/src/protocol/KVTableTest.cpp | 26 +- test/src/protocol/LockBatchBodyTest.cpp | 61 +- test/src/protocol/MessageQueueTest.cpp | 71 +- test/src/protocol/ProcessQueueInfoTest.cpp | 19 +- test/src/protocol/RemotingCommandTest.cpp | 170 ++--- test/src/protocol/TopicRouteDataTest.cpp | 40 +- .../transport/ClientRemotingProcessorTest.cpp | 336 +++++----- test/src/transport/ResponseFutureTest.cpp | 105 +-- test/src/transport/SocketUtilTest.cpp | 34 +- 202 files changed, 5594 insertions(+), 4443 deletions(-) create mode 100644 example/RequestReply.cpp rename {src/common => include}/DataBlock.h (94%) create mode 100644 include/DefaultMQProducerConfig.h create mode 100644 include/DefaultMQProducerConfigProxy.h create mode 100644 include/DefaultMQPullConsumerConfig.h create mode 100644 include/DefaultMQPullConsumerConfigProxy.h create mode 100644 include/DefaultMQPushConsumerConfig.h create mode 100644 include/DefaultMQPushConsumerConfigProxy.h create mode 100644 include/MQClientConfigProxy.h rename include/{DefaultMQConsumer.h => MessageUtil.h} (64%) create mode 100644 include/RequestCallback.h create mode 100644 include/TransactionMQProducerConfig.h delete mode 100644 package_rocketmq.mri rename src/{MQClientConfig.cpp => MQClientConfigImpl.cpp} (65%) create mode 100644 src/MQClientConfigImpl.h create mode 100644 src/common/ClientErrorCode.h create mode 100644 src/consumer/DefaultMQPushConsumerConfigImpl.cpp create mode 100644 src/consumer/DefaultMQPushConsumerConfigImpl.h rename src/consumer/{PullMessageService.h => PullMessageService.hpp} (91%) create mode 100644 src/message/MessageUtil.cpp create mode 100644 src/producer/CorrelationIdUtil.hpp create mode 100644 src/producer/DefaultMQProducerConfigImpl.cpp create mode 100644 src/producer/DefaultMQProducerConfigImpl.h create mode 100644 src/producer/RequestFutureTable.cpp create mode 100644 src/producer/RequestFutureTable.h create mode 100644 src/producer/RequestResponseFuture.cpp create mode 100644 src/producer/RequestResponseFuture.h create mode 100644 src/producer/TransactionMQProducerConfigImpl.cpp create mode 100644 src/producer/TransactionMQProducerConfigImpl.h create mode 100644 src/protocol/RequestCode.h create mode 100644 src/protocol/ResponseCode.h rename src/protocol/{ => body}/LockBatchBody.cpp (100%) rename src/protocol/{ => body}/LockBatchBody.h (100%) create mode 100644 src/protocol/body/ResetOffsetBody.cpp create mode 100644 src/protocol/body/ResetOffsetBody.h rename src/protocol/{ => header}/CommandHeader.cpp (95%) rename src/protocol/{ => header}/CommandHeader.h (98%) create mode 100644 src/protocol/header/ReplyMessageRequestHeader.cpp create mode 100644 src/protocol/header/ReplyMessageRequestHeader.h delete mode 100644 test/src/BatchMessageTest.cpp create mode 100644 test/src/common/BigEndianTest.cpp rename test/src/common/{PermNametTest.cpp => PermNameTest.cpp} (84%) delete mode 100644 test/src/common/big_endianTest.cpp create mode 100644 test/src/message/MessageBatchTest.cpp rename test/src/{StringIdMakerTest.cpp => message/MessageClientIDSetterTest.cpp} (63%) diff --git a/.travis.yml b/.travis.yml index 237b2a44d..75ac46b84 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,8 +52,8 @@ matrix: dist: trusty env: LINT=1 PYTHON=2.7 before_install: - - sudo apt-get update -qq - - sudo apt-get install -qq clang-format-3.8 + - sudo apt-get update + - sudo apt-get install -y clang-format-3.8 install: [] script: - sudo sh .travis/check-git-clang-format.sh diff --git a/.travis/check-git-clang-format.sh b/.travis/check-git-clang-format.sh index b8d3d1ffa..8416fa374 100644 --- a/.travis/check-git-clang-format.sh +++ b/.travis/check-git-clang-format.sh @@ -1,3 +1,6 @@ +#!/usr/bin/env bash + +# 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 @@ -12,17 +15,15 @@ # See the License for the specific language governing permissions and # limitations under the License. -#!/bin/bash - - if [ "$TRAVIS_PULL_REQUEST" = "true" ]; then +if [ "$TRAVIS_PULL_REQUEST" = "true" ]; then base_commit="$TRAVIS_BRANCH" else base_commit="HEAD^" fi - output="$(sudo python .travis/git-clang-format --binary clang-format-3.8 --commit $base_commit --diff)" +output="$(python .travis/git-clang-format --binary clang-format-3.8 --commit $base_commit --diff --style file)" - if [ "$output" = "no modified files to format" ] || [ "$output" = "clang-format did not modify any files" ]; then +if [ "$output" = "no modified files to format" ] || [ "$output" = "clang-format did not modify any files" ]; then echo "clang-format passed." exit 0 else diff --git a/CMakeLists.txt b/CMakeLists.txt index 49e6a4da0..e39910e61 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,10 +15,6 @@ cmake_minimum_required(VERSION 2.8) -if (APPLE) - set(CMAKE_MACOSX_RPATH 1) -endif (APPLE) - # CMake complains if we don't have this. if (COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) @@ -34,103 +30,99 @@ endif () # First, declare project (important for prerequisite checks). project(rocketmq-client-cpp) + if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif () if (NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_CONFIGURATION_TYPES "Release") endif () + set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) + set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) set(CMAKE_VERBOSE_MAKEFILE 1) -option(BUILD_ROCKETMQ_STATIC "build rocketmq-client static library" OFF) -option(BUILD_ROCKETMQ_SHARED "build rocketmq-client shared library" ON) +if (APPLE) + set(CMAKE_MACOSX_RPATH 1) +endif (APPLE) + +# put binaries in a different dir to make them easier to find. +set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) +set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) -# Find dependency +# Find dependencies #find_package(spdlog REQUIRED) +if (NOT spdlog_FOUND) + include_directories(${CMAKE_SOURCE_DIR}/bin/include) +endif () option(Libevent_USE_STATIC_LIBS "only find libevent static libs" OFF) # only find static libs +if (NOT LIBEVENT_ROOT) + set(LIBEVENT_ROOT ${CMAKE_SOURCE_DIR}/bin) +endif () find_package(Libevent 2.0.21 REQUIRED) -include_directories(${LIBEVENT_INCLUDE_DIRS}) message(STATUS "** LIBEVENT_INCLUDE_DIR: ${LIBEVENT_INCLUDE_DIR}") message(STATUS "** LIBEVENT_LIBRARIES: ${LIBEVENT_LIBRARIES}") option(JSONCPP_USE_STATIC_LIBS "only find jsoncpp static libs" OFF) # only find static libs +if (NOT JSONCPP_ROOT) + set(JSONCPP_ROOT ${CMAKE_SOURCE_DIR}/bin) +endif () find_package(Jsoncpp 0.10.6 REQUIRED) -include_directories(${JSONCPP_INCLUDE_DIRS}) message(STATUS "** JSONCPP_INCLUDE_DIRS: ${JSONCPP_INCLUDE_DIRS}") message(STATUS "** JSONCPP_LIBRARIES: ${JSONCPP_LIBRARIES}") -# put binaries in a different dir to make them easier to find. -set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) -set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) - -# for unix, put debug files in a separate bin "debug" dir. -# release bin files should stay in the root of the bin dir. -# if (CMAKE_GENERATOR STREQUAL "Unix Makefiles") -# if (CMAKE_BUILD_TYPE STREQUAL Debug) -# set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/debug) -# set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/debug) -# endif() -# endif() +# Set compile options +include(CheckCCompilerFlag) +include(CheckCXXCompilerFlag) +CHECK_C_COMPILER_FLAG("-std=c99" COMPILER_SUPPORTS_C99) +CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) +if (COMPILER_SUPPORTS_C99 AND COMPILER_SUPPORTS_CXX11) + if (NOT (CMAKE_VERSION VERSION_LESS "3.1")) + set(CMAKE_C_STANDARD 99) + set(CMAKE_CXX_STANDARD 11) + message(STATUS "** set CMAKE_C_STANDARD to 99") + message(STATUS "** set CMAKE_CXX_STANDARD to 11") + else () + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") + set(C_STANDARD_FLAG "-std=gnu99") + set(CXX_STANDARD_FLAG "-std=gnu++11") + else () + set(C_STANDARD_FLAG "-std=c99") + set(CXX_STANDARD_FLAG "-std=c++11") + endif () + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_STANDARD_FLAG}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD_FLAG}") + message(STATUS "** set CMAKE_C_FLAGS with ${C_STANDARD_FLAG}") + message(STATUS "** set CMAKE_CXX_FLAGS with ${CXX_STANDARD_FLAG}") + endif () +else () + message(FATAL_ERROR "The compiler has no C99 or C++11 support.") +endif () -IF (WIN32) +if (WIN32) add_definitions(-DWIN32 -DROCKETMQCLIENT_EXPORTS) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") -ELSE () - set(C_FLAGS - -Wall - -Wno-deprecated - -fPIC - -fno-strict-aliasing - ) - set(CXX_FLAGS - -Wall - -Wno-deprecated - -fPIC - -fno-strict-aliasing - -std=c++11 - -Wno-unused-local-typedef - -Wno-expansion-to-defined - # -finline-limit=1000 - # -Wextra - # -pedantic - # -pedantic-errors - # -D_FILE_OFFSET_BITS=64 - # -DVALGRIND - # -DCHECK_PTHREAD_RETURN_VALUE - # -Werror - # -Wconversion - # -Wno-unused-parameter - # -Wunused-but-set-variable - # -Wold-style-cast - # -Woverloaded-virtual - # -Wpointer-arith - # -Wshadow - # -Wwrite-strings - # -Wdeprecated-declarations - # -march=native - # -MMD - # -std=c++0x - # -rdynamic - ) + add_compile_options(/EHsc) + if (CMAKE_BUILD_TYPE EQUAL "Release") + add_compile_options(/MT) + else () + add_compile_options(/MTd) + endif () +else () + add_compile_options(-Wall + -Wno-deprecated + -fPIC + -fno-strict-aliasing + -Wno-unused-local-typedef + -Wno-expansion-to-defined) if (CMAKE_BUILD_BITS EQUAL 32) - list(APPEND CXX_FLAGS "-m32") + add_compile_options(-m32) else () #not-condition - list(APPEND CXX_FLAGS "-m64") + add_compile_options(-m64) endif () - string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CXX_FLAGS}") - string(REPLACE ";" " " CMAKE_C_FLAGS "${C_FLAGS}") - - set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DDEBUG") - set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") - - # Declare deplibs, so we can use list in linker later. There's probably # a more elegant way of doing this; with SCons, when you check for the # lib, it is automatically passed to the linker. @@ -146,40 +138,35 @@ ELSE () endif () list(APPEND deplibs z) + option(CODE_COVERAGE "Enable coverage reporting" OFF) + if (CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + # Add required flags (GCC & LLVM/Clang) + # Code Coverage Configuration + add_library(coverage_config INTERFACE) + target_compile_options(coverage_config INTERFACE + -O0 # no optimization + -g # generate debug info + --coverage # sets all required flags + ) + if (NOT (CMAKE_VERSION VERSION_LESS "3.13")) + target_link_options(coverage_config INTERFACE --coverage) + else () + target_link_libraries(coverage_config INTERFACE --coverage) + endif () + list(APPEND deplibs coverage_config) + endif (CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + # add include dir for bsd (posix uses /usr/include/) set(CMAKE_INCLUDE_PATH "${CMAKE_INCLUDE_PATH}:/usr/local/include") -ENDIF () - -# For config.h, set some static values; it may be a good idea to make -# these values dynamic for non-standard UNIX compilers. -set(ACCEPT_TYPE_ARG3 socklen_t) -set(HAVE_CXX_BOOL 1) -set(HAVE_CXX_CASTS 1) -set(HAVE_CXX_EXCEPTIONS 1) -set(HAVE_CXX_MUTABLE 1) -set(HAVE_CXX_STDLIB 1) -set(HAVE_PTHREAD_SIGNAL 1) -set(SELECT_TYPE_ARG1 int) -set(SELECT_TYPE_ARG234 "(fd_set *)") -set(SELECT_TYPE_ARG5 "(struct timeval *)") -set(STDC_HEADERS 1) -set(TIME_WITH_SYS_TIME 1) -set(HAVE_SOCKLEN_T 1) - -# For config.h, save the results based on a template (config.h.in). -# configure_file(res/config.h.in ${root_dir}/config.h) - -# add_definitions(-DSYSAPI_UNIX=1 -DHAVE_CONFIG_H) +endif () add_subdirectory(libs) add_subdirectory(project) add_subdirectory(example) - option(RUN_UNIT_TEST "RUN_UNIT_TEST" OFF) - if (RUN_UNIT_TEST) message(STATUS "** RUN_UNIT_TEST: Do execution testing") + enable_testing() add_subdirectory(test) endif () - diff --git a/build.sh b/build.sh index 6b0407efe..ee1cbfa33 100755 --- a/build.sh +++ b/build.sh @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +set -e + basepath=$( cd $(dirname $0) pwd @@ -23,24 +25,24 @@ down_dir="${basepath}/tmp_down_dir" build_dir="${basepath}/tmp_build_dir" packet_dir="${basepath}/tmp_packet_dir" install_lib_dir="${basepath}/bin" +fname_spdlog="spdlog*.zip" fname_libevent="libevent*.zip" fname_jsoncpp="jsoncpp*.zip" -fname_boost="boost*.tar.gz" +fname_spdlog_down="v1.5.0.zip" fname_libevent_down="release-2.1.11-stable.zip" fname_jsoncpp_down="0.10.6.zip" -fname_boost_down="1.58.0/boost_1_58_0.tar.gz" PrintParams() { echo "=========================================one key build help============================================" - echo "sh build.sh [no build libevent:noEvent] [no build json:noJson] [no build boost:noBoost] [ execution test:test]" - echo "usage: sh build.sh noJson noEvent noBoost test" + echo "sh build.sh [no build spdlog:noLog] [no build libevent:noEvent] [no build json:noJson] [ execution test:test]" + echo "usage: sh build.sh noLog noJson noEvent test" echo "=========================================one key build help============================================" echo "" } +need_build_spdlog=1 need_build_jsoncpp=1 need_build_libevent=1 -need_build_boost=1 test=0 verbose=1 codecov=0 @@ -49,15 +51,15 @@ cpu_num=4 pasres_arguments() { for var in "$@"; do case "$var" in + noLog) + need_build_spdlog=0 + ;; noJson) need_build_jsoncpp=0 ;; noEvent) need_build_libevent=0 ;; - noBoost) - need_build_boost=0 - ;; noVerbose) verbose=0 ;; @@ -75,6 +77,13 @@ pasres_arguments $@ PrintParams() { echo "###########################################################################" + + if [ $need_build_spdlog -eq 0 ]; then + echo "no need build spdlog lib" + else + echo "need build spdlog lib" + fi + if [ $need_build_libevent -eq 0 ]; then echo "no need build libevent lib" else @@ -87,19 +96,16 @@ PrintParams() { echo "need build jsoncpp lib" fi - if [ $need_build_boost -eq 0 ]; then - echo "no need build boost lib" - else - echo "need build boost lib" - fi if [ $test -eq 1 ]; then echo "build unit tests" else echo "without build unit tests" fi + if [ $codecov -eq 1 ]; then echo "run unit tests with code coverage" fi + if [ $verbose -eq 0 ]; then echo "no need print detail logs" else @@ -113,13 +119,16 @@ PrintParams() { Prepare() { if [ -e ${down_dir} ]; then echo "${down_dir} is exist" - #cd ${down_dir} - #ls |grep -v ${fname_libevent} |grep -v ${fname_jsoncpp} | grep -v ${fname_boost} |xargs rm -rf else mkdir -p ${down_dir} fi cd ${basepath} + + if [ -e ${fname_spdlog} ]; then + mv -f ${basepath}/${fname_spdlog} ${down_dir} + fi + if [ -e ${fname_libevent} ]; then mv -f ${basepath}/${fname_libevent} ${down_dir} fi @@ -128,20 +137,14 @@ Prepare() { mv -f ${basepath}/${fname_jsoncpp} ${down_dir} fi - if [ -e ${fname_boost} ]; then - mv -f ${basepath}/${fname_boost} ${down_dir} - fi - if [ -e ${build_dir} ]; then echo "${build_dir} is exist" - #rm -rf ${build_dir}/* else mkdir -p ${build_dir} fi if [ -e ${packet_dir} ]; then echo "${packet_dir} is exist" - #rm -rf ${packet_dir}/* else mkdir -p ${packet_dir} fi @@ -153,6 +156,30 @@ Prepare() { fi } +BuildSpdlog() { + if [ $need_build_spdlog -eq 0 ]; then + echo "no need build spdlog lib" + return 0 + fi + + cd ${down_dir} + if [ -e ${fname_spdlog} ]; then + echo "${fname_spdlog} is exist" + else + wget https://github.com/gabime/spdlog/archive/${fname_spdlog_down} -O spdlog-${fname_spdlog_down} + fi + unzip -o ${fname_spdlog} >unzipspdlog.txt 2>&1 + if [ $? -ne 0 ]; then + exit 1 + fi + + spdlog_dir=$(ls | grep spdlog | grep .*[^zip]$) + cd ${spdlog_dir} + cp -r include ${install_lib_dir} + + echo "build spdlog success." +} + BuildLibevent() { if [ $need_build_libevent -eq 0 ]; then echo "no need build libevent lib" @@ -198,7 +225,7 @@ BuildLibevent() { exit 1 fi make install - echo "build linevent success." + echo "build libevent success." } BuildJsonCPP() { @@ -251,51 +278,16 @@ BuildJsonCPP() { fi } -BuildBoost() { - if [ $need_build_boost -eq 0 ]; then - echo "no need build boost lib" - return 0 - fi - - cd ${down_dir} - if [ -e ${fname_boost} ]; then - echo "${fname_boost} is exist" - else - wget http://sourceforge.net/projects/boost/files/boost/${fname_boost_down} - fi - tar -zxvf ${fname_boost} >unzipboost.txt 2>&1 - boost_dir=$(ls | grep boost | grep .*[^gz]$) - cd ${boost_dir} - if [ $? -ne 0 ]; then - exit 1 - fi - ./bootstrap.sh - if [ $? -ne 0 ]; then - exit 1 - fi - echo "build boost static #####################" - pwd - if [ $verbose -eq 0 ]; then - echo "build boost without detail log." - ./b2 -j$cpu_num cflags=-fPIC cxxflags=-fPIC --with-atomic --with-thread --with-system --with-chrono --with-date_time --with-log --with-regex --with-serialization --with-filesystem --with-locale --with-iostreams threading=multi link=static release install --prefix=${install_lib_dir} >boostbuild.txt 2>&1 - else - ./b2 -j$cpu_num cflags=-fPIC cxxflags=-fPIC --with-atomic --with-thread --with-system --with-chrono --with-date_time --with-log --with-regex --with-serialization --with-filesystem --with-locale --with-iostreams threading=multi link=static release install --prefix=${install_lib_dir} - fi - if [ $? -ne 0 ]; then - exit 1 - fi -} - BuildRocketMQClient() { cd ${build_dir} echo "============start to build rocketmq client cpp.=========" if [ $test -eq 0 ]; then - cmake .. + cmake -DLibevent_USE_STATIC_LIBS=ON -DJSONCPP_USE_STATIC_LIBS=ON -DBUILD_ROCKETMQ_STATIC=ON -DBUILD_ROCKETMQ_SHARED=OFF .. else if [ $codecov -eq 1 ]; then - cmake .. -DRUN_UNIT_TEST=ON -DCODE_COVERAGE=ON + cmake .. -DLibevent_USE_STATIC_LIBS=ON -DJSONCPP_USE_STATIC_LIBS=ON -DBUILD_ROCKETMQ_STATIC=ON -DBUILD_ROCKETMQ_SHARED=OFF -DRUN_UNIT_TEST=ON -DCODE_COVERAGE=ON else - cmake .. -DRUN_UNIT_TEST=ON + cmake .. -DLibevent_USE_STATIC_LIBS=ON -DJSONCPP_USE_STATIC_LIBS=ON -DBUILD_ROCKETMQ_STATIC=ON -DBUILD_ROCKETMQ_SHARED=OFF -DRUN_UNIT_TEST=ON fi fi if [ $verbose -eq 0 ]; then @@ -309,7 +301,6 @@ BuildRocketMQClient() { exit 1 fi #sudo make install - PackageRocketMQStatic } BuildGoogleTest() { @@ -319,20 +310,20 @@ BuildGoogleTest() { fi if [ -f ./bin/lib/libgtest.a ]; then - echo "libgteest already exist no need build test" + echo "libgtest already exist no need build test" return 0 fi cd ${down_dir} - if [ -e release-1.8.1.tar.gz ]; then + if [ -e release-1.10.0.tar.gz ]; then echo "${fname_boost} is exist" else - wget https://github.com/abseil/googletest/archive/release-1.8.1.tar.gz + wget https://github.com/abseil/googletest/archive/release-1.10.0.tar.gz fi - if [ ! -d "googletest-release-1.8.1" ]; then - tar -zxvf release-1.8.1.tar.gz >googletest.txt 2>&1 + if [ ! -d "googletest-release-1.10.0" ]; then + tar -zxvf release-1.10.0.tar.gz >googletest.txt 2>&1 fi - cd googletest-release-1.8.1 + cd googletest-release-1.10.0 mkdir build cd build echo "build googletest static #####################" @@ -380,21 +371,11 @@ ExecutionTesting() { echo "############# unit test finish ###########" } -PackageRocketMQStatic() { - if test "$(uname)" = "Linux"; then - echo "package static library." - #packet libevent,jsoncpp,boost,rocketmq,Signature to one librocketmq.a - cp -f ${basepath}/libs/signature/lib/libSignature.a ${install_lib_dir}/lib - ar -M <${basepath}/package_rocketmq.mri - cp -f librocketmq.a ${install_lib_dir} - fi -} - PrintParams Prepare +BuildSpdlog BuildLibevent BuildJsonCPP -BuildBoost BuildGoogleTest BuildRocketMQClient ExecutionTesting diff --git a/cmake/BundleStaticLibrary.cmake b/cmake/BundleStaticLibrary.cmake index 4ab9a24b1..782eec4b1 100644 --- a/cmake/BundleStaticLibrary.cmake +++ b/cmake/BundleStaticLibrary.cmake @@ -16,7 +16,7 @@ # ref: https://cristianadam.eu/20190501/bundling-together-static-libraries-with-cmake/ set(STATIC_LIBRARY_REGEX "${CMAKE_STATIC_LIBRARY_SUFFIX}") -string(REPLACE ".", "\\.", STATIC_LIBRARY_REGEX ${STATIC_LIBRARY_REGEX}) +string(REPLACE "." "\\." STATIC_LIBRARY_REGEX "${STATIC_LIBRARY_REGEX}") set(STATIC_LIBRARY_REGEX "^.+${STATIC_LIBRARY_REGEX}$") function(bundle_static_library tgt_name bundled_tgt_name) diff --git a/cmake/FindJsoncpp.cmake b/cmake/FindJsoncpp.cmake index cdef2b1ca..4625ccfa1 100755 --- a/cmake/FindJsoncpp.cmake +++ b/cmake/FindJsoncpp.cmake @@ -17,17 +17,17 @@ # # Find the jsoncpp includes and library # -# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# if you nee to add a custom library search path, do it via CMAKE_PREFIX_PATH # # -*- cmake -*- # - Find JSONCpp # Find the JSONCpp includes and library -# This module defines +# +# This module define the following variables: +# +# JSONCPP_FOUND, If false, do not try to use jsoncpp. # JSONCPP_INCLUDE_DIRS, where to find json.h, etc. # JSONCPP_LIBRARIES, the libraries needed to use jsoncpp. -# JSONCPP_FOUND, If false, do not try to use jsoncpp. -# also defined, but not for general use are -# JSONCPP_LIBRARIES, where to find the jsoncpp library. # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES if (JSONCPP_USE_STATIC_LIBS) @@ -48,13 +48,11 @@ else () endif () endif () -set(JSONCPP_INCLUDE_SEARCH_PATH ${CMAKE_SOURCE_DIR}/bin/include /usr/local/include C:/jsoncpp/include - ${CMAKE_SOURCE_DIR}/win32-deps/include C:/jsoncpp-0.10.6/include) -set(JSONCPP_LIBRARIE_SEARCH_PATH ${CMAKE_SOURCE_DIR}/bin/lib /usr/local/lib C:/jsoncpp/lib - ${CMAKE_SOURCE_DIR}/win32-deps/lib C:/jsoncpp-0.10.6/) +set(JSONCPP_INCLUDE_SEARCH_PATH /usr/local/include /usr/include) +set(JSONCPP_LIBRARIES_SEARCH_PATH /usr/local/lib /usr/lib) if (JSONCPP_ROOT) list(INSERT JSONCPP_INCLUDE_SEARCH_PATH 0 ${JSONCPP_ROOT}/include) - list(INSERT JSONCPP_LIBRARIE_SEARCH_PATH 0 ${JSONCPP_ROOT}/lib) + list(INSERT JSONCPP_LIBRARIES_SEARCH_PATH 0 ${JSONCPP_ROOT}/lib) endif () find_path(JSONCPP_INCLUDE_DIRS @@ -64,34 +62,25 @@ find_path(JSONCPP_INCLUDE_DIRS find_library(JSONCPP_LIBRARIES NAMES jsoncpp - PATHS ${JSONCPP_LIBRARIE_SEARCH_PATH}) - -IF (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS) - SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARIES}) - SET(JSONCPP_FOUND "YES") -ELSE (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS) - SET(JSONCPP_FOUND "NO") -ENDIF (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS) - + PATHS ${JSONCPP_LIBRARIES_SEARCH_PATH}) -IF (JSONCPP_FOUND) - IF (NOT JSONCPP_FIND_QUIETLY) - MESSAGE(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}") - ENDIF (NOT JSONCPP_FIND_QUIETLY) -ELSE (JSONCPP_FOUND) - IF (JSONCPP_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find JSONCPP library include: ${JSONCPP_INCLUDE_DIRS}, lib: ${JSONCPP_LIBRARIES}") - ENDIF (JSONCPP_FIND_REQUIRED) -ENDIF (JSONCPP_FOUND) +if (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS) + set(JSONCPP_FOUND "YES") +else (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS) + set(JSONCPP_FOUND "NO") +endif (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS) -# Deprecated declarations. -SET(NATIVE_JSONCPP_INCLUDE_PATH ${JSONCPP_INCLUDE_DIRS}) -GET_FILENAME_COMPONENT(NATIVE_JSONCPP_LIB_PATH ${JSONCPP_LIBRARIES} PATH) +if (JSONCPP_FOUND) + if (NOT JSONCPP_FIND_QUIETLY) + message(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}") + endif (NOT JSONCPP_FIND_QUIETLY) +else (JSONCPP_FOUND) + if (JSONCPP_FIND_REQUIRED) + message(FATAL_ERROR "Could not find JSONCPP library, include: ${JSONCPP_INCLUDE_DIRS}, lib: ${JSONCPP_LIBRARIES}") + endif (JSONCPP_FIND_REQUIRED) +endif (JSONCPP_FOUND) -MARK_AS_ADVANCED( - JSONCPP_LIBRARIES - JSONCPP_INCLUDE_DIRS -) +mark_as_advanced(JSONCPP_LIBRARIES JSONCPP_INCLUDE_DIRS) # Restore the original find library ordering if (JSONCPP_USE_STATIC_LIBS) diff --git a/cmake/FindLibevent.cmake b/cmake/FindLibevent.cmake index 0165e7027..1b4ab6528 100755 --- a/cmake/FindLibevent.cmake +++ b/cmake/FindLibevent.cmake @@ -29,7 +29,7 @@ # Note that 'libevent' contains both core and extra. You must specify one of # them for the other components. # -# This module will define the following variables:: +# This module will define the following variables: # # LIBEVENT_FOUND - True if headers and requested libraries were found # LIBEVENT_INCLUDE_DIRS - Libevent include directories @@ -59,18 +59,16 @@ else () endif () endif () -set(LIBEVENT_INCLUDE_SEARCH_PATH ${CMAKE_SOURCE_DIR}/bin/include /usr/local/include C:/libevent/include - ${CMAKE_SOURCE_DIR}/win32-deps/include) -set(LIBEVENT_LIBRARIE_SEARCH_PATH ${CMAKE_SOURCE_DIR}/bin/lib /usr/local/lib C:/libevent-2.0.22-stable - C:/libevent-2.0.22-stable/lib C:/libevent/lib ${CMAKE_SOURCE_DIR}/win32-deps/lib) +set(LIBEVENT_INCLUDE_SEARCH_PATH /usr/local/include /usr/include) +set(LIBEVENT_LIBRARIES_SEARCH_PATH /usr/local/lib /usr/lib) if (LIBEVENT_ROOT) - list(INSERT LIBEVENT_INCLUDE_SEARCH_PATH 0 ${JSONCPP_ROOT}/include) - list(INSERT LIBEVENT_LIBRARIE_SEARCH_PATH 0 ${JSONCPP_ROOT}/lib) + list(INSERT LIBEVENT_INCLUDE_SEARCH_PATH 0 ${LIBEVENT_ROOT}/include) + list(INSERT LIBEVENT_LIBRARIES_SEARCH_PATH 0 ${LIBEVENT_ROOT}/lib) endif () # Look for the Libevent 2.0 or 1.4 headers find_path(LIBEVENT_INCLUDE_DIR - NAMES WIN32-Code/event2/event-config.h event2/event-config.h event-config.h + NAMES event2/event-config.h event-config.h PATHS ${LIBEVENT_INCLUDE_SEARCH_PATH} HINTS ${PC_LIBEVENT_INCLUDE_DIRS}) @@ -81,7 +79,6 @@ set(Libevent_LIB_PREFIX "") set(LIBEVENT_EVENT_CONFIG_DIR ${LIBEVENT_INCLUDE_DIR}) if (WIN32) set(Libevent_LIB_PREFIX "lib") - set(LIBEVENT_EVENT_CONFIG_DIR "${LIBEVENT_INCLUDE_DIR}/../WIN32-Code/") endif () if (LIBEVENT_INCLUDE_DIR) @@ -110,7 +107,7 @@ endif () set(_LIBEVENT_REQUIRED_VARS) if (WIN32) - set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extras) + set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extra) else () set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extra pthreads) endif () @@ -124,10 +121,10 @@ foreach (COMPONENT ${Libevent_FIND_COMPONENTS}) set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event_${COMPONENT}") endif () string(TOUPPER "${COMPONENT}" COMPONENT_UPPER) - message(STATUS "** ${_LIBEVENT_LIBNAME}") + message(STATUS "** fine ${_LIBEVENT_LIBNAME} in ${LIBEVENT_LIBRARIES_SEARCH_PATH}") find_library(LIBEVENT_${COMPONENT_UPPER}_LIBRARY NAMES ${_LIBEVENT_LIBNAME} - PATHS ${LIBEVENT_LIBRARIE_SEARCH_PATH} + PATHS ${LIBEVENT_LIBRARIES_SEARCH_PATH} HINTS ${PC_LIBEVENT_LIBRARY_DIRS} ) if (LIBEVENT_${COMPONENT_UPPER}_LIBRARY) @@ -140,9 +137,8 @@ unset(_LIBEVENT_LIBNAME) include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set LIBEVENT_FOUND to TRUE # if all listed variables are TRUE and the requested version matches. -find_package_handle_standard_args(Libevent REQUIRED_VARS - ${_LIBEVENT_REQUIRED_VARS} - LIBEVENT_INCLUDE_DIR +find_package_handle_standard_args(Libevent + REQUIRED_VARS ${_LIBEVENT_REQUIRED_VARS} LIBEVENT_INCLUDE_DIR VERSION_VAR LIBEVENT_VERSION HANDLE_COMPONENTS) diff --git a/example/AsyncProducer.cpp b/example/AsyncProducer.cpp index a8acd5d74..8f6c05f3e 100644 --- a/example/AsyncProducer.cpp +++ b/example/AsyncProducer.cpp @@ -90,7 +90,7 @@ int main(int argc, char* argv[]) { int threadCount = info.thread_count; for (int j = 0; j < threadCount; j++) { - std::shared_ptr th = std::make_shared(AsyncProducerWorker, &info, producer); + auto th = std::make_shared(AsyncProducerWorker, &info, producer); work_pool.push_back(th); } diff --git a/example/BatchProducer.cpp b/example/BatchProducer.cpp index 12e95f7e5..4055d8a88 100644 --- a/example/BatchProducer.cpp +++ b/example/BatchProducer.cpp @@ -80,7 +80,7 @@ int main(int argc, char* argv[]) { int threadCount = info.thread_count; for (int j = 0; j < threadCount; j++) { - std::shared_ptr th = std::make_shared(SyncProducerWorker, &info, producer); + auto th = std::make_shared(SyncProducerWorker, &info, producer); work_pool.push_back(th); } diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 6ef72a805..8e445b17a 100755 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -17,37 +17,23 @@ project(example) set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin) -include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories(${CMAKE_SOURCE_DIR}/src) - -link_directories(${LIBEVENT_LIBRARY}) -link_directories(${JSONCPP_LIBRARY}) - file(GLOB files RELATIVE "${PROJECT_SOURCE_DIR}" "*.c*") list(REMOVE_ITEM files "ArgHelper.cpp") foreach(file ${files}) get_filename_component(basename ${file} NAME_WE) add_executable(${basename} ${file}) + if(MSVC) if(CMAKE_CONFIGURATION_TYPES STREQUAL "Release") - set_target_properties( ${basename} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT" ) + set_target_properties(${basename} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT") else() - set_target_properties( ${basename} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMTD" ) + set_target_properties(${basename} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMTD") endif() endif() - if (MSVC) - if (BUILD_ROCKETMQ_SHARED) - target_link_libraries (${basename} rocketmq_shared ${deplibs} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES}) - else() - target_link_libraries (${basename} rocketmq_static ${deplibs} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES}) - endif() + if (BUILD_ROCKETMQ_SHARED) + target_link_libraries (${basename} rocketmq_shared) else() - if (BUILD_ROCKETMQ_SHARED) - target_link_libraries (${basename} rocketmq_shared) - else() - target_link_libraries (${basename} rocketmq_static) - endif() + target_link_libraries (${basename} rocketmq_static) endif() - endforeach() diff --git a/example/OrderlyProducer.cpp b/example/OrderlyProducer.cpp index 237532b9d..d50542e22 100644 --- a/example/OrderlyProducer.cpp +++ b/example/OrderlyProducer.cpp @@ -81,7 +81,7 @@ int main(int argc, char* argv[]) { int threadCount = info.thread_count; for (int j = 0; j < threadCount; j++) { - std::shared_ptr th = std::make_shared(ProducerWorker, &info, producer); + auto th = std::make_shared(ProducerWorker, &info, producer); work_pool.push_back(th); } diff --git a/example/PullConsumer.cpp b/example/PullConsumer.cpp index 6046d6c60..7bd7ffd49 100644 --- a/example/PullConsumer.cpp +++ b/example/PullConsumer.cpp @@ -34,7 +34,7 @@ void putMessageQueueOffset(MQMessageQueue mq, uint64_t offset) { } uint64_t getMessageQueueOffset(MQMessageQueue mq) { - auto it = g_offseTable.find(mq); + const auto& it = g_offseTable.find(mq); if (it != g_offseTable.end()) { return it->second; } diff --git a/example/PushConsumer.cpp b/example/PushConsumer.cpp index 9aba07c5b..9f1797921 100644 --- a/example/PushConsumer.cpp +++ b/example/PushConsumer.cpp @@ -61,7 +61,7 @@ int main(int argc, char* argv[]) { consumer->setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET); if (info.broadcasting) { - consumer->setMessageModel(rocketmq::BROADCASTING); + consumer->setMessageModel(BROADCASTING); } consumer->subscribe(info.topic, "*"); diff --git a/example/RequestReply.cpp b/example/RequestReply.cpp new file mode 100644 index 000000000..1ba3af811 --- /dev/null +++ b/example/RequestReply.cpp @@ -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 + +#include "../src/common/UtilAll.h" +#include "../src/log/Logging.h" +#include "MessageUtil.h" +#include "common.h" + +using namespace rocketmq; + +class MyResponseMessageListener : public MessageListenerConcurrently { + public: + MyResponseMessageListener(DefaultMQProducer* replyProducer) : m_replyProducer(replyProducer) {} + virtual ~MyResponseMessageListener() = default; + + ConsumeStatus consumeMessage(const std::vector& msgs) override { + for (const auto& msg : msgs) { + try { + std::cout << "handle message: " << msg->toString() << std::endl; + const auto& replyTo = MessageUtil::getReplyToClient(msg); + + // create reply message with given util, do not create reply message by yourself + std::unique_ptr replyMessage(MessageUtil::createReplyMessage(msg, "reply message contents.")); + + // send reply message with producer + SendResult replyResult = m_replyProducer->send(replyMessage.get(), 10000); + std::cout << "reply to " << replyTo << ", " << replyResult.toString() << std::endl; + } catch (const std::exception& e) { + std::cout << e.what() << std::endl; + } + } + return CONSUME_SUCCESS; + } + + private: + DefaultMQProducer* m_replyProducer; +}; + +int main(int argc, char* argv[]) { + RocketmqSendAndConsumerArgs info; + if (!ParseArgs(argc, argv, &info)) { + exit(-1); + } + PrintRocketmqSendAndConsumerArgs(info); + + DefaultMQProducer producer(""); + producer.setNamesrvAddr(info.namesrv); + producer.setSendMsgTimeout(3000); + producer.setRetryTimes(info.retrytimes); + producer.setRetryTimes4Async(info.retrytimes); + producer.setSendLatencyFaultEnable(!info.selectUnactiveBroker); + producer.setTcpTransportTryLockTimeout(1000); + producer.setTcpTransportConnectTimeout(400); + producer.start(); + + DefaultMQPushConsumer consumer(info.groupname); + consumer.setNamesrvAddr(info.namesrv); + consumer.setTcpTransportTryLockTimeout(1000); + consumer.setTcpTransportConnectTimeout(400); + consumer.setConsumeThreadNum(info.thread_count); + consumer.setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET); + + // recommend client configs + consumer.setPullTimeDelayMillsWhenException(0L); + + consumer.subscribe(info.topic, "*"); + + MyResponseMessageListener msglistener(&producer); + consumer.registerMessageListener(&msglistener); + + try { + consumer.start(); + } catch (MQClientException& e) { + std::cout << e << std::endl; + return -1; + } + + // std::this_thread::sleep_for(std::chrono::seconds(10)); + + int msg_count = g_msgCount.load(); + for (int count = 0; count < msg_count; count++) { + try { + MQMessage msg(info.topic, "Hello world"); + + auto begin = UtilAll::currentTimeMillis(); + std::unique_ptr retMsg(producer.request(&msg, 10000)); + auto cost = UtilAll::currentTimeMillis() - begin; + std::cout << count << " >>> request to <" << info.topic << "> cost: " << cost + << " replyMessage: " << retMsg->toString() << std::endl; + } catch (const std::exception& e) { + std::cout << count << " >>> " << e.what() << std::endl; + } + } + + consumer.shutdown(); + producer.shutdown(); + + return 0; +} diff --git a/example/SyncProducer.cpp b/example/SyncProducer.cpp index d840fdd3d..994a519d7 100644 --- a/example/SyncProducer.cpp +++ b/example/SyncProducer.cpp @@ -69,7 +69,7 @@ int main(int argc, char* argv[]) { int threadCount = info.thread_count; for (int j = 0; j < threadCount; j++) { - std::shared_ptr th = std::make_shared(SyncProducerWorker, &info, producer); + auto th = std::make_shared(SyncProducerWorker, &info, producer); work_pool.push_back(th); } diff --git a/example/TransactionProducer.cpp b/example/TransactionProducer.cpp index f6985f980..547a279c5 100644 --- a/example/TransactionProducer.cpp +++ b/example/TransactionProducer.cpp @@ -90,7 +90,7 @@ int main(int argc, char* argv[]) { int threadCount = info.thread_count; for (int j = 0; j < threadCount; j++) { - std::shared_ptr th = std::make_shared(SyncProducerWorker, &info, producer); + auto th = std::make_shared(SyncProducerWorker, &info, producer); work_pool.push_back(th); } diff --git a/example/common.h b/example/common.h index db242f785..84683bc39 100644 --- a/example/common.h +++ b/example/common.h @@ -31,9 +31,9 @@ #endif #include "DefaultMQProducer.h" -#include "TransactionMQProducer.h" #include "DefaultMQPullConsumer.h" #include "DefaultMQPushConsumer.h" +#include "TransactionMQProducer.h" std::atomic g_msgCount(1); diff --git a/format.sh b/format.sh index f46c5f296..9fcf5af34 100755 --- a/format.sh +++ b/format.sh @@ -15,58 +15,53 @@ # See the License for the specific language governing permissions and # limitations under the License. +set -e TMPFILE=".clang_format_file.tmp" FORMAT="{BasedOnStyle: Chromium, ColumnLimit: 120, TabWidth: 2}" -function Usage -{ +function Usage() { echo "Usage: $0 want-format-file|want-format-dir ..." #echo "Currently only format a file or dir at a time" } -#Setp1 check clang-format support +# Setp 1: check clang-format support if ! which clang-format &>/dev/null; then echo -e "\033[32m !!!!!!please install clang-format \033[0m" exit 1 fi - -#Setp2 check weather incoming format file -if [ ! $# -ge 1 ];then +# Setp 2: check weather incoming format file +if [ ! $# -ge 1 ]; then Usage exit 1 fi -for dest in "$@" -do - if [ ! -e $dest ]; then - echo -e "\033[32m $dest not exists,please check this file weather exists \033[0m" - fi +for dest in "$@"; do + if [ ! -e $dest ]; then + echo -e "\033[32m $dest not exists,please check this file weather exists \033[0m" + fi done - -#Setp3 get filelist -for dest in $* -do - if [ -f $dest ];then - files="$files $dest" - elif [ -d $dest ];then - files="$files `ls $dest/*.cpp $dest/*.h $dest/*.cc 2>/dev/null`" - else - echo -e "\033[32m $dest sorry current $0 only support regular file or dir \033[0m" - fi +# Setp 3: get filelist +for dest in $*; do + if [ -f $dest ]; then + files="$files $dest" + elif [ -d $dest ]; then + files="$files $(ls $dest/*.cpp $dest/*.h $dest/*.cc 2>/dev/null)" + else + echo -e "\033[32m $dest sorry current $0 only support regular file or dir \033[0m" + fi done -#Setp4 use clang-format format dest file -for file in $files -do +# Setp 4: use clang-format format dest file +for file in $files; do echo $file - clang-format $file > $TMPFILE + clang-format -style=file $file >$TMPFILE - if [ -e $TMPFILE ];then - filesize=`wc -c $TMPFILE |cut -d " " -f1` - if [ $filesize -eq 0 ];then + if [ -e $TMPFILE ]; then + filesize=$(wc -c $TMPFILE | awk -F' ' '{ print $1; }') + if [ $filesize -eq 0 ]; then echo -e "\033[32m formt file error,May be because of the size of the source file is 0, or format program error \033[0m" exit 1 fi diff --git a/src/common/DataBlock.h b/include/DataBlock.h similarity index 94% rename from src/common/DataBlock.h rename to include/DataBlock.h index 08a64046c..7976cd005 100644 --- a/src/common/DataBlock.h +++ b/include/DataBlock.h @@ -18,20 +18,20 @@ #define __DATA_BLOCK_H__ #include +#include #include "RocketMQClient.h" namespace rocketmq { class MemoryBlock; -typedef MemoryBlock* MemoryBlockPtr; +typedef std::unique_ptr MemoryBlockPtr; typedef std::shared_ptr MemoryBlockPtr2; -typedef std::unique_ptr MemoryBlockPtr3; class ROCKETMQCLIENT_API MemoryBlock { public: MemoryBlock() : MemoryBlock(nullptr, 0) {} - MemoryBlock(char* data, size_t size) : data_(data), size_(size) {} + explicit MemoryBlock(char* data, size_t size) : data_(data), size_(size) {} virtual ~MemoryBlock() = default; /** Returns a void pointer to the data. @@ -58,6 +58,14 @@ class ROCKETMQCLIENT_API MemoryBlock { return data_[offset]; } + operator std::string() { + if (size_ > 0) { + return std::string(data_, size_); + } else { + return ""; + } + } + /** Frees all the blocks data, setting its size to 0. */ virtual void reset() { reset(nullptr, 0); } @@ -90,14 +98,14 @@ class ROCKETMQCLIENT_API MemoryPool : public MemoryBlock { * @param initialSize the size of block to create * @param initialiseToZero whether to clear the memory or just leave it uninitialised */ - MemoryPool(size_t initialSize, bool initialiseToZero = false); + explicit MemoryPool(size_t 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 */ - MemoryPool(const void* dataToInitialiseFrom, size_t sizeInBytes); + explicit MemoryPool(const void* dataToInitialiseFrom, size_t sizeInBytes); /** Creates a copy of another memory block. */ MemoryPool(const MemoryPool&); diff --git a/include/DefaultMQProducer.h b/include/DefaultMQProducer.h index 71a1da95d..91e0e2b4d 100644 --- a/include/DefaultMQProducer.h +++ b/include/DefaultMQProducer.h @@ -17,72 +17,22 @@ #ifndef __DEFAULT_MQ_PRODUCER_H__ #define __DEFAULT_MQ_PRODUCER_H__ -#include "MQClientConfig.h" +#include "DefaultMQProducerConfigProxy.h" #include "MQProducer.h" #include "RPCHook.h" namespace rocketmq { -class ROCKETMQCLIENT_API DefaultMQProducerConfig : public MQClientConfig { - public: - DefaultMQProducerConfig(); - virtual ~DefaultMQProducerConfig() = default; - - // if msgbody size larger than maxMsgBodySize, exception will be throwed - int getMaxMessageSize() const { return m_maxMessageSize; } - void setMaxMessageSize(int maxMessageSize) { m_maxMessageSize = maxMessageSize; } - - /* - * if msgBody size is large than m_compressMsgBodyOverHowmuch - * rocketmq cpp will compress msgBody according to compressLevel - */ - int getCompressMsgBodyOverHowmuch() const { return m_compressMsgBodyOverHowmuch; } - void setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch) { - m_compressMsgBodyOverHowmuch = compressMsgBodyOverHowmuch; - } - - int getCompressLevel() const { return m_compressLevel; } - void setCompressLevel(int compressLevel) { - if ((compressLevel >= 0 && compressLevel <= 9) || compressLevel == -1) { - m_compressLevel = compressLevel; - } - } - - // set and get timeout of per msg - int getSendMsgTimeout() const { return m_sendMsgTimeout; } - void setSendMsgTimeout(int sendMsgTimeout) { m_sendMsgTimeout = sendMsgTimeout; } - - // set msg max retry times, default retry times is 5 - int getRetryTimes() const { return m_retryTimes; } - void setRetryTimes(int times) { m_retryTimes = std::min(std::max(0, times), 15); } - - int getRetryTimes4Async() const { return m_retryTimes4Async; } - void setRetryTimes4Async(int times) { m_retryTimes4Async = std::min(std::max(0, times), 15); } - - bool isRetryAnotherBrokerWhenNotStoreOK() const { return m_retryAnotherBrokerWhenNotStoreOK; } - void setRetryAnotherBrokerWhenNotStoreOK(bool retryAnotherBrokerWhenNotStoreOK) { - m_retryAnotherBrokerWhenNotStoreOK = retryAnotherBrokerWhenNotStoreOK; - } - - virtual bool isSendLatencyFaultEnable() const = 0; - virtual void setSendLatencyFaultEnable(bool sendLatencyFaultEnable) = 0; - - protected: - int m_maxMessageSize; // default: 4 MB - int m_compressMsgBodyOverHowmuch; // default: 4 KB - int m_compressLevel; - int m_sendMsgTimeout; - int m_retryTimes; - int m_retryTimes4Async; - bool m_retryAnotherBrokerWhenNotStoreOK; -}; - -class ROCKETMQCLIENT_API DefaultMQProducer : public MQProducer, public DefaultMQProducerConfig { +class ROCKETMQCLIENT_API DefaultMQProducer : public MQProducer, public DefaultMQProducerConfigProxy { public: DefaultMQProducer(const std::string& groupname); DefaultMQProducer(const std::string& groupname, RPCHookPtr rpcHook); virtual ~DefaultMQProducer(); + private: + DefaultMQProducer(const std::string& groupname, RPCHookPtr rpcHook, DefaultMQProducerConfigPtr producerConfig); + friend class TransactionMQProducer; + public: // MQProducer void start() override; void shutdown() override; @@ -123,12 +73,15 @@ class ROCKETMQCLIENT_API DefaultMQProducer : public MQProducer, public DefaultMQ SendResult send(std::vector& msgs, const MQMessageQueue& mq) override; SendResult send(std::vector& msgs, const MQMessageQueue& mq, long timeout) override; + // RPC + MQMessagePtr request(MQMessagePtr msg, long timeout) override; + public: // DefaultMQProducerConfig bool isSendLatencyFaultEnable() const override; void setSendLatencyFaultEnable(bool sendLatencyFaultEnable) override; public: - void setRPCHook(std::shared_ptr rpcHook); + void setRPCHook(RPCHookPtr rpcHook); protected: std::shared_ptr m_producerDelegate; diff --git a/include/DefaultMQProducerConfig.h b/include/DefaultMQProducerConfig.h new file mode 100644 index 000000000..fe396ee80 --- /dev/null +++ b/include/DefaultMQProducerConfig.h @@ -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. + */ +#ifndef __DEFAULT_MQ_PRODUCER_CONFIG_H__ +#define __DEFAULT_MQ_PRODUCER_CONFIG_H__ + +#include "MQClientConfig.h" + +namespace rocketmq { + +class DefaultMQProducerConfig; +typedef std::shared_ptr DefaultMQProducerConfigPtr; + +class ROCKETMQCLIENT_API DefaultMQProducerConfig : virtual public MQClientConfig { + public: + virtual ~DefaultMQProducerConfig() = default; + + // if msgbody size larger than maxMsgBodySize, exception will be throwed + virtual int getMaxMessageSize() const = 0; + virtual void setMaxMessageSize(int maxMessageSize) = 0; + + /* + * if msgBody size is large than m_compressMsgBodyOverHowmuch + * rocketmq cpp will compress msgBody according to compressLevel + */ + virtual int getCompressMsgBodyOverHowmuch() const = 0; + virtual void setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch) = 0; + + virtual int getCompressLevel() const = 0; + virtual void setCompressLevel(int compressLevel) = 0; + + // set and get timeout of per msg + virtual int getSendMsgTimeout() const = 0; + virtual void setSendMsgTimeout(int sendMsgTimeout) = 0; + + // set msg max retry times, default retry times is 5 + virtual int getRetryTimes() const = 0; + virtual void setRetryTimes(int times) = 0; + + virtual int getRetryTimes4Async() const = 0; + virtual void setRetryTimes4Async(int times) = 0; + + virtual bool isRetryAnotherBrokerWhenNotStoreOK() const = 0; + virtual void setRetryAnotherBrokerWhenNotStoreOK(bool retryAnotherBrokerWhenNotStoreOK) = 0; + + virtual bool isSendLatencyFaultEnable() const { return false; }; + virtual void setSendLatencyFaultEnable(bool sendLatencyFaultEnable){}; +}; + +} // namespace rocketmq + +#endif // __DEFAULT_MQ_PRODUCER_CONFIG_H__ diff --git a/include/DefaultMQProducerConfigProxy.h b/include/DefaultMQProducerConfigProxy.h new file mode 100644 index 000000000..522decf15 --- /dev/null +++ b/include/DefaultMQProducerConfigProxy.h @@ -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 __DEFAULT_MQ_PRODUCER_CONFI_PROXY_H__ +#define __DEFAULT_MQ_PRODUCER_CONFI_PROXY_H__ + +#include "DefaultMQProducerConfig.h" +#include "MQClientConfigProxy.h" + +namespace rocketmq { + +class ROCKETMQCLIENT_API DefaultMQProducerConfigProxy : virtual public DefaultMQProducerConfig, + public MQClientConfigProxy { + public: + DefaultMQProducerConfigProxy(DefaultMQProducerConfigPtr producerConfig) + : MQClientConfigProxy(producerConfig), m_producerConfig(producerConfig) {} + virtual ~DefaultMQProducerConfigProxy() = default; + + DefaultMQProducerConfigPtr getRealConfig() const { return m_producerConfig; } + + int getMaxMessageSize() const override { return m_producerConfig->getMaxMessageSize(); } + + void setMaxMessageSize(int maxMessageSize) override { m_producerConfig->setMaxMessageSize(maxMessageSize); } + + int getCompressMsgBodyOverHowmuch() const override { return m_producerConfig->getCompressMsgBodyOverHowmuch(); } + + void setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch) override { + m_producerConfig->setCompressMsgBodyOverHowmuch(compressMsgBodyOverHowmuch); + } + + int getCompressLevel() const override { return m_producerConfig->getCompressLevel(); } + + void setCompressLevel(int compressLevel) override { m_producerConfig->setCompressLevel(compressLevel); } + + int getSendMsgTimeout() const override { return m_producerConfig->getSendMsgTimeout(); } + + void setSendMsgTimeout(int sendMsgTimeout) override { m_producerConfig->setSendMsgTimeout(sendMsgTimeout); } + + int getRetryTimes() const override { return m_producerConfig->getRetryTimes(); } + + void setRetryTimes(int times) override { m_producerConfig->setRetryTimes(times); } + + int getRetryTimes4Async() const override { return m_producerConfig->getRetryTimes4Async(); } + + void setRetryTimes4Async(int times) override { m_producerConfig->setRetryTimes4Async(times); } + + bool isRetryAnotherBrokerWhenNotStoreOK() const override { + return m_producerConfig->isRetryAnotherBrokerWhenNotStoreOK(); + } + + void setRetryAnotherBrokerWhenNotStoreOK(bool retryAnotherBrokerWhenNotStoreOK) override { + m_producerConfig->setRetryAnotherBrokerWhenNotStoreOK(retryAnotherBrokerWhenNotStoreOK); + } + + bool isSendLatencyFaultEnable() const override { return m_producerConfig->isSendLatencyFaultEnable(); } + + void setSendLatencyFaultEnable(bool sendLatencyFaultEnable) override { + m_producerConfig->setSendLatencyFaultEnable(sendLatencyFaultEnable); + } + + private: + DefaultMQProducerConfigPtr m_producerConfig; +}; + +} // namespace rocketmq + +#endif // __DEFAULT_MQ_PRODUCER_CONFI_PROXY_H__ diff --git a/include/DefaultMQPullConsumer.h b/include/DefaultMQPullConsumer.h index 1bd7affd4..8461969b6 100755 --- a/include/DefaultMQPullConsumer.h +++ b/include/DefaultMQPullConsumer.h @@ -21,25 +21,13 @@ #include #include "AllocateMQStrategy.h" -#include "DefaultMQConsumer.h" +#include "DefaultMQPullConsumerConfigProxy.h" #include "MQPullConsumer.h" #include "RPCHook.h" namespace rocketmq { -class ROCKETMQCLIENT_API DefaultMQPullConsumerConfig : public DefaultMQConsumerConfig { - public: - DefaultMQPullConsumerConfig(); - virtual ~DefaultMQPullConsumerConfig() = default; - - AllocateMQStrategy* getAllocateMQStrategy() { return m_allocateMQStrategy.get(); } - void setAllocateMQStrategy(AllocateMQStrategy* strategy) { m_allocateMQStrategy.reset(strategy); } - - protected: - std::unique_ptr m_allocateMQStrategy; -}; - -class ROCKETMQCLIENT_API DefaultMQPullConsumer : public MQPullConsumer, public DefaultMQPullConsumerConfig { +class ROCKETMQCLIENT_API DefaultMQPullConsumer : public MQPullConsumer, public DefaultMQPullConsumerConfigProxy { public: DefaultMQPullConsumer(const std::string& groupname); DefaultMQPullConsumer(const std::string& groupname, RPCHookPtr rpcHook); @@ -82,7 +70,7 @@ class ROCKETMQCLIENT_API DefaultMQPullConsumer : public MQPullConsumer, public D void fetchMessageQueuesInBalance(const std::string& topic, std::vector& mqs) override; public: - void setRPCHook(std::shared_ptr rpcHook); + void setRPCHook(RPCHookPtr rpcHook); protected: std::shared_ptr m_pullConsumerDelegate; diff --git a/include/DefaultMQPullConsumerConfig.h b/include/DefaultMQPullConsumerConfig.h new file mode 100644 index 000000000..835c0762d --- /dev/null +++ b/include/DefaultMQPullConsumerConfig.h @@ -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 __DEFAULT_MQ_PULL_CONSUMER_CONFIG_H__ +#define __DEFAULT_MQ_PULL_CONSUMER_CONFIG_H__ + +#include "AllocateMQStrategy.h" +#include "ConsumeType.h" +#include "MQClientConfig.h" + +namespace rocketmq { + +class DefaultMQPullConsumerConfig; +typedef std::shared_ptr DefaultMQPullConsumerConfigPtr; + +class ROCKETMQCLIENT_API DefaultMQPullConsumerConfig : virtual public MQClientConfig { + public: + virtual ~DefaultMQPullConsumerConfig() = default; + + virtual MessageModel getMessageModel() const = 0; + virtual void setMessageModel(MessageModel messageModel) = 0; + + virtual AllocateMQStrategy* getAllocateMQStrategy() const = 0; + virtual void setAllocateMQStrategy(AllocateMQStrategy* strategy) = 0; +}; + +} // namespace rocketmq + +#endif // __DEFAULT_MQ_PULL_CONSUMER_CONFIG_H__ diff --git a/include/DefaultMQPullConsumerConfigProxy.h b/include/DefaultMQPullConsumerConfigProxy.h new file mode 100644 index 000000000..101acf4bf --- /dev/null +++ b/include/DefaultMQPullConsumerConfigProxy.h @@ -0,0 +1,48 @@ +/* + * 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 __DEFAULT_MQ_PULL_CONSUMER_CONFIG_PROXY_H__ +#define __DEFAULT_MQ_PULL_CONSUMER_CONFIG_PROXY_H__ + +#include "DefaultMQPullConsumerConfig.h" +#include "MQClientConfigProxy.h" + +namespace rocketmq { + +class ROCKETMQCLIENT_API DefaultMQPullConsumerConfigProxy : virtual public DefaultMQPullConsumerConfig, + public MQClientConfigProxy { + public: + DefaultMQPullConsumerConfigProxy(DefaultMQPullConsumerConfigPtr consumerConfig) + : MQClientConfigProxy(consumerConfig), m_consumerConfig(consumerConfig) {} + virtual ~DefaultMQPullConsumerConfigProxy() = default; + + MessageModel getMessageModel() const override { return m_consumerConfig->getMessageModel(); } + + void setMessageModel(MessageModel messageModel) override { m_consumerConfig->setMessageModel(messageModel); } + + AllocateMQStrategy* getAllocateMQStrategy() const override { return m_consumerConfig->getAllocateMQStrategy(); } + + void setAllocateMQStrategy(AllocateMQStrategy* strategy) override { + m_consumerConfig->setAllocateMQStrategy(strategy); + } + + private: + DefaultMQPullConsumerConfigPtr m_consumerConfig; +}; + +} // namespace rocketmq + +#endif // __DEFAULT_MQ_PULL_CONSUMER_CONFIG_PROXY_H__ diff --git a/include/DefaultMQPushConsumer.h b/include/DefaultMQPushConsumer.h index 1caf98f1b..e90eb953d 100755 --- a/include/DefaultMQPushConsumer.h +++ b/include/DefaultMQPushConsumer.h @@ -17,79 +17,13 @@ #ifndef __DEFAULT_MQ_PUSH_CONSUMER_H__ #define __DEFAULT_MQ_PUSH_CONSUMER_H__ -#include "AllocateMQStrategy.h" -#include "DefaultMQConsumer.h" +#include "DefaultMQPushConsumerConfigProxy.h" #include "MQPushConsumer.h" #include "RPCHook.h" namespace rocketmq { -class ROCKETMQCLIENT_API DefaultMQPushConsumerConfig : public DefaultMQConsumerConfig { - public: - DefaultMQPushConsumerConfig(); - virtual ~DefaultMQPushConsumerConfig() = default; - - ConsumeFromWhere getConsumeFromWhere() const { return m_consumeFromWhere; } - void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) { m_consumeFromWhere = consumeFromWhere; } - - std::string getConsumeTimestamp() { return m_consumeTimestamp; } - void setConsumeTimestamp(std::string consumeTimestamp) { m_consumeTimestamp = consumeTimestamp; } - - /** - * consuming thread count, default value is cpu cores - */ - int getConsumeThreadNum() const { return m_consumeThreadNum; } - void setConsumeThreadNum(int threadNum) { - if (threadNum > 0) { - m_consumeThreadNum = threadNum; - } - } - - /** - * the pull number of message size by each pullMsg for orderly consume, default value is 1 - */ - int getConsumeMessageBatchMaxSize() const { return m_consumeMessageBatchMaxSize; } - void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) { - if (consumeMessageBatchMaxSize >= 1) { - m_consumeMessageBatchMaxSize = consumeMessageBatchMaxSize; - } - } - - /** - * max cache msg size per Queue in memory if consumer could not consume msgs immediately, - * default maxCacheMsgSize per Queue is 1000, set range is:1~65535 - */ - int getMaxCacheMsgSizePerQueue() const { return m_maxMsgCacheSize; } - void setMaxCacheMsgSizePerQueue(int maxCacheSize) { - if (maxCacheSize > 0 && maxCacheSize < 65535) { - m_maxMsgCacheSize = maxCacheSize; - } - } - - int getAsyncPullTimeout() const { return m_asyncPullTimeout; } - void setAsyncPullTimeout(int asyncPullTimeout) { m_asyncPullTimeout = asyncPullTimeout; } - - int getMaxReconsumeTimes() { return m_maxReconsumeTimes; } - void setMaxReconsumeTimes(int maxReconsumeTimes) { m_maxReconsumeTimes = maxReconsumeTimes; } - - AllocateMQStrategy* getAllocateMQStrategy() { return m_allocateMQStrategy.get(); } - void setAllocateMQStrategy(AllocateMQStrategy* strategy) { m_allocateMQStrategy.reset(strategy); } - - protected: - ConsumeFromWhere m_consumeFromWhere; - std::string m_consumeTimestamp; - - int m_consumeThreadNum; - int m_consumeMessageBatchMaxSize; - int m_maxMsgCacheSize; - - int m_asyncPullTimeout; // 30s - int m_maxReconsumeTimes; - - std::unique_ptr m_allocateMQStrategy; -}; - -class ROCKETMQCLIENT_API DefaultMQPushConsumer : public MQPushConsumer, public DefaultMQPushConsumerConfig { +class ROCKETMQCLIENT_API DefaultMQPushConsumer : public MQPushConsumer, public DefaultMQPushConsumerConfigProxy { public: DefaultMQPushConsumer(const std::string& groupname); DefaultMQPushConsumer(const std::string& groupname, RPCHookPtr rpcHook); @@ -108,13 +42,15 @@ class ROCKETMQCLIENT_API DefaultMQPushConsumer : public MQPushConsumer, public D void registerMessageListener(MessageListenerConcurrently* messageListener) override; void registerMessageListener(MessageListenerOrderly* messageListener) override; + MQMessageListener* getMessageListener() const override; + void subscribe(const std::string& topic, const std::string& subExpression) override; void suspend() override; void resume() override; public: - void setRPCHook(std::shared_ptr rpcHook); + void setRPCHook(RPCHookPtr rpcHook); protected: std::shared_ptr m_pushConsumerDelegate; diff --git a/include/DefaultMQPushConsumerConfig.h b/include/DefaultMQPushConsumerConfig.h new file mode 100644 index 000000000..0c571cc2e --- /dev/null +++ b/include/DefaultMQPushConsumerConfig.h @@ -0,0 +1,76 @@ +/* + * 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 __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_H__ +#define __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_H__ + +#include "AllocateMQStrategy.h" +#include "ConsumeType.h" +#include "MQClientConfig.h" + +namespace rocketmq { + +class DefaultMQPushConsumerConfig; +typedef std::shared_ptr DefaultMQPushConsumerConfigPtr; + +class ROCKETMQCLIENT_API DefaultMQPushConsumerConfig : virtual public MQClientConfig { + public: + virtual ~DefaultMQPushConsumerConfig() = default; + + virtual MessageModel getMessageModel() const = 0; + virtual void setMessageModel(MessageModel messageModel) = 0; + + virtual ConsumeFromWhere getConsumeFromWhere() const = 0; + virtual void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) = 0; + + virtual std::string getConsumeTimestamp() = 0; + virtual void setConsumeTimestamp(std::string consumeTimestamp) = 0; + + /** + * consuming thread count, default value is cpu cores + */ + virtual int getConsumeThreadNum() const = 0; + virtual void setConsumeThreadNum(int threadNum) = 0; + + /** + * the pull number of message size by each pullMsg for orderly consume, default value is 1 + */ + virtual int getConsumeMessageBatchMaxSize() const = 0; + virtual void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) = 0; + + /** + * max cache msg size per Queue in memory if consumer could not consume msgs immediately, + * default maxCacheMsgSize per Queue is 1000, set range is:1~65535 + */ + virtual int getMaxCacheMsgSizePerQueue() const = 0; + virtual void setMaxCacheMsgSizePerQueue(int maxCacheSize) = 0; + + virtual int getAsyncPullTimeout() const = 0; + virtual void setAsyncPullTimeout(int asyncPullTimeout) = 0; + + virtual int getMaxReconsumeTimes() const = 0; + virtual void setMaxReconsumeTimes(int maxReconsumeTimes) = 0; + + virtual long getPullTimeDelayMillsWhenException() const = 0; + virtual void setPullTimeDelayMillsWhenException(long pullTimeDelayMillsWhenException) = 0; + + virtual AllocateMQStrategy* getAllocateMQStrategy() const = 0; + virtual void setAllocateMQStrategy(AllocateMQStrategy* strategy) = 0; +}; + +} // namespace rocketmq + +#endif // __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_H__ diff --git a/include/DefaultMQPushConsumerConfigProxy.h b/include/DefaultMQPushConsumerConfigProxy.h new file mode 100644 index 000000000..ef0c4de54 --- /dev/null +++ b/include/DefaultMQPushConsumerConfigProxy.h @@ -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 __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_PROXY_H__ +#define __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_PROXY_H__ + +#include "DefaultMQPushConsumerConfig.h" +#include "MQClientConfigProxy.h" + +namespace rocketmq { + +class ROCKETMQCLIENT_API DefaultMQPushConsumerConfigProxy : virtual public DefaultMQPushConsumerConfig, + public MQClientConfigProxy { + public: + DefaultMQPushConsumerConfigProxy(DefaultMQPushConsumerConfigPtr consumerConfig) + : MQClientConfigProxy(consumerConfig), m_consumerConfig(consumerConfig) {} + virtual ~DefaultMQPushConsumerConfigProxy() = default; + + DefaultMQPushConsumerConfigPtr getRealConfig() const { return m_consumerConfig; } + + MessageModel getMessageModel() const override { return m_consumerConfig->getMessageModel(); } + + void setMessageModel(MessageModel messageModel) override { m_consumerConfig->setMessageModel(messageModel); } + + ConsumeFromWhere getConsumeFromWhere() const override { return m_consumerConfig->getConsumeFromWhere(); } + + void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) override { + m_consumerConfig->setConsumeFromWhere(consumeFromWhere); + } + + std::string getConsumeTimestamp() override { return m_consumerConfig->getConsumeTimestamp(); } + + void setConsumeTimestamp(std::string consumeTimestamp) override { + m_consumerConfig->setConsumeTimestamp(consumeTimestamp); + } + + int getConsumeThreadNum() const override { return m_consumerConfig->getConsumeThreadNum(); } + + void setConsumeThreadNum(int threadNum) override { return m_consumerConfig->setConsumeThreadNum(threadNum); } + + int getConsumeMessageBatchMaxSize() const override { return m_consumerConfig->getConsumeMessageBatchMaxSize(); } + + void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) override { + m_consumerConfig->setConsumeMessageBatchMaxSize(consumeMessageBatchMaxSize); + } + + int getMaxCacheMsgSizePerQueue() const override { return m_consumerConfig->getMaxCacheMsgSizePerQueue(); } + + void setMaxCacheMsgSizePerQueue(int maxCacheSize) override { + m_consumerConfig->setMaxCacheMsgSizePerQueue(maxCacheSize); + } + + int getAsyncPullTimeout() const override { return m_consumerConfig->getAsyncPullTimeout(); } + + void setAsyncPullTimeout(int asyncPullTimeout) override { m_consumerConfig->setAsyncPullTimeout(asyncPullTimeout); } + + int getMaxReconsumeTimes() const override { return m_consumerConfig->getMaxReconsumeTimes(); } + + void setMaxReconsumeTimes(int maxReconsumeTimes) override { + m_consumerConfig->setMaxReconsumeTimes(maxReconsumeTimes); + } + + long getPullTimeDelayMillsWhenException() const override { + return m_consumerConfig->getPullTimeDelayMillsWhenException(); + } + + void setPullTimeDelayMillsWhenException(long pullTimeDelayMillsWhenException) override { + m_consumerConfig->setPullTimeDelayMillsWhenException(pullTimeDelayMillsWhenException); + } + + AllocateMQStrategy* getAllocateMQStrategy() const override { return m_consumerConfig->getAllocateMQStrategy(); } + + void setAllocateMQStrategy(AllocateMQStrategy* strategy) override { + m_consumerConfig->setAllocateMQStrategy(strategy); + } + + private: + DefaultMQPushConsumerConfigPtr m_consumerConfig; +}; + +} // namespace rocketmq + +#endif // __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_PROXY_H__ diff --git a/include/MQClientConfig.h b/include/MQClientConfig.h index cb4de5480..9cc5bc636 100644 --- a/include/MQClientConfig.h +++ b/include/MQClientConfig.h @@ -17,78 +17,57 @@ #ifndef __MQ_CLIENT_CONFIG_H__ #define __MQ_CLIENT_CONFIG_H__ +#include #include #include "RocketMQClient.h" namespace rocketmq { +class MQClientConfig; +typedef std::shared_ptr MQClientConfigPtr; + /** * MQ Client Config */ class ROCKETMQCLIENT_API MQClientConfig { public: - MQClientConfig(); virtual ~MQClientConfig() = default; - // clientId=processId-ipAddr@instanceName - std::string buildMQClientId() const; + // clientId = clientIP @ processId [ @ unitName ] + virtual std::string buildMQClientId() const = 0; + + virtual const std::string& getGroupName() const = 0; + virtual void setGroupName(const std::string& groupname) = 0; - // groupName - const std::string& getGroupName() const; - void setGroupName(const std::string& groupname); + virtual const std::string& getNamesrvAddr() const = 0; + virtual void setNamesrvAddr(const std::string& namesrvAddr) = 0; - const std::string& getNamesrvAddr() const; - void setNamesrvAddr(const std::string& namesrvAddr); + virtual const std::string& getInstanceName() const = 0; + virtual void setInstanceName(const std::string& instanceName) = 0; - const std::string& getInstanceName() const; - void setInstanceName(const std::string& instanceName); + virtual void changeInstanceNameToPID() = 0; - void changeInstanceNameToPID(); + virtual const std::string& getUnitName() const = 0; + virtual void setUnitName(std::string unitName) = 0; /** - * 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 + * the num of threads to distribute network data **/ - int getTcpTransportWorkerThreadNum() const; - void setTcpTransportWorkerThreadNum(int num); + virtual int getTcpTransportWorkerThreadNum() const = 0; + virtual void setTcpTransportWorkerThreadNum(int num) = 0; /** - * 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; + * timeout of tcp connect **/ - uint64_t getTcpTransportConnectTimeout() const; - void setTcpTransportConnectTimeout(uint64_t timeout); // ms + virtual uint64_t getTcpTransportConnectTimeout() const = 0; + virtual void setTcpTransportConnectTimeout(uint64_t timeout) = 0; // ms /** - * 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 + * timeout of tryLock tcpTransport, the minimun value is 1000ms **/ - uint64_t getTcpTransportTryLockTimeout() const; - void setTcpTransportTryLockTimeout(uint64_t timeout); // ms - - const std::string& getUnitName() const; - void setUnitName(std::string unitName); - - protected: - std::string m_namesrvAddr; - std::string m_instanceName; - std::string m_groupName; - std::string m_unitName; - - int m_tcpWorkerThreadNum; - uint64_t m_tcpConnectTimeout; // ms - uint64_t m_tcpTransportTryLockTimeout; // s + virtual uint64_t getTcpTransportTryLockTimeout() const = 0; + virtual void setTcpTransportTryLockTimeout(uint64_t timeout) = 0; // ms }; } // namespace rocketmq diff --git a/include/MQClientConfigProxy.h b/include/MQClientConfigProxy.h new file mode 100644 index 000000000..5714aadab --- /dev/null +++ b/include/MQClientConfigProxy.h @@ -0,0 +1,73 @@ +/* + * 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_CONFIG_PROXY_H__ +#define __MQ_CLIENT_CONFIG_PROXY_H__ + +#include "MQClientConfig.h" + +namespace rocketmq { + +class ROCKETMQCLIENT_API MQClientConfigProxy : virtual public MQClientConfig { + public: + MQClientConfigProxy(MQClientConfigPtr clientConfig) : m_clientConfig(clientConfig) {} + virtual ~MQClientConfigProxy() = default; + + MQClientConfigPtr getRealConfig() const { return m_clientConfig; } + + std::string buildMQClientId() const override { return m_clientConfig->buildMQClientId(); } + + const std::string& getGroupName() const override { return m_clientConfig->getGroupName(); } + + void setGroupName(const std::string& groupname) override { m_clientConfig->setGroupName(groupname); } + + const std::string& getNamesrvAddr() const override { return m_clientConfig->getNamesrvAddr(); } + + void setNamesrvAddr(const std::string& namesrvAddr) override { m_clientConfig->setNamesrvAddr(namesrvAddr); } + + const std::string& getInstanceName() const override { return m_clientConfig->getInstanceName(); } + + void setInstanceName(const std::string& instanceName) override { m_clientConfig->setInstanceName(instanceName); } + + void changeInstanceNameToPID() override { m_clientConfig->changeInstanceNameToPID(); } + + const std::string& getUnitName() const override { return m_clientConfig->getUnitName(); } + + void setUnitName(std::string unitName) override { m_clientConfig->setUnitName(unitName); } + + int getTcpTransportWorkerThreadNum() const override { return m_clientConfig->getTcpTransportWorkerThreadNum(); } + + void setTcpTransportWorkerThreadNum(int num) override { m_clientConfig->setTcpTransportWorkerThreadNum(num); } + + uint64_t getTcpTransportConnectTimeout() const override { return m_clientConfig->getTcpTransportConnectTimeout(); } + + void setTcpTransportConnectTimeout(uint64_t timeout) override { + m_clientConfig->setTcpTransportConnectTimeout(timeout); + } + + uint64_t getTcpTransportTryLockTimeout() const override { return m_clientConfig->getTcpTransportTryLockTimeout(); } + + void setTcpTransportTryLockTimeout(uint64_t timeout) override { + m_clientConfig->setTcpTransportTryLockTimeout(timeout); + } + + private: + MQClientConfigPtr m_clientConfig; +}; + +} // namespace rocketmq + +#endif // __MQ_CLIENT_CONFIG_PROXY_H__ diff --git a/include/MQClientException.h b/include/MQClientException.h index 56deb7a4a..4e2498dbb 100644 --- a/include/MQClientException.h +++ b/include/MQClientException.h @@ -29,10 +29,22 @@ namespace rocketmq { class ROCKETMQCLIENT_API MQException : public std::exception { public: MQException(const std::string& msg, int error, const char* file, int line) noexcept - : m_error(error), m_line(line), m_msg(msg), m_file(file), m_type("MQException") {} - - MQException(const std::string& msg, int error, const char* file, const char* type, int line) noexcept - : m_error(error), m_line(line), m_msg(msg), m_file(file), m_type(type) {} + : MQException(msg, error, nullptr, file, line) {} + + MQException(const std::string& msg, int error, std::exception_ptr cause, const char* file, int line) noexcept + : MQException("MQException", msg, error, cause, file, line) {} + + MQException(const std::string& type, + const std::string& msg, + int error, + std::exception_ptr cause, + const char* file, + int line) noexcept : m_type(type), + m_msg(msg), + m_error(error), + m_cause(cause), + m_file(file), + m_line(line) {} virtual ~MQException() noexcept = default; @@ -45,18 +57,27 @@ class ROCKETMQCLIENT_API MQException : public std::exception { return m_what_.c_str(); } - int GetError() const noexcept { return m_error; } - int GetLine() { return m_line; } - const char* GetMsg() { return m_msg.c_str(); } - const char* GetFile() { return m_file.c_str(); } const char* GetType() const noexcept { return m_type.c_str(); } + const std::string& GetErrorMessage() const noexcept { return m_msg; } + const char* GetMsg() const noexcept { return m_msg.c_str(); } + + int GetError() const noexcept { return m_error; } + + std::exception_ptr GetCause() const { return m_cause; } + + const char* GetFile() const noexcept { return m_file.c_str(); } + int GetLine() const noexcept { return m_line; } + protected: - int m_error; - int m_line; + std::string m_type; std::string m_msg; + int m_error; + + std::exception_ptr m_cause; + std::string m_file; - std::string m_type; + int m_line; mutable std::string m_what_; }; @@ -66,32 +87,42 @@ inline std::ostream& operator<<(std::ostream& os, const MQException& e) { return os; } -#define DEFINE_MQCLIENTEXCEPTION2(name, super) \ - class ROCKETMQCLIENT_API name : public super { \ - public: \ - name(const std::string& msg, int error, const char* file, int line) noexcept \ - : super(msg, error, file, #name, line) {} \ - \ - protected: \ - name(const std::string& msg, int error, const char* file, const char* type, int line) noexcept \ - : super(msg, error, file, type, line) {} \ +#define DEFINE_MQEXCEPTION2(name, super) \ + class ROCKETMQCLIENT_API name : public super { \ + public: \ + name(const std::string& msg, int error, const char* file, int line) noexcept \ + : name(msg, error, nullptr, file, line) {} \ + name(const std::string& msg, int error, std::exception_ptr cause, const char* file, int line) noexcept \ + : name(#name, msg, error, cause, file, line) {} \ + \ + protected: \ + name(const std::string& type, \ + const std::string& msg, \ + int error, \ + std::exception_ptr cause, \ + const char* file, \ + int line) noexcept : super(type, msg, error, cause, file, line) {} \ }; -#define DEFINE_MQCLIENTEXCEPTION(name) DEFINE_MQCLIENTEXCEPTION2(name, MQException) - -DEFINE_MQCLIENTEXCEPTION(MQClientException) -DEFINE_MQCLIENTEXCEPTION(MQBrokerException) -DEFINE_MQCLIENTEXCEPTION(InterruptedException) -DEFINE_MQCLIENTEXCEPTION(RemotingException) -DEFINE_MQCLIENTEXCEPTION2(RemotingCommandException, RemotingException) -DEFINE_MQCLIENTEXCEPTION2(RemotingConnectException, RemotingException) -DEFINE_MQCLIENTEXCEPTION2(RemotingSendRequestException, RemotingException) -DEFINE_MQCLIENTEXCEPTION2(RemotingTimeoutException, RemotingException) -DEFINE_MQCLIENTEXCEPTION2(RemotingTooMuchRequestException, RemotingException) -DEFINE_MQCLIENTEXCEPTION(UnknownHostException) - -#define THROW_MQEXCEPTION(e, msg, err) throw e(msg, err, __FILE__, __LINE__) -#define NEW_MQEXCEPTION(e, msg, err) e(msg, err, __FILE__, __LINE__) +#define DEFINE_MQEXCEPTION(name) DEFINE_MQEXCEPTION2(name, MQException) + +DEFINE_MQEXCEPTION(MQClientException) +DEFINE_MQEXCEPTION(MQBrokerException) +DEFINE_MQEXCEPTION(InterruptedException) +DEFINE_MQEXCEPTION(RemotingException) +DEFINE_MQEXCEPTION2(RemotingCommandException, RemotingException) +DEFINE_MQEXCEPTION2(RemotingConnectException, RemotingException) +DEFINE_MQEXCEPTION2(RemotingSendRequestException, RemotingException) +DEFINE_MQEXCEPTION2(RemotingTimeoutException, RemotingException) +DEFINE_MQEXCEPTION2(RemotingTooMuchRequestException, RemotingException) +DEFINE_MQEXCEPTION(UnknownHostException) +DEFINE_MQEXCEPTION(RequestTimeoutException) + +#define THROW_MQEXCEPTION(e, msg, err) throw e((msg), (err), __FILE__, __LINE__) +#define THROW_MQEXCEPTION2(e, msg, err, cause) throw e((msg), (err), (cause), __FILE__, __LINE__) + +#define NEW_MQEXCEPTION(e, msg, err) e((msg), (err), __FILE__, __LINE__) +#define NEW_MQEXCEPTION2(e, msg, err, cause) e((msg), (err), (cause), __FILE__, __LINE__) } // namespace rocketmq diff --git a/include/MQMessage.h b/include/MQMessage.h index a2a819e4e..19f581d02 100644 --- a/include/MQMessage.h +++ b/include/MQMessage.h @@ -30,6 +30,7 @@ namespace rocketmq { class MQMessage; typedef MQMessage* MQMessagePtr; typedef std::shared_ptr MQMessagePtr2; +typedef std::unique_ptr MQMessagePtr3; class ROCKETMQCLIENT_API MQMessage { public: diff --git a/include/MQMessageConst.h b/include/MQMessageConst.h index 61c5c00cf..06572197e 100644 --- a/include/MQMessageConst.h +++ b/include/MQMessageConst.h @@ -52,6 +52,13 @@ class ROCKETMQCLIENT_API MQMessageConst { static const std::string PROPERTY_TRANSACTION_CHECK_TIMES; static const std::string PROPERTY_CHECK_IMMUNITY_TIME_IN_SECONDS; static const std::string PROPERTY_INSTANCE_ID; + static const std::string PROPERTY_CORRELATION_ID; + static const std::string PROPERTY_MESSAGE_REPLY_TO_CLIENT; + static const std::string PROPERTY_MESSAGE_TTL; + static const std::string PROPERTY_REPLY_MESSAGE_ARRIVE_TIME; + static const std::string PROPERTY_PUSH_REPLY_TIME; + static const std::string PROPERTY_CLUSTER; + static const std::string PROPERTY_MESSAGE_TYPE; // sdk internal use only static const std::string PROPERTY_ALREADY_COMPRESSED_FLAG; diff --git a/include/MQMessageExt.h b/include/MQMessageExt.h index f14204501..42e50783e 100644 --- a/include/MQMessageExt.h +++ b/include/MQMessageExt.h @@ -42,9 +42,9 @@ class ROCKETMQCLIENT_API MQMessageExt : public MQMessage { MQMessageExt(); MQMessageExt(int queueId, int64_t bornTimestamp, - sockaddr bornHost, + const struct sockaddr* bornHost, int64_t storeTimestamp, - sockaddr storeHost, + const struct sockaddr* storeHost, std::string msgId); virtual ~MQMessageExt(); @@ -72,16 +72,16 @@ class ROCKETMQCLIENT_API MQMessageExt : public MQMessage { int64_t getBornTimestamp() const; void setBornTimestamp(int64_t bornTimestamp); - const sockaddr& getBornHost() const; + const struct sockaddr* getBornHost() const; std::string getBornHostString() const; - void setBornHost(const sockaddr& bornHost); + void setBornHost(const struct sockaddr* bornHost); int64_t getStoreTimestamp() const; void setStoreTimestamp(int64_t storeTimestamp); - const sockaddr& getStoreHost() const; + const struct sockaddr* getStoreHost() const; std::string getStoreHostString() const; - void setStoreHost(const sockaddr& storeHost); + void setStoreHost(const struct sockaddr* storeHost); int32_t getReconsumeTimes() const; void setReconsumeTimes(int32_t reconsumeTimes); @@ -111,15 +111,16 @@ class ROCKETMQCLIENT_API MQMessageExt : public MQMessage { int64_t m_commitLogOffset; int32_t m_sysFlag; int64_t m_bornTimestamp; - sockaddr m_bornHost; + struct sockaddr* m_bornHost; int64_t m_storeTimestamp; - sockaddr m_storeHost; + struct sockaddr* m_storeHost; int32_t m_reconsumeTimes; int64_t m_preparedTransactionOffset; std::string m_msgId; }; class ROCKETMQCLIENT_API MQMessageClientExt : public MQMessageExt { + public: const std::string& getOffsetMsgId() const; void setOffsetMsgId(const std::string& offsetMsgId); diff --git a/include/MQMessageListener.h b/include/MQMessageListener.h index d7b700a27..61bb24375 100644 --- a/include/MQMessageListener.h +++ b/include/MQMessageListener.h @@ -30,33 +30,15 @@ enum ConsumeStatus { RECONSUME_LATER }; -/*enum ConsumeOrderlyStatus -{*/ -/** - * Success consumption - */ -// SUCCESS, -/** - * Rollback consumption(only for binlog consumption) - */ -// ROLLBACK, -/** - * Commit offset(only for binlog consumption) - */ -// COMMIT, -/** - * Suspend current queue a moment - */ -// SUSPEND_CURRENT_QUEUE_A_MOMENT -/*};*/ - enum MessageListenerType { messageListenerDefaultly = 0, messageListenerOrderly = 1, messageListenerConcurrently = 2 }; class ROCKETMQCLIENT_API MQMessageListener { public: virtual ~MQMessageListener() = default; + virtual MessageListenerType getMessageListenerType() { return messageListenerDefaultly; } + // Recommended virtual ConsumeStatus consumeMessage(const std::vector& msgs) { std::vector msgs2; msgs2.reserve(msgs.size()); @@ -67,7 +49,7 @@ class ROCKETMQCLIENT_API MQMessageListener { } // SDK will be responsible for the lifecycle of messages. - virtual ConsumeStatus consumeMessage(const std::vector& msgs) = 0; + virtual ConsumeStatus consumeMessage(const std::vector& msgs) { return RECONSUME_LATER; }; }; class ROCKETMQCLIENT_API MessageListenerConcurrently : virtual public MQMessageListener { diff --git a/include/MQMessageQueue.h b/include/MQMessageQueue.h index a37cdf579..8fe594070 100644 --- a/include/MQMessageQueue.h +++ b/include/MQMessageQueue.h @@ -44,6 +44,8 @@ class ROCKETMQCLIENT_API MQMessageQueue { void setQueueId(int queueId); bool operator==(const MQMessageQueue& mq) const; + bool operator!=(const MQMessageQueue& mq) const { return !operator==(mq); } + bool operator<(const MQMessageQueue& mq) const; int compareTo(const MQMessageQueue& mq) const; diff --git a/include/MQProducer.h b/include/MQProducer.h index 36878d98f..81a1c3195 100644 --- a/include/MQProducer.h +++ b/include/MQProducer.h @@ -74,6 +74,9 @@ class ROCKETMQCLIENT_API MQProducer { virtual SendResult send(std::vector& msgs, long timeout) = 0; virtual SendResult send(std::vector& msgs, const MQMessageQueue& mq) = 0; virtual SendResult send(std::vector& msgs, const MQMessageQueue& mq, long timeout) = 0; + + // RPC + virtual MQMessagePtr request(MQMessagePtr msg, long timeout) = 0; }; } // namespace rocketmq diff --git a/include/MQPushConsumer.h b/include/MQPushConsumer.h index 76d5f9386..8d59f09f4 100644 --- a/include/MQPushConsumer.h +++ b/include/MQPushConsumer.h @@ -29,6 +29,8 @@ class ROCKETMQCLIENT_API MQPushConsumer : public MQConsumer { virtual void registerMessageListener(MessageListenerConcurrently* messageListener) = 0; virtual void registerMessageListener(MessageListenerOrderly* messageListener) = 0; + virtual MQMessageListener* getMessageListener() const = 0; + virtual void subscribe(const std::string& topic, const std::string& subExpression) = 0; // virtual void subscribe(const std::string& topic, MessageSelector* selector) = 0; diff --git a/include/DefaultMQConsumer.h b/include/MessageUtil.h similarity index 64% rename from include/DefaultMQConsumer.h rename to include/MessageUtil.h index 1f103aca1..ad6808a37 100644 --- a/include/DefaultMQConsumer.h +++ b/include/MessageUtil.h @@ -14,25 +14,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __DEFAULT_MQ_CONSUMER_H__ -#define __DEFAULT_MQ_CONSUMER_H__ +#ifndef __MESSAGE_UTIL_H__ +#define __MESSAGE_UTIL_H__ -#include "ConsumeType.h" -#include "MQClientConfig.h" +#include + +#include "MQClientException.h" +#include "MQMessage.h" namespace rocketmq { -class ROCKETMQCLIENT_API DefaultMQConsumerConfig : public MQClientConfig { +class ROCKETMQCLIENT_API MessageUtil { public: - DefaultMQConsumerConfig() : m_messageModel(CLUSTERING) {} - - MessageModel getMessageModel() const { return m_messageModel; } - void setMessageModel(MessageModel messageModel) { m_messageModel = messageModel; } + static MQMessagePtr createReplyMessage(const MQMessagePtr requestMessage, + const std::string& body) throw(MQClientException); - protected: - MessageModel m_messageModel; + static const std::string& getReplyToClient(const MQMessagePtr msg); }; } // namespace rocketmq -#endif // __DEFAULT_MQ_CONSUMER_H__ +#endif // __MESSAGE_UTIL_H__ diff --git a/include/PullResult.h b/include/PullResult.h index d43fda23e..eccf19ea5 100644 --- a/include/PullResult.h +++ b/include/PullResult.h @@ -28,12 +28,11 @@ enum PullStatus { FOUND, NO_NEW_MSG, NO_MATCHED_MSG, + NO_LATEST_MSG, OFFSET_ILLEGAL, BROKER_TIMEOUT // indicate pull request timeout or received NULL response }; -static const char* EnumStrings[] = {"FOUND", "NO_NEW_MSG", "NO_MATCHED_MSG", "OFFSET_ILLEGAL", "BROKER_TIMEOUT"}; - class ROCKETMQCLIENT_API PullResult { public: PullResult(); @@ -53,13 +52,7 @@ class ROCKETMQCLIENT_API PullResult { virtual ~PullResult(); - std::string toString() const { - std::stringstream ss; - ss << "PullResult [ pullStatus=" << EnumStrings[pullStatus] << ", nextBeginOffset=" << nextBeginOffset - << ", minOffset=" << minOffset << ", maxOffset=" << maxOffset << ", msgFoundList=" << msgFoundList.size() - << " ]"; - return ss.str(); - } + std::string toString() const; public: PullStatus pullStatus; diff --git a/include/RemotingCommand.h b/include/RemotingCommand.h index e204445a8..2fa8a2745 100644 --- a/include/RemotingCommand.h +++ b/include/RemotingCommand.h @@ -22,14 +22,11 @@ #include #include "CommandCustomHeader.h" +#include "DataBlock.h" #include "MQClientException.h" namespace rocketmq { -class MemoryBlock; -typedef MemoryBlock* MemoryBlockPtr; -typedef std::shared_ptr MemoryBlockPtr2; - class ROCKETMQCLIENT_API RemotingCommand { public: static int32_t createNewRequestId(); @@ -37,6 +34,7 @@ class ROCKETMQCLIENT_API RemotingCommand { public: RemotingCommand() : m_code(0) {} RemotingCommand(int32_t code, CommandCustomHeader* customHeader = nullptr); + RemotingCommand(int32_t code, const std::string& remark, CommandCustomHeader* customHeader = nullptr); RemotingCommand(int32_t code, const std::string& language, int32_t version, @@ -71,13 +69,13 @@ class ROCKETMQCLIENT_API RemotingCommand { CommandCustomHeader* readCustomHeader() const; - MemoryBlockPtr2 getBody(); + MemoryBlockPtr2 getBody() const; void setBody(MemoryBlock* body); void setBody(MemoryBlockPtr2 body); void setBody(const std::string& body); public: - MemoryBlockPtr encode(); + MemoryBlockPtr encode() const; template H* decodeCommandCustomHeader(bool useCache); @@ -85,7 +83,7 @@ class ROCKETMQCLIENT_API RemotingCommand { template H* decodeCommandCustomHeader(); - static RemotingCommand* Decode(MemoryBlockPtr2& package); + static RemotingCommand* Decode(MemoryBlockPtr2 package, bool havePackageLen = false); std::string toString() const; diff --git a/include/RequestCallback.h b/include/RequestCallback.h new file mode 100644 index 000000000..8b31098b9 --- /dev/null +++ b/include/RequestCallback.h @@ -0,0 +1,48 @@ +/* + * 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 __REQUEST_CALLBACK_H__ +#define __REQUEST_CALLBACK_H__ + +#include "MQClientException.h" +#include "MQMessage.h" + +namespace rocketmq { + +enum RequestCallbackType { REQUEST_CALLBACK_TYPE_SIMPLE = 0, REQUEST_CALLBACK_TYPE_AUTO_DELETE = 1 }; + +class ROCKETMQCLIENT_API RequestCallback { + public: + virtual ~RequestCallback() = default; + + virtual void onSuccess(MQMessagePtr3 message) { onSuccess(message.get()); } + + // SDK will be responsible for the lifecycle of message. + virtual void onSuccess(MQMessagePtr message) = 0; + + virtual void onException(MQException& e) noexcept = 0; + + virtual RequestCallbackType getRequestCallbackType() const { return REQUEST_CALLBACK_TYPE_SIMPLE; } +}; + +class ROCKETMQCLIENT_API AutoDeleteRequestCallback : public RequestCallback { + public: + RequestCallbackType getRequestCallbackType() const override final { return REQUEST_CALLBACK_TYPE_AUTO_DELETE; } +}; + +} // namespace rocketmq + +#endif // __REQUEST_CALLBACK_H__ diff --git a/include/RocketMQClient.h b/include/RocketMQClient.h index 09be80128..fc5bb6a92 100644 --- a/include/RocketMQClient.h +++ b/include/RocketMQClient.h @@ -37,30 +37,6 @@ #define ROCKETMQCLIENT_API #endif // WIN32 -/** A platform-independent 8-bit signed integer type. */ -typedef int8_t int8; - -/** A platform-independent 8-bit unsigned integer type. */ -typedef uint8_t uint8; - -/** A platform-independent 16-bit signed integer type. */ -typedef int16_t int16; - -/** A platform-independent 16-bit unsigned integer type. */ -typedef uint16_t uint16; - -/** A platform-independent 32-bit signed integer type. */ -typedef int32_t int32; - -/** A platform-independent 32-bit unsigned integer type. */ -typedef uint32_t uint32; - -/** A platform-independent 64-bit integer type. */ -typedef int64_t int64; - -/** A platform-independent 64-bit unsigned integer type. */ -typedef uint64_t uint64; - #ifdef WIN32 #define SIZET_FMT "%lu" #else diff --git a/include/SendCallback.h b/include/SendCallback.h index 7370250d4..e01f513e5 100755 --- a/include/SendCallback.h +++ b/include/SendCallback.h @@ -22,7 +22,7 @@ namespace rocketmq { -enum SendCallbackType { SEND_CALLBACK_TYPE_SIMPLE = 0, SEND_CALLBACK_TYPE_ATUO_DELETE = 1 }; +enum SendCallbackType { SEND_CALLBACK_TYPE_SIMPLE = 0, SEND_CALLBACK_TYPE_AUTO_DELETE = 1 }; class ROCKETMQCLIENT_API SendCallback { public: @@ -37,7 +37,7 @@ class ROCKETMQCLIENT_API SendCallback { // async SendCallback will be deleted automatically by rocketmq cpp after invoke callback interface class ROCKETMQCLIENT_API AutoDeleteSendCallback : public SendCallback { public: - SendCallbackType getSendCallbackType() const override final { return SEND_CALLBACK_TYPE_ATUO_DELETE; } + SendCallbackType getSendCallbackType() const override final { return SEND_CALLBACK_TYPE_AUTO_DELETE; } }; } // namespace rocketmq diff --git a/include/SessionCredentials.h b/include/SessionCredentials.h index 5feea08a5..15dd25ab5 100644 --- a/include/SessionCredentials.h +++ b/include/SessionCredentials.h @@ -34,6 +34,12 @@ class ROCKETMQCLIENT_API SessionCredentials { SessionCredentials() : authChannel_("ALIYUN") {} SessionCredentials(const std::string& accessKey, const std::string& secretKey, const std::string& authChannel) : accessKey_(accessKey), secretKey_(secretKey), authChannel_(authChannel) {} + SessionCredentials(const SessionCredentials& other) + : accessKey_(other.accessKey_), + secretKey_(other.secretKey_), + signature_(other.signature_), + signatureMethod_(other.signatureMethod_), + authChannel_(other.authChannel_) {} ~SessionCredentials() = default; diff --git a/include/TransactionMQProducer.h b/include/TransactionMQProducer.h index 97ce077e8..0a1380fcb 100644 --- a/include/TransactionMQProducer.h +++ b/include/TransactionMQProducer.h @@ -18,34 +18,25 @@ #define __TRANSACTION_MQ_PRODUCER_H__ #include "DefaultMQProducer.h" -#include "TransactionListener.h" +#include "TransactionMQProducerConfig.h" namespace rocketmq { -class ROCKETMQCLIENT_API TransactionMQProducerConfig { - public: - TransactionMQProducerConfig(); - virtual ~TransactionMQProducerConfig() = default; - - public: // TransactionMQProducerConfig - TransactionListener* getTransactionListener() const { return m_transactionListener; } - void setTransactionListener(TransactionListener* transactionListener) { m_transactionListener = transactionListener; } - - protected: - TransactionListener* m_transactionListener; -}; - -class ROCKETMQCLIENT_API TransactionMQProducer : public DefaultMQProducer, public TransactionMQProducerConfig { +class ROCKETMQCLIENT_API TransactionMQProducer : public DefaultMQProducer, virtual public TransactionMQProducerConfig { public: TransactionMQProducer(const std::string& groupname); TransactionMQProducer(const std::string& groupname, RPCHookPtr rpcHook); virtual ~TransactionMQProducer(); + public: // TransactionMQProducerConfig + TransactionListener* getTransactionListener() const override; + void setTransactionListener(TransactionListener* transactionListener) override; + public: // MQProducer void start() override; void shutdown() override; - // Transaction + // Transaction: don't delete msg object, until callback occur. TransactionSendResult sendMessageInTransaction(MQMessagePtr msg, void* arg) override; }; diff --git a/include/TransactionMQProducerConfig.h b/include/TransactionMQProducerConfig.h new file mode 100644 index 000000000..e341aa2be --- /dev/null +++ b/include/TransactionMQProducerConfig.h @@ -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 __TRANSACTION_MQ_PRODUCER_CONFIG_H__ +#define __TRANSACTION_MQ_PRODUCER_CONFIG_H__ + +#include "DefaultMQProducerConfig.h" +#include "TransactionListener.h" + +namespace rocketmq { + +class TransactionMQProducerConfig; +typedef std::shared_ptr TransactionMQProducerConfigPtr; + +class ROCKETMQCLIENT_API TransactionMQProducerConfig : virtual public DefaultMQProducerConfig { + public: + virtual ~TransactionMQProducerConfig() = default; + + public: // TransactionMQProducerConfig + virtual TransactionListener* getTransactionListener() const = 0; + virtual void setTransactionListener(TransactionListener* transactionListener) = 0; +}; + +} // namespace rocketmq + +#endif // __TRANSACTION_MQ_PRODUCER_CONFIG_H__ diff --git a/include/c/CMessage.h b/include/c/CMessage.h index 37feda702..7c16f15bc 100644 --- a/include/c/CMessage.h +++ b/include/c/CMessage.h @@ -23,7 +23,6 @@ extern "C" { #endif -// typedef struct _CMessage_ CMessage; typedef struct CMessage CMessage; ROCKETMQCLIENT_API CMessage* CreateMessage(const char* topic); diff --git a/include/c/CMessageExt.h b/include/c/CMessageExt.h index 17c0cee6b..bfd43438b 100644 --- a/include/c/CMessageExt.h +++ b/include/c/CMessageExt.h @@ -23,7 +23,6 @@ extern "C" { #endif -// typedef struct _CMessageExt_ _CMessageExt; typedef struct CMessageExt CMessageExt; ROCKETMQCLIENT_API const char* GetMessageTopic(CMessageExt* msgExt); diff --git a/include/c/CProducer.h b/include/c/CProducer.h index b70e28e65..ed8800c42 100644 --- a/include/c/CProducer.h +++ b/include/c/CProducer.h @@ -28,7 +28,6 @@ extern "C" { #endif -// typedef struct _CProducer_ _CProducer; typedef struct CProducer CProducer; typedef int (*QueueSelectorCallback)(int size, CMessage* msg, void* arg); typedef void (*CSendSuccessCallback)(CSendResult result); @@ -67,12 +66,12 @@ ROCKETMQCLIENT_API int SendMessageSync(CProducer* producer, CMessage* msg, CSend ROCKETMQCLIENT_API int SendBatchMessage(CProducer* producer, CBatchMessage* msg, CSendResult* result); ROCKETMQCLIENT_API int SendMessageAsync(CProducer* producer, CMessage* msg, - CSendSuccessCallback cSendSuccessCallback, - CSendExceptionCallback cSendExceptionCallback); + CSendSuccessCallback sendSuccessCallback, + CSendExceptionCallback sendExceptionCallback); ROCKETMQCLIENT_API int SendAsync(CProducer* producer, CMessage* msg, - COnSendSuccessCallback cSendSuccessCallback, - COnSendExceptionCallback cSendExceptionCallback, + COnSendSuccessCallback sendSuccessCallback, + COnSendExceptionCallback sendExceptionCallback, void* userData); ROCKETMQCLIENT_API int SendMessageOneway(CProducer* producer, CMessage* msg); ROCKETMQCLIENT_API int SendMessageOnewayOrderly(CProducer* producer, @@ -90,8 +89,8 @@ ROCKETMQCLIENT_API int SendMessageOrderlyAsync(CProducer* producer, CMessage* msg, QueueSelectorCallback callback, void* arg, - CSendSuccessCallback cSendSuccessCallback, - CSendExceptionCallback cSendExceptionCallback); + CSendSuccessCallback sendSuccessCallback, + CSendExceptionCallback sendExceptionCallback); ROCKETMQCLIENT_API int SendMessageOrderlyByShardingKey(CProducer* producer, CMessage* msg, const char* shardingKey, diff --git a/include/c/CPushConsumer.h b/include/c/CPushConsumer.h index 3754879e4..4a8bd1400 100644 --- a/include/c/CPushConsumer.h +++ b/include/c/CPushConsumer.h @@ -24,7 +24,6 @@ extern "C" { #endif -// typedef struct _CConsumer_ _CConsumer; typedef struct CPushConsumer CPushConsumer; typedef enum E_CConsumeStatus { E_CONSUME_SUCCESS = 0, E_RECONSUME_LATER = 1 } CConsumeStatus; @@ -40,8 +39,8 @@ ROCKETMQCLIENT_API const char* GetPushConsumerGroupID(CPushConsumer* consumer); ROCKETMQCLIENT_API int SetPushConsumerNameServerAddress(CPushConsumer* consumer, const char* namesrv); ROCKETMQCLIENT_API int SetPushConsumerNameServerDomain(CPushConsumer* consumer, const char* domain); ROCKETMQCLIENT_API int Subscribe(CPushConsumer* consumer, const char* topic, const char* expression); -ROCKETMQCLIENT_API int RegisterMessageCallbackOrderly(CPushConsumer* consumer, MessageCallBack pCallback); -ROCKETMQCLIENT_API int RegisterMessageCallback(CPushConsumer* consumer, MessageCallBack pCallback); +ROCKETMQCLIENT_API int RegisterMessageCallbackOrderly(CPushConsumer* consumer, MessageCallBack callback); +ROCKETMQCLIENT_API int RegisterMessageCallback(CPushConsumer* consumer, MessageCallBack callback); ROCKETMQCLIENT_API int UnregisterMessageCallbackOrderly(CPushConsumer* consumer); ROCKETMQCLIENT_API int UnregisterMessageCallback(CPushConsumer* consumer); ROCKETMQCLIENT_API int SetPushConsumerThreadCount(CPushConsumer* consumer, int threadCount); diff --git a/package_rocketmq.mri b/package_rocketmq.mri deleted file mode 100644 index fc5f6900e..000000000 --- a/package_rocketmq.mri +++ /dev/null @@ -1,22 +0,0 @@ -create librocketmq.a -addlib ../bin/lib/libboost_chrono.a -addlib ../bin/lib/libboost_date_time.a -addlib ../bin/lib/libboost_filesystem.a -addlib ../bin/lib/libboost_iostreams.a -addlib ../bin/lib/libboost_locale.a -addlib ../bin/lib/libboost_log.a -addlib ../bin/lib/libboost_log_setup.a -addlib ../bin/lib/libboost_regex.a -addlib ../bin/lib/libboost_serialization.a -addlib ../bin/lib/libboost_system.a -addlib ../bin/lib/libboost_thread.a -addlib ../bin/lib/libboost_wserialization.a -addlib ../bin/lib/libevent.a -addlib ../bin/lib/libevent_core.a -addlib ../bin/lib/libevent_extra.a -addlib ../bin/lib/libevent_pthreads.a -addlib ../bin/lib/libjsoncpp.a -addlib ../bin/lib/libSignature.a -addlib ../bin/librocketmq.a -save -end diff --git a/project/CMakeLists.txt b/project/CMakeLists.txt index 074d55fde..c65d319c2 100755 --- a/project/CMakeLists.txt +++ b/project/CMakeLists.txt @@ -13,23 +13,24 @@ # See the License for the specific language governing permissions and # limitations under the License. -# source files project(rocketmq-client) +option(BUILD_ROCKETMQ_STATIC "build rocketmq-client static library" OFF) +option(BUILD_ROCKETMQ_SHARED "build rocketmq-client shared library" ON) + +# source files file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/../src/*.c*) list(REMOVE_ITEM SRC_FILES ${PROJECT_SOURCE_DIR}/../src/dllmain.cpp) # subdirs -SET(SUB_DIRS) +set(SUB_DIRS) file(GLOB children ${PROJECT_SOURCE_DIR}/../src/*) -FOREACH (child ${children}) - IF (IS_DIRECTORY ${child}) - LIST(APPEND SUB_DIRS ${child}) - ENDIF () -ENDFOREACH () -LIST(APPEND SUB_DIRS ${PROJECT_SOURCE_DIR}/../src) - -include_directories(${SUB_DIRS}) +foreach (child ${children}) + if (IS_DIRECTORY ${child}) + list(APPEND SUB_DIRS ${child}) + endif () +endforeach () +list(APPEND SUB_DIRS ${PROJECT_SOURCE_DIR}/../src) # libs_directories file(GLOB LIB_DIRS ${PROJECT_SOURCE_DIR}/../libs/*) @@ -45,7 +46,7 @@ if (BUILD_ROCKETMQ_STATIC) add_library(rocketmq_static STATIC ${SRC_FILES}) target_include_directories(rocketmq_static - PUBLIC ${PROJECT_SOURCE_DIR}/../include) + PUBLIC ${CMAKE_SOURCE_DIR}/include ${SUB_DIRS} ${JSONCPP_INCLUDE_DIRS} ${LIBEVENT_INCLUDE_DIRS}) if (spdlog_FOUND) target_link_libraries(rocketmq_static PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} ${LIBEVENT_LIBRARIES} spdlog::spdlog) @@ -65,7 +66,7 @@ if (BUILD_ROCKETMQ_SHARED) add_library(rocketmq_shared SHARED ${SRC_FILES}) target_include_directories(rocketmq_shared - PUBLIC ${PROJECT_SOURCE_DIR}/../include) + PUBLIC ${CMAKE_SOURCE_DIR}/include ${SUB_DIRS} ${JSONCPP_INCLUDE_DIRS} ${LIBEVENT_INCLUDE_DIRS}) if (spdlog_FOUND) target_link_libraries(rocketmq_shared PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} ${LIBEVENT_LIBRARIES} spdlog::spdlog) diff --git a/src/ClientRemotingProcessor.cpp b/src/ClientRemotingProcessor.cpp index a9989479b..4f8d8a410 100644 --- a/src/ClientRemotingProcessor.cpp +++ b/src/ClientRemotingProcessor.cpp @@ -16,27 +16,31 @@ */ #include "ClientRemotingProcessor.h" -#include "CommandHeader.h" #include "ConsumerRunningInfo.h" #include "MQDecoder.h" #include "MQProtos.h" +#include "MessageAccessor.h" +#include "MessageSysFlag.h" +#include "RequestFutureTable.h" +#include "SocketUtil.h" +#include "protocol/body/ResetOffsetBody.h" +#include "protocol/header/CommandHeader.h" +#include "protocol/header/ReplyMessageRequestHeader.h" namespace rocketmq { -ClientRemotingProcessor::ClientRemotingProcessor(MQClientInstance* mqClientFactory) - : m_mqClientFactory(mqClientFactory) {} +ClientRemotingProcessor::ClientRemotingProcessor(MQClientInstance* clientInstance) : m_clientInstance(clientInstance) {} ClientRemotingProcessor::~ClientRemotingProcessor() = default; -RemotingCommand* ClientRemotingProcessor::processRequest(const std::string& addr, RemotingCommand* request) { - LOG_DEBUG("request Command received:processRequest, addr:%s, code:%d", addr.data(), request->getCode()); +RemotingCommand* ClientRemotingProcessor::processRequest(TcpTransportPtr channel, RemotingCommand* request) { + const auto& addr = channel->getPeerAddrAndPort(); + LOG_DEBUG_NEW("processRequest, code:{}, addr:{}", request->getCode(), addr); switch (request->getCode()) { case CHECK_TRANSACTION_STATE: return checkTransactionState(addr, request); - break; case NOTIFY_CONSUMER_IDS_CHANGED: return notifyConsumerIdsChanged(request); - break; case RESET_CONSUMER_CLIENT_OFFSET: // oneWayRPC return resetOffset(request); case GET_CONSUMER_STATUS_FROM_CLIENT: @@ -44,23 +48,64 @@ RemotingCommand* ClientRemotingProcessor::processRequest(const std::string& addr break; case GET_CONSUMER_RUNNING_INFO: return getConsumerRunningInfo(addr, request); - break; case CONSUME_MESSAGE_DIRECTLY: // return consumeMessageDirectly( request); break; + case PUSH_REPLY_MESSAGE_TO_CLIENT: + return receiveReplyMessage(request); default: break; } return nullptr; } +RemotingCommand* ClientRemotingProcessor::checkTransactionState(const std::string& addr, RemotingCommand* request) { + auto* requestHeader = request->decodeCommandCustomHeader(); + assert(requestHeader != nullptr); + + auto requestBody = request->getBody(); + if (requestBody != nullptr && requestBody->getSize() > 0) { + MQMessageExtPtr2 messageExt = MQDecoder::decode(*requestBody); + if (messageExt != nullptr) { + const auto& transactionId = messageExt->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX); + if (!transactionId.empty()) { + messageExt->setTransactionId(transactionId); + } + const auto& group = messageExt->getProperty(MQMessageConst::PROPERTY_PRODUCER_GROUP); + if (!group.empty()) { + auto* producer = m_clientInstance->selectProducer(group); + if (producer != nullptr) { + producer->checkTransactionState(addr, messageExt, requestHeader); + } else { + LOG_DEBUG_NEW("checkTransactionState, pick producer by group[{}] failed", group); + } + } else { + LOG_WARN_NEW("checkTransactionState, pick producer group failed"); + } + } else { + LOG_WARN_NEW("checkTransactionState, decode message failed"); + } + } else { + LOG_ERROR_NEW("checkTransactionState, request body is empty, request header: {}", requestHeader->toString()); + } + + return nullptr; +} + +RemotingCommand* ClientRemotingProcessor::notifyConsumerIdsChanged(RemotingCommand* request) { + auto* requestHeader = request->decodeCommandCustomHeader(); + LOG_INFO_NEW("notifyConsumerIdsChanged, group:{}", requestHeader->getConsumerGroup()); + m_clientInstance->rebalanceImmediately(); + return nullptr; +} + RemotingCommand* ClientRemotingProcessor::resetOffset(RemotingCommand* request) { auto* responseHeader = request->decodeCommandCustomHeader(); auto requestBody = request->getBody(); if (requestBody != nullptr && requestBody->getSize() > 0) { std::unique_ptr body(ResetOffsetBody::Decode(*requestBody)); if (body != nullptr) { - m_mqClientFactory->resetOffset(responseHeader->getGroup(), responseHeader->getTopic(), body->getOffsetTable()); + m_clientInstance->resetOffset(responseHeader->getGroup(), responseHeader->getTopic(), body->getOffsetTable()); } else { LOG_ERROR("resetOffset failed as received data could not be unserialized"); } @@ -68,91 +113,97 @@ RemotingCommand* ClientRemotingProcessor::resetOffset(RemotingCommand* request) return nullptr; // as resetOffset is oneWayRPC, do not need return any response } -ResetOffsetBody* ResetOffsetBody::Decode(MemoryBlock& mem) { - Json::Value root = RemotingSerializable::fromJson(mem); - Json::Value qds = root["offsetTable"]; - std::unique_ptr body(new ResetOffsetBody()); - for (unsigned int i = 0; i < qds.size(); i++) { - Json::Value qd = qds[i]; - MQMessageQueue mq(qd["brokerName"].asString(), qd["topic"].asString(), qd["queueId"].asInt()); - int64_t offset = qd["offset"].asInt64(); - body->setOffsetTable(mq, offset); - } - return body.release(); -} - -std::map ResetOffsetBody::getOffsetTable() { - return m_offsetTable; -} - -void ResetOffsetBody::setOffsetTable(const MQMessageQueue& mq, int64_t offset) { - m_offsetTable[mq] = offset; -} - RemotingCommand* ClientRemotingProcessor::getConsumerRunningInfo(const std::string& addr, RemotingCommand* request) { auto* requestHeader = request->decodeCommandCustomHeader(); - LOG_INFO("getConsumerRunningInfo:%s", requestHeader->getConsumerGroup().c_str()); + LOG_INFO("getConsumerRunningInfo, group:{}", requestHeader->getConsumerGroup()); - RemotingCommand* response = - new RemotingCommand(request->getCode(), "CPP", request->getVersion(), request->getOpaque(), request->getFlag(), - request->getRemark(), nullptr); + std::unique_ptr response( + new RemotingCommand(MQResponseCode::SYSTEM_ERROR, "not set any response code")); std::unique_ptr runningInfo( - m_mqClientFactory->consumerRunningInfo(requestHeader->getConsumerGroup())); + m_clientInstance->consumerRunningInfo(requestHeader->getConsumerGroup())); if (runningInfo != nullptr) { if (requestHeader->isJstackEnable()) { /*string jstack = UtilAll::jstack(); consumerRunningInfo->setJstack(jstack);*/ } - response->setCode(SUCCESS_VALUE); - std::string body = runningInfo->encode(); + response->setCode(SUCCESS); + auto body = runningInfo->encode(); response->setBody(body); } else { response->setCode(SYSTEM_ERROR); response->setRemark("The Consumer Group not exist in this consumer"); } - return response; + return response.release(); } -RemotingCommand* ClientRemotingProcessor::notifyConsumerIdsChanged(RemotingCommand* request) { - auto* requestHeader = request->decodeCommandCustomHeader(); - LOG_INFO("notifyConsumerIdsChanged:%s", requestHeader->getConsumerGroup().c_str()); - m_mqClientFactory->rebalanceImmediately(); - return nullptr; -} +RemotingCommand* ClientRemotingProcessor::receiveReplyMessage(RemotingCommand* request) { + std::unique_ptr response( + new RemotingCommand(MQResponseCode::SYSTEM_ERROR, "not set any response code")); -RemotingCommand* ClientRemotingProcessor::checkTransactionState(const std::string& addr, RemotingCommand* request) { - auto* requestHeader = request->decodeCommandCustomHeader(); - assert(requestHeader != nullptr); + auto receiveTime = UtilAll::currentTimeMillis(); + auto* requestHeader = request->decodeCommandCustomHeader(); - auto requestBody = request->getBody(); - if (requestBody != nullptr && requestBody->getSize() > 0) { - MQMessageExtPtr2 messageExt = MQDecoder::decode(*requestBody); - if (messageExt != nullptr) { - const auto& transactionId = messageExt->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX); - if (!transactionId.empty()) { - messageExt->setTransactionId(transactionId); - } - const auto& group = messageExt->getProperty(MQMessageConst::PROPERTY_PRODUCER_GROUP); - if (!group.empty()) { - auto* producer = m_mqClientFactory->selectProducer(group); - if (producer != nullptr) { - producer->checkTransactionState(addr, messageExt, requestHeader); - } else { - LOG_DEBUG_NEW("checkTransactionState, pick producer by group[{}] failed", group); - } + try { + std::unique_ptr msg(new MQMessageExt); + + msg->setTopic(requestHeader->getTopic()); + msg->setQueueId(requestHeader->getQueueId()); + msg->setStoreTimestamp(requestHeader->getStoreTimestamp()); + + if (!requestHeader->getBornHost().empty()) { + msg->setBornHost(string2SocketAddress(requestHeader->getBornHost())); + } + + if (!requestHeader->getStoreHost().empty()) { + msg->setStoreHost(string2SocketAddress(requestHeader->getStoreHost())); + } + + auto body = request->getBody(); + if ((requestHeader->getSysFlag() & MessageSysFlag::CompressedFlag) == MessageSysFlag::CompressedFlag) { + std::string outbody; + if (UtilAll::inflate(body->getData(), body->getSize(), outbody)) { + msg->setBody(std::move(outbody)); } else { - LOG_WARN_NEW("checkTransactionState, pick producer group failed"); + LOG_WARN_NEW("err when uncompress constant"); } } else { - LOG_WARN_NEW("checkTransactionState, decode message failed"); + msg->setBody(body->getData(), body->getSize()); } - } else { - LOG_ERROR_NEW("checkTransactionState, request body is empty, request header: {}", requestHeader->toString()); + + msg->setFlag(requestHeader->getFlag()); + MessageAccessor::setProperties(*msg, MQDecoder::string2messageProperties(requestHeader->getProperties())); + MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_REPLY_MESSAGE_ARRIVE_TIME, + UtilAll::to_string(receiveTime)); + msg->setBornTimestamp(requestHeader->getBornTimestamp()); + msg->setReconsumeTimes(requestHeader->getReconsumeTimes()); + LOG_DEBUG_NEW("receive reply message:{}", msg->toString()); + + processReplyMessage(std::move(msg)); + + response->setCode(MQResponseCode::SUCCESS); + response->setRemark(null); + } catch (const std::exception& e) { + LOG_WARN_NEW("unknown err when receiveReplyMsg, {}", e.what()); + response->setCode(MQResponseCode::SYSTEM_ERROR); + response->setRemark("process reply message fail"); } - return nullptr; + return response.release(); +} + +void ClientRemotingProcessor::processReplyMessage(std::unique_ptr replyMsg) { + const auto& correlationId = replyMsg->getProperty(MQMessageConst::PROPERTY_CORRELATION_ID); + auto requestResponseFuture = RequestFutureTable::removeRequestFuture(correlationId); + if (requestResponseFuture != nullptr) { + requestResponseFuture->putResponseMessage(std::move(replyMsg)); + requestResponseFuture->executeRequestCallback(); + } else { + auto bornHost = replyMsg->getBornHostString(); + LOG_WARN_NEW("receive reply message, but not matched any request, CorrelationId: {} , reply from host: {}", + correlationId, bornHost); + } } } // namespace rocketmq diff --git a/src/ClientRemotingProcessor.h b/src/ClientRemotingProcessor.h index efcb5fc95..e758cbcd8 100644 --- a/src/ClientRemotingProcessor.h +++ b/src/ClientRemotingProcessor.h @@ -25,29 +25,22 @@ namespace rocketmq { class ClientRemotingProcessor : public RequestProcessor { public: - ClientRemotingProcessor(MQClientInstance* mqClientFactory); + ClientRemotingProcessor(MQClientInstance* clientInstance); virtual ~ClientRemotingProcessor(); - RemotingCommand* processRequest(const std::string& addr, RemotingCommand* request) override; + RemotingCommand* processRequest(TcpTransportPtr channel, RemotingCommand* request) override; + RemotingCommand* checkTransactionState(const std::string& addr, RemotingCommand* request); + RemotingCommand* notifyConsumerIdsChanged(RemotingCommand* request); RemotingCommand* resetOffset(RemotingCommand* request); RemotingCommand* getConsumerRunningInfo(const std::string& addr, RemotingCommand* request); - RemotingCommand* notifyConsumerIdsChanged(RemotingCommand* request); - RemotingCommand* checkTransactionState(const std::string& addr, RemotingCommand* request); + RemotingCommand* receiveReplyMessage(RemotingCommand* request); private: - MQClientInstance* m_mqClientFactory; -}; - -class ResetOffsetBody { - public: - static ResetOffsetBody* Decode(MemoryBlock& mem); - - std::map getOffsetTable(); - void setOffsetTable(const MQMessageQueue& mq, int64_t offset); + void processReplyMessage(std::unique_ptr replyMsg); private: - std::map m_offsetTable; + MQClientInstance* m_clientInstance; }; } // namespace rocketmq diff --git a/src/MQAdminImpl.cpp b/src/MQAdminImpl.cpp index ea0651f43..be67fce31 100644 --- a/src/MQAdminImpl.cpp +++ b/src/MQAdminImpl.cpp @@ -27,9 +27,9 @@ void MQAdminImpl::createTopic(const std::string& key, const std::string& newTopi void MQAdminImpl::fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) { try { TopicRouteDataPtr topicRouteData( - m_mqClientFactory->getMQClientAPIImpl()->getTopicRouteInfoFromNameServer(topic, 1000 * 3)); + m_clientInstance->getMQClientAPIImpl()->getTopicRouteInfoFromNameServer(topic, 1000 * 3)); if (topicRouteData != nullptr) { - mqs = m_mqClientFactory->topicRouteData2TopicSubscribeInfo(topic, topicRouteData); + mqs = m_clientInstance->topicRouteData2TopicSubscribeInfo(topic, topicRouteData); if (!mqs.empty()) { return; } else { @@ -45,16 +45,16 @@ void MQAdminImpl::fetchSubscribeMessageQueues(const std::string& topic, std::vec } int64_t MQAdminImpl::searchOffset(const MQMessageQueue& mq, int64_t timestamp) { - std::string brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName()); + std::string brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); if (brokerAddr.empty()) { - m_mqClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic()); - brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName()); + m_clientInstance->updateTopicRouteInfoFromNameServer(mq.getTopic()); + brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); } if (!brokerAddr.empty()) { try { - return m_mqClientFactory->getMQClientAPIImpl()->searchOffset(brokerAddr, mq.getTopic(), mq.getQueueId(), - timestamp, 1000 * 3); + return m_clientInstance->getMQClientAPIImpl()->searchOffset(brokerAddr, mq.getTopic(), mq.getQueueId(), timestamp, + 1000 * 3); } catch (MQException& e) { THROW_MQEXCEPTION(MQClientException, "Invoke Broker exception", -1); } @@ -63,16 +63,15 @@ int64_t MQAdminImpl::searchOffset(const MQMessageQueue& mq, int64_t timestamp) { } int64_t MQAdminImpl::maxOffset(const MQMessageQueue& mq) { - std::string brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName()); + std::string brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); if (brokerAddr.empty()) { - m_mqClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic()); - brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName()); + m_clientInstance->updateTopicRouteInfoFromNameServer(mq.getTopic()); + brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); } if (!brokerAddr.empty()) { try { - return m_mqClientFactory->getMQClientAPIImpl()->getMaxOffset(brokerAddr, mq.getTopic(), mq.getQueueId(), - 1000 * 3); + return m_clientInstance->getMQClientAPIImpl()->getMaxOffset(brokerAddr, mq.getTopic(), mq.getQueueId(), 1000 * 3); } catch (MQException& e) { THROW_MQEXCEPTION(MQClientException, "Invoke Broker exception", -1); } @@ -81,16 +80,15 @@ int64_t MQAdminImpl::maxOffset(const MQMessageQueue& mq) { } int64_t MQAdminImpl::minOffset(const MQMessageQueue& mq) { - std::string brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName()); + std::string brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); if (brokerAddr.empty()) { - m_mqClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic()); - brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName()); + m_clientInstance->updateTopicRouteInfoFromNameServer(mq.getTopic()); + brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); } if (!brokerAddr.empty()) { try { - return m_mqClientFactory->getMQClientAPIImpl()->getMinOffset(brokerAddr, mq.getTopic(), mq.getQueueId(), - 1000 * 3); + return m_clientInstance->getMQClientAPIImpl()->getMinOffset(brokerAddr, mq.getTopic(), mq.getQueueId(), 1000 * 3); } catch (const std::exception& e) { THROW_MQEXCEPTION(MQClientException, "Invoke Broker[" + brokerAddr + "] exception", -1); } @@ -100,16 +98,16 @@ int64_t MQAdminImpl::minOffset(const MQMessageQueue& mq) { } int64_t MQAdminImpl::earliestMsgStoreTime(const MQMessageQueue& mq) { - std::string brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName()); + std::string brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); if (brokerAddr.empty()) { - m_mqClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic()); - brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName()); + m_clientInstance->updateTopicRouteInfoFromNameServer(mq.getTopic()); + brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); } if (!brokerAddr.empty()) { try { - return m_mqClientFactory->getMQClientAPIImpl()->getEarliestMsgStoretime(brokerAddr, mq.getTopic(), - mq.getQueueId(), 1000 * 3); + return m_clientInstance->getMQClientAPIImpl()->getEarliestMsgStoretime(brokerAddr, mq.getTopic(), mq.getQueueId(), + 1000 * 3); } catch (MQException& e) { THROW_MQEXCEPTION(MQClientException, "Invoke Broker exception", -1); } diff --git a/src/MQAdminImpl.h b/src/MQAdminImpl.h index 244d9a356..ee3d18d05 100644 --- a/src/MQAdminImpl.h +++ b/src/MQAdminImpl.h @@ -29,7 +29,7 @@ namespace rocketmq { class MQAdminImpl { public: - MQAdminImpl(MQClientInstance* mqClientFactory) : m_mqClientFactory(mqClientFactory) {} + MQAdminImpl(MQClientInstance* clientInstance) : m_clientInstance(clientInstance) {} void createTopic(const std::string& key, const std::string& newTopic, int queueNum); @@ -38,13 +38,13 @@ class MQAdminImpl { int64_t searchOffset(const MQMessageQueue& mq, int64_t timestamp); int64_t maxOffset(const MQMessageQueue& mq); int64_t minOffset(const MQMessageQueue& mq); - int64_t earliestMsgStoreTime(const MQMessageQueue& mqClientFactory); + int64_t earliestMsgStoreTime(const MQMessageQueue& mq); MQMessageExtPtr viewMessage(const std::string& msgId); QueryResult queryMessage(const std::string& topic, const std::string& key, int maxNum, int64_t begin, int64_t end); private: - MQClientInstance* m_mqClientFactory; + MQClientInstance* m_clientInstance; }; } // namespace rocketmq diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index 22d937ae9..53da5865c 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -32,18 +32,19 @@ namespace rocketmq { MQClientAPIImpl::MQClientAPIImpl(ClientRemotingProcessor* clientRemotingProcessor, - std::shared_ptr rpcHook, - const MQClientConfig* clientConfig) - : m_remotingClient(new TcpRemotingClient(clientConfig->getTcpTransportWorkerThreadNum(), - clientConfig->getTcpTransportConnectTimeout(), - clientConfig->getTcpTransportTryLockTimeout())) { + RPCHookPtr rpcHook, + const MQClientConfig& clientConfig) + : m_remotingClient(new TcpRemotingClient(clientConfig.getTcpTransportWorkerThreadNum(), + clientConfig.getTcpTransportConnectTimeout(), + clientConfig.getTcpTransportTryLockTimeout())) { m_remotingClient->registerRPCHook(rpcHook); m_remotingClient->registerProcessor(CHECK_TRANSACTION_STATE, clientRemotingProcessor); + m_remotingClient->registerProcessor(NOTIFY_CONSUMER_IDS_CHANGED, clientRemotingProcessor); m_remotingClient->registerProcessor(RESET_CONSUMER_CLIENT_OFFSET, clientRemotingProcessor); m_remotingClient->registerProcessor(GET_CONSUMER_STATUS_FROM_CLIENT, clientRemotingProcessor); m_remotingClient->registerProcessor(GET_CONSUMER_RUNNING_INFO, clientRemotingProcessor); - m_remotingClient->registerProcessor(NOTIFY_CONSUMER_IDS_CHANGED, clientRemotingProcessor); m_remotingClient->registerProcessor(CONSUME_MESSAGE_DIRECTLY, clientRemotingProcessor); + m_remotingClient->registerProcessor(PUSH_REPLY_MESSAGE_TO_CLIENT, clientRemotingProcessor); } MQClientAPIImpl::~MQClientAPIImpl() = default; @@ -57,13 +58,11 @@ void MQClientAPIImpl::shutdown() { } void MQClientAPIImpl::updateNameServerAddr(const std::string& addrs) { - if (m_remotingClient != nullptr) { - m_remotingClient->updateNameServerAddressList(addrs); - } + m_remotingClient->updateNameServerAddressList(addrs); } void MQClientAPIImpl::createTopic(const std::string& addr, const std::string& defaultTopic, TopicConfig topicConfig) { - CreateTopicRequestHeader* requestHeader = new CreateTopicRequestHeader(); + auto* requestHeader = new CreateTopicRequestHeader(); requestHeader->topic = topicConfig.getTopicName(); requestHeader->defaultTopic = defaultTopic; requestHeader->readQueueNums = topicConfig.getReadQueueNums(); @@ -76,7 +75,7 @@ void MQClientAPIImpl::createTopic(const std::string& addr, const std::string& de std::unique_ptr response(m_remotingClient->invokeSync(addr, request)); assert(response != nullptr); switch (response->getCode()) { - case SUCCESS_VALUE: { + case SUCCESS: { return; } default: @@ -111,8 +110,17 @@ SendResult* MQClientAPIImpl::sendMessage(const std::string& addr, int code = SEND_MESSAGE; std::unique_ptr header; - if (msg->isBatch()) { + const auto& msgType = msg->getProperty(MQMessageConst::PROPERTY_MESSAGE_TYPE); + bool isReply = msgType == REPLY_MESSAGE_FLAG; + if (isReply) { + code = SEND_REPLY_MESSAGE_V2; + } else if (msg->isBatch()) { code = SEND_BATCH_MESSAGE; + } else { + code = SEND_MESSAGE_V2; + } + + if (code != SEND_MESSAGE && code != SEND_REPLY_MESSAGE) { header.reset(SendMessageRequestHeaderV2::createSendMessageRequestHeaderV2(requestHeader.get())); } else { header = std::move(requestHeader); @@ -150,8 +158,8 @@ void MQClientAPIImpl::sendMessageAsync(const std::string& addr, int retryTimesWhenSendFailed, DefaultMQProducerImplPtr producer) throw(RemotingException) { // delete in future - auto cbw = new SendCallbackWrap(addr, brokerName, msg, std::forward(request), sendCallback, - topicPublishInfo, instance, retryTimesWhenSendFailed, 0, producer); + auto* cbw = new SendCallbackWrap(addr, brokerName, msg, std::forward(request), sendCallback, + topicPublishInfo, instance, retryTimesWhenSendFailed, 0, producer); try { sendMessageAsyncImpl(cbw, timeoutMillis); @@ -192,7 +200,7 @@ SendResult* MQClientAPIImpl::processSendResponse(const std::string& brokerName, case SLAVE_NOT_AVAILABLE: sendStatus = SEND_SLAVE_NOT_AVAILABLE; break; - case SUCCESS_VALUE: + case SUCCESS: sendStatus = SEND_OK; break; default: @@ -212,9 +220,11 @@ SendResult* MQClientAPIImpl::processSendResponse(const std::string& brokerName, const auto& messages = static_cast(msg)->getMessages(); uniqMsgId.clear(); uniqMsgId.reserve(33 * messages.size()); + bool isFirst = true; for (const auto& message : messages) { - if (!uniqMsgId.empty()) { + if (!isFirst) { uniqMsgId.append(","); + isFirst = false; } uniqMsgId.append(MessageClientIDSetter::getUniqID(*message)); } @@ -270,14 +280,18 @@ PullResult* MQClientAPIImpl::pullMessageSync(const std::string& addr, RemotingCo PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* response) { PullStatus pullStatus = NO_NEW_MSG; switch (response->getCode()) { - case SUCCESS_VALUE: + case SUCCESS: pullStatus = FOUND; break; case PULL_NOT_FOUND: pullStatus = NO_NEW_MSG; break; case PULL_RETRY_IMMEDIATELY: - pullStatus = NO_MATCHED_MSG; + if ("OFFSET_OVERFLOW_BADLY" == response->getRemark()) { + pullStatus = NO_LATEST_MSG; + } else { + pullStatus = NO_MATCHED_MSG; + } break; case PULL_OFFSET_MOVED: pullStatus = OFFSET_ILLEGAL; @@ -295,7 +309,7 @@ PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* response) { } MQMessageExtPtr MQClientAPIImpl::viewMessage(const std::string& addr, int64_t phyoffset, int timeoutMillis) { - ViewMessageRequestHeader* requestHeader = new ViewMessageRequestHeader(); + auto* requestHeader = new ViewMessageRequestHeader(); requestHeader->offset = phyoffset; RemotingCommand request(VIEW_MESSAGE_BY_ID, requestHeader); @@ -303,7 +317,7 @@ MQMessageExtPtr MQClientAPIImpl::viewMessage(const std::string& addr, int64_t ph std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->getCode()) { - case SUCCESS_VALUE: { + case SUCCESS: { // TODO: ... } default: @@ -318,7 +332,7 @@ int64_t MQClientAPIImpl::searchOffset(const std::string& addr, int queueId, uint64_t timestamp, int timeoutMillis) { - SearchOffsetRequestHeader* requestHeader = new SearchOffsetRequestHeader(); + auto* requestHeader = new SearchOffsetRequestHeader(); requestHeader->topic = topic; requestHeader->queueId = queueId; requestHeader->timestamp = timestamp; @@ -328,7 +342,7 @@ int64_t MQClientAPIImpl::searchOffset(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->getCode()) { - case SUCCESS_VALUE: { + case SUCCESS: { auto* responseHeader = response->decodeCommandCustomHeader(); assert(responseHeader != nullptr); return responseHeader->offset; @@ -344,7 +358,7 @@ int64_t MQClientAPIImpl::getMaxOffset(const std::string& addr, const std::string& topic, int queueId, int timeoutMillis) { - GetMaxOffsetRequestHeader* requestHeader = new GetMaxOffsetRequestHeader(); + auto* requestHeader = new GetMaxOffsetRequestHeader(); requestHeader->topic = topic; requestHeader->queueId = queueId; @@ -353,7 +367,7 @@ int64_t MQClientAPIImpl::getMaxOffset(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->getCode()) { - case SUCCESS_VALUE: { + case SUCCESS: { auto* responseHeader = response->decodeCommandCustomHeader(GET_MAX_OFFSET); return responseHeader->offset; } @@ -368,7 +382,7 @@ int64_t MQClientAPIImpl::getMinOffset(const std::string& addr, const std::string& topic, int queueId, int timeoutMillis) { - GetMinOffsetRequestHeader* requestHeader = new GetMinOffsetRequestHeader(); + auto* requestHeader = new GetMinOffsetRequestHeader(); requestHeader->topic = topic; requestHeader->queueId = queueId; @@ -377,7 +391,7 @@ int64_t MQClientAPIImpl::getMinOffset(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->getCode()) { - case SUCCESS_VALUE: { + case SUCCESS: { auto* responseHeader = response->decodeCommandCustomHeader(); assert(responseHeader != nullptr); return responseHeader->offset; @@ -393,7 +407,7 @@ int64_t MQClientAPIImpl::getEarliestMsgStoretime(const std::string& addr, const std::string& topic, int queueId, int timeoutMillis) { - GetEarliestMsgStoretimeRequestHeader* requestHeader = new GetEarliestMsgStoretimeRequestHeader(); + auto* requestHeader = new GetEarliestMsgStoretimeRequestHeader(); requestHeader->topic = topic; requestHeader->queueId = queueId; @@ -402,7 +416,7 @@ int64_t MQClientAPIImpl::getEarliestMsgStoretime(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->getCode()) { - case SUCCESS_VALUE: { + case SUCCESS: { auto* responseHeader = response->decodeCommandCustomHeader(); assert(responseHeader != nullptr); return responseHeader->timestamp; @@ -418,7 +432,7 @@ void MQClientAPIImpl::getConsumerIdListByGroup(const std::string& addr, const std::string& consumerGroup, std::vector& cids, int timeoutMillis) { - GetConsumerListByGroupRequestHeader* requestHeader = new GetConsumerListByGroupRequestHeader(); + auto* requestHeader = new GetConsumerListByGroupRequestHeader(); requestHeader->consumerGroup = consumerGroup; RemotingCommand request(GET_CONSUMER_LIST_BY_GROUP, requestHeader); @@ -426,15 +440,17 @@ void MQClientAPIImpl::getConsumerIdListByGroup(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->getCode()) { - case SUCCESS_VALUE: { + case SUCCESS: { auto responseBody = response->getBody(); if (responseBody != nullptr && responseBody->getSize() > 0) { std::unique_ptr body( GetConsumerListByGroupResponseBody::Decode(*responseBody)); - cids = body->consumerIdList; + cids = std::move(body->consumerIdList); return; } } + case SYSTEM_ERROR: + // no consumer for this group default: break; } @@ -450,7 +466,7 @@ int64_t MQClientAPIImpl::queryConsumerOffset(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->getCode()) { - case SUCCESS_VALUE: { + case SUCCESS: { auto* responseHeader = response->decodeCommandCustomHeader(); assert(responseHeader != nullptr); return responseHeader->offset; @@ -470,7 +486,7 @@ void MQClientAPIImpl::updateConsumerOffset(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->getCode()) { - case SUCCESS_VALUE: { + case SUCCESS: { return; } default: @@ -488,15 +504,15 @@ void MQClientAPIImpl::updateConsumerOffsetOneway(const std::string& addr, m_remotingClient->invokeOneway(addr, request); } -void MQClientAPIImpl::sendHearbeat(const std::string& addr, HeartbeatData* heartbeatData) { +void MQClientAPIImpl::sendHearbeat(const std::string& addr, HeartbeatData* heartbeatData, long timeoutMillis) { RemotingCommand request(HEART_BEAT, nullptr); request.setBody(heartbeatData->encode()); - std::unique_ptr response(m_remotingClient->invokeSync(addr, request)); + std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->getCode()) { - case SUCCESS_VALUE: { - LOG_INFO("sendheartbeat to broker:%s success", addr.c_str()); + case SUCCESS: { + LOG_DEBUG_NEW("sendHeartbeat to broker:{} success", addr); return; } default: @@ -516,7 +532,7 @@ void MQClientAPIImpl::unregisterClient(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request)); assert(response != nullptr); switch (response->getCode()) { - case SUCCESS_VALUE: + case SUCCESS: LOG_INFO("unregisterClient to:%s success", addr.c_str()); return; default: @@ -542,7 +558,7 @@ void MQClientAPIImpl::consumerSendMessageBack(const std::string& addr, int delayLevel, int timeoutMillis, int maxConsumeRetryTimes) { - ConsumerSendMsgBackRequestHeader* requestHeader = new ConsumerSendMsgBackRequestHeader(); + auto* requestHeader = new ConsumerSendMsgBackRequestHeader(); requestHeader->group = consumerGroup; requestHeader->originTopic = msg.getTopic(); requestHeader->offset = msg.getCommitLogOffset(); @@ -555,7 +571,7 @@ void MQClientAPIImpl::consumerSendMessageBack(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->getCode()) { - case SUCCESS_VALUE: { + case SUCCESS: { return; } default: @@ -575,7 +591,7 @@ void MQClientAPIImpl::lockBatchMQ(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->getCode()) { - case SUCCESS_VALUE: { + case SUCCESS: { auto requestBody = response->getBody(); if (requestBody != nullptr && requestBody->getSize() > 0) { std::unique_ptr body(LockBatchResponseBody::Decode(*requestBody)); @@ -605,7 +621,7 @@ void MQClientAPIImpl::unlockBatchMQ(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->getCode()) { - case SUCCESS_VALUE: { + case SUCCESS: { return; } break; default: @@ -625,7 +641,7 @@ TopicRouteData* MQClientAPIImpl::getTopicRouteInfoFromNameServer(const std::stri case TOPIC_NOT_EXIST: { break; } - case SUCCESS_VALUE: { + case SUCCESS: { auto responseBody = response->getBody(); if (responseBody != nullptr && responseBody->getSize() > 0) { return TopicRouteData::Decode(*responseBody); @@ -644,7 +660,7 @@ TopicList* MQClientAPIImpl::getTopicListFromNameServer() { std::unique_ptr response(m_remotingClient->invokeSync(null, request)); assert(response != nullptr); switch (response->getCode()) { - case SUCCESS_VALUE: { + case SUCCESS: { auto responseBody = response->getBody(); if (responseBody != nullptr && responseBody->getSize() > 0) { return TopicList::Decode(*responseBody); diff --git a/src/MQClientAPIImpl.h b/src/MQClientAPIImpl.h index 0b3844798..b2f94fa7a 100644 --- a/src/MQClientAPIImpl.h +++ b/src/MQClientAPIImpl.h @@ -17,12 +17,10 @@ #ifndef __MQ_CLIENT_API_IMPL_H__ #define __MQ_CLIENT_API_IMPL_H__ -#include "CommandHeader.h" #include "CommunicationMode.h" #include "DefaultMQProducerImpl.h" #include "HeartbeatData.h" #include "KVTable.h" -#include "LockBatchBody.h" #include "MQClientException.h" #include "MQClientInstance.h" #include "MQMessageExt.h" @@ -33,6 +31,8 @@ #include "TopicList.h" #include "TopicPublishInfo.h" #include "TopicRouteData.h" +#include "protocol/body/LockBatchBody.h" +#include "protocol/header/CommandHeader.h" namespace rocketmq { @@ -47,8 +47,8 @@ class SendCallbackWrap; class MQClientAPIImpl { public: MQClientAPIImpl(ClientRemotingProcessor* clientRemotingProcessor, - std::shared_ptr rpcHook, - const MQClientConfig* clientConfig); + RPCHookPtr rpcHook, + const MQClientConfig& clientConfig); virtual ~MQClientAPIImpl(); void start(); @@ -79,7 +79,7 @@ class MQClientAPIImpl { SendResult* processSendResponse(const std::string& brokerName, const MQMessagePtr msg, RemotingCommand* pResponse); PullResult* pullMessage(const std::string& addr, - PullMessageRequestHeader* pRequestHeader, + PullMessageRequestHeader* requestHeader, int timeoutMillis, CommunicationMode communicationMode, PullCallback* pullCallback); @@ -104,17 +104,17 @@ class MQClientAPIImpl { int timeoutMillis); int64_t queryConsumerOffset(const std::string& addr, - QueryConsumerOffsetRequestHeader* pRequestHeader, + QueryConsumerOffsetRequestHeader* requestHeader, int timeoutMillis); void updateConsumerOffset(const std::string& addr, - UpdateConsumerOffsetRequestHeader* pRequestHeader, + UpdateConsumerOffsetRequestHeader* requestHeader, int timeoutMillis); void updateConsumerOffsetOneway(const std::string& addr, - UpdateConsumerOffsetRequestHeader* pRequestHeader, + UpdateConsumerOffsetRequestHeader* requestHeader, int timeoutMillis); - void sendHearbeat(const std::string& addr, HeartbeatData* pHeartbeatData); + void sendHearbeat(const std::string& addr, HeartbeatData* heartbeatData, long timeoutMillis); void unregisterClient(const std::string& addr, const std::string& clientID, const std::string& producerGroup, @@ -192,7 +192,6 @@ class MQClientAPIImpl { private: std::unique_ptr m_remotingClient; - std::string m_nameSrvAddr; }; } // namespace rocketmq diff --git a/src/MQClientConfig.cpp b/src/MQClientConfigImpl.cpp similarity index 65% rename from src/MQClientConfig.cpp rename to src/MQClientConfigImpl.cpp index 7495d0351..b8a24f810 100644 --- a/src/MQClientConfig.cpp +++ b/src/MQClientConfigImpl.cpp @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "MQClientConfig.h" +#include "MQClientConfigImpl.h" #include #include @@ -26,7 +26,7 @@ namespace rocketmq { static const std::string DEFAULT_INSTANCE_NAME = "DEFAULT"; -MQClientConfig::MQClientConfig() +MQClientConfigImpl::MQClientConfigImpl() : m_instanceName(DEFAULT_INSTANCE_NAME), m_tcpWorkerThreadNum(std::min(4, (int)std::thread::hardware_concurrency())), m_tcpConnectTimeout(3000), @@ -37,11 +37,11 @@ MQClientConfig::MQClientConfig() } } -std::string MQClientConfig::buildMQClientId() const { +std::string MQClientConfigImpl::buildMQClientId() const { std::string clientId; clientId.append(UtilAll::getLocalAddress()); // clientIP clientId.append("@"); - clientId.append(m_instanceName); // processId + clientId.append(m_instanceName); // instanceName if (!m_unitName.empty()) { clientId.append("@"); clientId.append(m_unitName); // unitName @@ -49,68 +49,68 @@ std::string MQClientConfig::buildMQClientId() const { return clientId; } -const std::string& MQClientConfig::getGroupName() const { +const std::string& MQClientConfigImpl::getGroupName() const { return m_groupName; } -void MQClientConfig::setGroupName(const std::string& groupname) { +void MQClientConfigImpl::setGroupName(const std::string& groupname) { m_groupName = groupname; } -const std::string& MQClientConfig::getNamesrvAddr() const { +const std::string& MQClientConfigImpl::getNamesrvAddr() const { return m_namesrvAddr; } -void MQClientConfig::setNamesrvAddr(const std::string& namesrvAddr) { +void MQClientConfigImpl::setNamesrvAddr(const std::string& namesrvAddr) { m_namesrvAddr = NameSpaceUtil::formatNameServerURL(namesrvAddr); } -const std::string& MQClientConfig::getInstanceName() const { +const std::string& MQClientConfigImpl::getInstanceName() const { return m_instanceName; } -void MQClientConfig::setInstanceName(const std::string& instanceName) { +void MQClientConfigImpl::setInstanceName(const std::string& instanceName) { m_instanceName = instanceName; } -void MQClientConfig::changeInstanceNameToPID() { +void MQClientConfigImpl::changeInstanceNameToPID() { if (m_instanceName == DEFAULT_INSTANCE_NAME) { m_instanceName = UtilAll::to_string(UtilAll::getProcessId()); } } -int MQClientConfig::getTcpTransportWorkerThreadNum() const { +const std::string& MQClientConfigImpl::getUnitName() const { + return m_unitName; +} + +void MQClientConfigImpl::setUnitName(std::string unitName) { + m_unitName = unitName; +} + +int MQClientConfigImpl::getTcpTransportWorkerThreadNum() const { return m_tcpWorkerThreadNum; } -void MQClientConfig::setTcpTransportWorkerThreadNum(int num) { +void MQClientConfigImpl::setTcpTransportWorkerThreadNum(int num) { if (num > m_tcpWorkerThreadNum) { m_tcpWorkerThreadNum = num; } } -uint64_t MQClientConfig::getTcpTransportConnectTimeout() const { +uint64_t MQClientConfigImpl::getTcpTransportConnectTimeout() const { return m_tcpConnectTimeout; } -void MQClientConfig::setTcpTransportConnectTimeout(uint64_t timeout) { +void MQClientConfigImpl::setTcpTransportConnectTimeout(uint64_t timeout) { m_tcpConnectTimeout = timeout; } -uint64_t MQClientConfig::getTcpTransportTryLockTimeout() const { +uint64_t MQClientConfigImpl::getTcpTransportTryLockTimeout() const { return m_tcpTransportTryLockTimeout; } -void MQClientConfig::setTcpTransportTryLockTimeout(uint64_t timeout) { +void MQClientConfigImpl::setTcpTransportTryLockTimeout(uint64_t timeout) { m_tcpTransportTryLockTimeout = std::max(1000, timeout) / 1000; } -const std::string& MQClientConfig::getUnitName() const { - return m_unitName; -} - -void MQClientConfig::setUnitName(std::string unitName) { - m_unitName = unitName; -} - } // namespace rocketmq diff --git a/src/MQClientConfigImpl.h b/src/MQClientConfigImpl.h new file mode 100644 index 000000000..a4e522c9b --- /dev/null +++ b/src/MQClientConfigImpl.h @@ -0,0 +1,70 @@ +/* + * 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_CONFIG_IMPL_H__ +#define __MQ_CLIENT_CONFIG_IMPL_H__ + +#include "MQClientConfig.h" + +namespace rocketmq { + +/** + * MQ Client Config + */ +class MQClientConfigImpl : virtual public MQClientConfig { + public: + MQClientConfigImpl(); + virtual ~MQClientConfigImpl() = default; + + std::string buildMQClientId() const override; + + const std::string& getGroupName() const override; + void setGroupName(const std::string& groupname) override; + + const std::string& getNamesrvAddr() const override; + void setNamesrvAddr(const std::string& namesrvAddr) override; + + const std::string& getInstanceName() const override; + void setInstanceName(const std::string& instanceName) override; + + void changeInstanceNameToPID() override; + + const std::string& getUnitName() const override; + void setUnitName(std::string unitName) override; + + int getTcpTransportWorkerThreadNum() const override; + void setTcpTransportWorkerThreadNum(int num) override; + + uint64_t getTcpTransportConnectTimeout() const override; + void setTcpTransportConnectTimeout(uint64_t timeout) override; // ms + + uint64_t getTcpTransportTryLockTimeout() const override; + void setTcpTransportTryLockTimeout(uint64_t timeout) override; // ms + + protected: + std::string m_namesrvAddr; + std::string m_instanceName; + std::string m_groupName; + std::string m_unitName; + + int m_tcpWorkerThreadNum; + uint64_t m_tcpConnectTimeout; // ms + uint64_t m_tcpTransportTryLockTimeout; // s +}; + +} // namespace rocketmq + +#endif // __MQ_CLIENT_CONFIG_H__ diff --git a/src/MQClientImpl.cpp b/src/MQClientImpl.cpp index fac8659a3..58376b54d 100644 --- a/src/MQClientImpl.cpp +++ b/src/MQClientImpl.cpp @@ -24,19 +24,23 @@ namespace rocketmq { -#define ROCKETMQCPP_VERSION "1.0.1" -#define BUILD_DATE "03-14-2018" +#define ROCKETMQCPP_VERSION "3.0.0" +#define BUILD_DATE __DATE__ " " __TIME__ // display version: strings bin/librocketmq.so |grep VERSION const char* rocketmq_build_time = "VERSION: " ROCKETMQCPP_VERSION ", BUILD DATE: " BUILD_DATE; void MQClientImpl::start() { - if (m_clientInstance == nullptr) { - m_clientInstance = MQClientManager::getInstance()->getOrCreateMQClientInstance(m_clientConfig, m_rpcHook); + if (nullptr == m_clientInstance) { + if (nullptr == m_clientConfig) { + THROW_MQEXCEPTION(MQClientException, "have not clientConfig for create clientInstance.", -1); + } + + m_clientInstance = MQClientManager::getInstance()->getOrCreateMQClientInstance(*m_clientConfig, m_rpcHook); } - LOG_INFO_NEW("MQClientImpl start, nameserveraddr:{}, instanceName:{}, groupName:{}, clientId:{}", - m_clientConfig->getNamesrvAddr(), m_clientConfig->getInstanceName(), m_clientConfig->getGroupName(), - m_clientInstance->getClientId()); + + LOG_INFO_NEW("MQClientImpl start, clientId:{}, real nameservAddr:{}", m_clientInstance->getClientId(), + m_clientInstance->getNamesrvAddr()); } void MQClientImpl::shutdown() { @@ -79,12 +83,20 @@ QueryResult MQClientImpl::queryMessage(const std::string& topic, return m_clientInstance->getMQAdminImpl()->queryMessage(topic, key, maxNum, begin, end); } -MQClientInstancePtr MQClientImpl::getFactory() const { +bool MQClientImpl::isServiceStateOk() { + return m_serviceState == RUNNING; +} + +MQClientInstancePtr MQClientImpl::getClientInstance() const { return m_clientInstance; } -bool MQClientImpl::isServiceStateOk() { - return m_serviceState == RUNNING; +void MQClientImpl::setClientInstance(MQClientInstancePtr clientInstance) { + if (m_serviceState == CREATE_JUST) { + m_clientInstance = clientInstance; + } else { + THROW_MQEXCEPTION(MQClientException, "Client already start, can not reset clientInstance!", -1); + } } } // namespace rocketmq diff --git a/src/MQClientImpl.h b/src/MQClientImpl.h index f116407c8..3b689bdb5 100644 --- a/src/MQClientImpl.h +++ b/src/MQClientImpl.h @@ -24,9 +24,9 @@ namespace rocketmq { -class MQClientImpl : virtual public MQAdmin { +class MQClientImpl : public MQAdmin { public: - MQClientImpl(MQClientConfig* config, std::shared_ptr rpcHook) + MQClientImpl(MQClientConfigPtr config, RPCHookPtr rpcHook) : m_clientConfig(config), m_rpcHook(rpcHook), m_serviceState(CREATE_JUST), m_clientInstance(nullptr) {} public: // MQAdmin @@ -46,16 +46,18 @@ class MQClientImpl : virtual public MQAdmin { virtual void start(); virtual void shutdown(); - MQClientInstancePtr getFactory() const; virtual bool isServiceStateOk(); - std::shared_ptr getRPCHook() { return m_rpcHook; } - void setRPCHook(std::shared_ptr rpcHook) { m_rpcHook = rpcHook; } + MQClientInstancePtr getClientInstance() const; + void setClientInstance(MQClientInstancePtr clientInstance); + + RPCHookPtr getRPCHook() { return m_rpcHook; } + void setRPCHook(RPCHookPtr rpcHook) { m_rpcHook = rpcHook; } protected: - MQClientConfig* m_clientConfig; - std::shared_ptr m_rpcHook; - ServiceState m_serviceState; + MQClientConfigPtr m_clientConfig; + RPCHookPtr m_rpcHook; + volatile ServiceState m_serviceState; MQClientInstancePtr m_clientInstance; }; diff --git a/src/MQClientInstance.cpp b/src/MQClientInstance.cpp index fff4d6045..1ac65166b 100644 --- a/src/MQClientInstance.cpp +++ b/src/MQClientInstance.cpp @@ -26,7 +26,7 @@ #include "MQClientManager.h" #include "MQVersion.h" #include "PermName.h" -#include "PullMessageService.h" +#include "PullMessageService.hpp" #include "PullRequest.h" #include "RebalanceImpl.h" #include "RebalanceService.h" @@ -42,14 +42,11 @@ namespace rocketmq { static const long LOCK_TIMEOUT_MILLIS = 3000L; -MQClientInstance::MQClientInstance(MQClientConfig clientConfig, const std::string& clientId) +MQClientInstance::MQClientInstance(const MQClientConfig& clientConfig, const std::string& clientId) : MQClientInstance(clientConfig, clientId, nullptr) {} -MQClientInstance::MQClientInstance(MQClientConfig clientConfig, - const std::string& clientId, - std::shared_ptr rpcHook) - : m_clientConfig(clientConfig), - m_clientId(clientId), +MQClientInstance::MQClientInstance(const MQClientConfig& clientConfig, const std::string& clientId, RPCHookPtr rpcHook) + : m_clientId(clientId), m_rebalanceService(new RebalanceService(this)), m_pullMessageService(new PullMessageService(this)), m_scheduledExecutorService("MQClient", false) { @@ -58,9 +55,9 @@ MQClientInstance::MQClientInstance(MQClientConfig clientConfig, m_topicPublishInfoTable[AUTO_CREATE_TOPIC_KEY_TOPIC] = defaultTopicInfo; m_clientRemotingProcessor.reset(new ClientRemotingProcessor(this)); - m_mqClientAPIImpl.reset(new MQClientAPIImpl(m_clientRemotingProcessor.get(), rpcHook, &m_clientConfig)); + m_mqClientAPIImpl.reset(new MQClientAPIImpl(m_clientRemotingProcessor.get(), rpcHook, clientConfig)); - std::string namesrvAddr = m_clientConfig.getNamesrvAddr(); + std::string namesrvAddr = clientConfig.getNamesrvAddr(); if (!namesrvAddr.empty()) { m_mqClientAPIImpl->updateNameServerAddr(namesrvAddr); LOG_INFO_NEW("user specified name server address: {}", namesrvAddr); @@ -85,11 +82,22 @@ MQClientInstance::~MQClientInstance() { m_mqClientAPIImpl = nullptr; } +std::string MQClientInstance::getNamesrvAddr() const { + auto namesrvAddrs = m_mqClientAPIImpl->getRemotingClient()->getNameServerAddressList(); + std::ostringstream oss; + for (const auto& addr : namesrvAddrs) { + oss << addr << ";"; + } + return oss.str(); +} + TopicPublishInfoPtr MQClientInstance::topicRouteData2TopicPublishInfo(const std::string& topic, TopicRouteDataPtr route) { - TopicPublishInfoPtr info(new TopicPublishInfo()); + auto info = std::make_shared(); info->setTopicRouteData(route); + auto& mqList = const_cast(info->getMessageQueueList()); + std::string orderTopicConf = route->getOrderTopicConf(); if (!orderTopicConf.empty()) { // order msg // "broker-a:8";"broker-b:8" @@ -100,7 +108,7 @@ TopicPublishInfoPtr MQClientInstance::topicRouteData2TopicPublishInfo(const std: UtilAll::Split(item, broker, ':'); int nums = atoi(item[1].c_str()); for (int i = 0; i < nums; i++) { - info->getMessageQueueList().emplace_back(topic, item[0], i); + mqList.emplace_back(topic, item[0], i); } } info->setOrderTopic(true); @@ -127,20 +135,19 @@ TopicPublishInfoPtr MQClientInstance::topicRouteData2TopicPublishInfo(const std: } for (int i = 0; i < qd.writeQueueNums; i++) { - info->getMessageQueueList().emplace_back(topic, qd.brokerName, i); + mqList.emplace_back(topic, qd.brokerName, i); } } } // sort, make brokerName is staggered. - std::sort(info->getMessageQueueList().begin(), info->getMessageQueueList().end(), - [](const MQMessageQueue& a, const MQMessageQueue& b) { - auto result = a.getQueueId() - b.getQueueId(); - if (result == 0) { - result = a.getBrokerName().compare(b.getBrokerName()); - } - return result < 0; - }); + std::sort(mqList.begin(), mqList.end(), [](const MQMessageQueue& a, const MQMessageQueue& b) { + auto result = a.getQueueId() - b.getQueueId(); + if (result == 0) { + result = a.getBrokerName().compare(b.getBrokerName()); + } + return result < 0; + }); info->setOrderTopic(false); } @@ -166,7 +173,7 @@ std::vector MQClientInstance::topicRouteData2TopicSubscribeInfo( void MQClientInstance::start() { switch (m_serviceState) { case CREATE_JUST: - LOG_INFO_NEW("MQClientInstance:{} start", m_clientId); + LOG_INFO_NEW("the client instance [{}] is starting", m_clientId); m_serviceState = START_FAILED; m_mqClientAPIImpl->start(); @@ -180,13 +187,15 @@ void MQClientInstance::start() { // start rebalance service m_rebalanceService->start(); - LOG_INFO_NEW("the client factory [{}] start OK", m_clientId); + LOG_INFO_NEW("the client instance [{}] start OK", m_clientId); m_serviceState = RUNNING; break; case RUNNING: + LOG_INFO_NEW("the client instance [{}] already running.", m_clientId, m_serviceState); + break; case SHUTDOWN_ALREADY: case START_FAILED: - LOG_INFO_NEW("The Factory object:{} start failed with fault state:{}", m_clientId, m_serviceState); + LOG_INFO_NEW("the client instance [{}] start failed with fault state:{}", m_clientId, m_serviceState); break; default: break; @@ -194,11 +203,13 @@ void MQClientInstance::start() { } void MQClientInstance::shutdown() { - if (getConsumerTableSize() != 0) + if (getConsumerTableSize() != 0) { return; + } - if (getProducerTableSize() != 0) + if (getProducerTableSize() != 0) { return; + } switch (m_serviceState) { case CREATE_JUST: @@ -211,7 +222,7 @@ void MQClientInstance::shutdown() { m_rebalanceService->shutdown(); MQClientManager::getInstance()->removeMQClientInstance(m_clientId); - LOG_INFO_NEW("the client factory [{}] shutdown OK", m_clientId); + LOG_INFO_NEW("the client instance [{}] shutdown OK", m_clientId); } break; case SHUTDOWN_ALREADY: break; @@ -266,7 +277,7 @@ void MQClientInstance::persistAllConsumerOffsetPeriodically() { 1000 * 5, time_unit::milliseconds); } -std::string MQClientInstance::getClientId() { +const std::string& MQClientInstance::getClientId() const { return m_clientId; } @@ -291,6 +302,7 @@ void MQClientInstance::cleanOfflineBroker() { if (UtilAll::try_lock_for(m_lockNamesrv, LOCK_TIMEOUT_MILLIS)) { std::lock_guard lock(m_lockNamesrv, std::adopt_lock); + std::set offlineBrokers; BrokerAddrMAP updatedTable(getBrokerAddrTable()); for (auto itBrokerTable = updatedTable.begin(); itBrokerTable != updatedTable.end();) { const auto& brokerName = itBrokerTable->first; @@ -299,6 +311,7 @@ void MQClientInstance::cleanOfflineBroker() { for (auto it = cloneAddrTable.begin(); it != cloneAddrTable.end();) { const auto& addr = it->second; if (!isBrokerAddrExistInTopicRouteTable(addr)) { + offlineBrokers.insert(addr); it = cloneAddrTable.erase(it); LOG_INFO_NEW("the broker addr[{} {}] is offline, remove it", brokerName, addr); } else { @@ -314,7 +327,18 @@ void MQClientInstance::cleanOfflineBroker() { } } - resetBrokerAddrTable(std::move(updatedTable)); + if (offlineBrokers.size() > 0) { + resetBrokerAddrTable(std::move(updatedTable)); + + std::lock_guard lock(m_topicBrokerAddrTableMutex); + for (auto it = m_topicBrokerAddrTable.begin(); it != m_topicBrokerAddrTable.end();) { + if (offlineBrokers.find(it->second.first) != offlineBrokers.end()) { + it = m_topicBrokerAddrTable.erase(it); + } else { + it++; + } + } + } } else { LOG_WARN_NEW("lock namesrv, but failed."); } @@ -348,7 +372,7 @@ void MQClientInstance::sendHeartbeatToAllBrokerWithLock() { void MQClientInstance::persistAllConsumerOffset() { std::lock_guard lock(m_consumerTableMutex); for (const auto& it : m_consumerTable) { - LOG_DEBUG_NEW("Client factory start persistAllConsumerOffset"); + LOG_DEBUG_NEW("the client instance [{}] start persistAllConsumerOffset", m_clientId); it.second->persistConsumerOffset(); } } @@ -362,7 +386,7 @@ void MQClientInstance::sendHeartbeatToAllBroker() { return; } - BrokerAddrMAP brokerAddrTable(getBrokerAddrTable()); + auto brokerAddrTable = getBrokerAddrTable(); if (!brokerAddrTable.empty()) { for (const auto& it : brokerAddrTable) { // const auto& brokerName = it.first; @@ -375,8 +399,8 @@ void MQClientInstance::sendHeartbeatToAllBroker() { } try { - m_mqClientAPIImpl->sendHearbeat(addr, heartbeatData.get()); - } catch (MQException& e) { + m_mqClientAPIImpl->sendHearbeat(addr, heartbeatData.get(), 3000); + } catch (const MQException& e) { LOG_ERROR_NEW("{}", e.what()); } } @@ -426,7 +450,6 @@ bool MQClientInstance::updateTopicRouteInfoFromNameServer(const std::string& top // update publish info { TopicPublishInfoPtr publishInfo(topicRouteData2TopicPublishInfo(topic, topicRouteData)); - publishInfo->setHaveTopicRouterInfo(true); updateProducerTopicPublishInfo(topic, publishInfo); } @@ -507,11 +530,11 @@ bool MQClientInstance::topicRouteDataIsChange(TopicRouteData* olddata, TopicRout TopicRouteDataPtr MQClientInstance::getTopicRouteData(const std::string& topic) { std::lock_guard lock(m_topicRouteTableMutex); - auto iter = m_topicRouteTable.find(topic); - if (iter != m_topicRouteTable.end()) { - return iter->second; + const auto& it = m_topicRouteTable.find(topic); + if (it != m_topicRouteTable.end()) { + return it->second; } - return TopicRouteDataPtr(); + return nullptr; } void MQClientInstance::addTopicRouteData(const std::string& topic, TopicRouteDataPtr topicRouteData) { @@ -595,22 +618,23 @@ void MQClientInstance::rebalanceImmediately() { } void MQClientInstance::doRebalance() { - LOG_INFO_NEW("Client factory:{} start dorebalance", m_clientId); + LOG_INFO_NEW("the client instance:{} start doRebalance", m_clientId); if (getConsumerTableSize() > 0) { std::lock_guard lock(m_consumerTableMutex); for (auto& it : m_consumerTable) { it.second->doRebalance(); } } - LOG_INFO_NEW("Client factory:{} finish dorebalance", m_clientId); + LOG_INFO_NEW("the client instance [{}] finish doRebalance", m_clientId); } void MQClientInstance::doRebalanceByConsumerGroup(const std::string& consumerGroup) { std::lock_guard lock(m_consumerTableMutex); - if (m_consumerTable.find(consumerGroup) != m_consumerTable.end()) { + const auto& it = m_consumerTable.find(consumerGroup); + if (it != m_consumerTable.end()) { try { - LOG_INFO_NEW("Client factory:{} start dorebalance for consumer:{}", m_clientId, consumerGroup); - auto* consumer = m_consumerTable[consumerGroup]; + LOG_INFO_NEW("the client instance [{}] start doRebalance for consumer [{}]", m_clientId, consumerGroup); + auto* consumer = it->second; consumer->doRebalance(); } catch (const std::exception& e) { LOG_ERROR_NEW("{}", e.what()); @@ -620,24 +644,28 @@ void MQClientInstance::doRebalanceByConsumerGroup(const std::string& consumerGro MQProducerInner* MQClientInstance::selectProducer(const std::string& producerName) { std::lock_guard lock(m_producerTableMutex); - if (m_producerTable.find(producerName) != m_producerTable.end()) { - return m_producerTable[producerName]; + const auto& it = m_producerTable.find(producerName); + if (it != m_producerTable.end()) { + return it->second; } return nullptr; } bool MQClientInstance::addProducerToTable(const std::string& producerName, MQProducerInner* producer) { std::lock_guard lock(m_producerTableMutex); - if (m_producerTable.find(producerName) != m_producerTable.end()) + if (m_producerTable.find(producerName) != m_producerTable.end()) { return false; - m_producerTable[producerName] = producer; - return true; + } else { + m_producerTable[producerName] = producer; + return true; + } } void MQClientInstance::eraseProducerFromTable(const std::string& producerName) { std::lock_guard lock(m_producerTableMutex); - if (m_producerTable.find(producerName) != m_producerTable.end()) { - m_producerTable.erase(producerName); + const auto& it = m_producerTable.find(producerName); + if (it != m_producerTable.end()) { + m_producerTable.erase(it); } } @@ -659,8 +687,9 @@ void MQClientInstance::updateProducerTopicPublishInfo(const std::string& topic, MQConsumerInner* MQClientInstance::selectConsumer(const std::string& group) { std::lock_guard lock(m_consumerTableMutex); - if (m_consumerTable.find(group) != m_consumerTable.end()) { - return m_consumerTable[group]; + const auto& it = m_consumerTable.find(group); + if (it != m_consumerTable.end()) { + return it->second; } return nullptr; } @@ -677,8 +706,9 @@ bool MQClientInstance::addConsumerToTable(const std::string& consumerName, MQCon void MQClientInstance::eraseConsumerFromTable(const std::string& consumerName) { std::lock_guard lock(m_consumerTableMutex); - if (m_consumerTable.find(consumerName) != m_consumerTable.end()) { - m_consumerTable.erase(consumerName); // do not need free consumer, as it was allocated by user + const auto& it = m_consumerTable.find(consumerName); + if (it != m_consumerTable.end()) { + m_consumerTable.erase(it); // do not need free consumer, as it was allocated by user } else { LOG_WARN_NEW("could not find consumer:{} from table", consumerName); } @@ -714,36 +744,34 @@ void MQClientInstance::addTopicInfoToTable(const std::string& topic, TopicPublis void MQClientInstance::eraseTopicInfoFromTable(const std::string& topic) { std::lock_guard lock(m_topicPublishInfoTableMutex); - if (m_topicPublishInfoTable.find(topic) != m_topicPublishInfoTable.end()) { - m_topicPublishInfoTable.erase(topic); + const auto& it = m_topicPublishInfoTable.find(topic); + if (it != m_topicPublishInfoTable.end()) { + m_topicPublishInfoTable.erase(it); } } TopicPublishInfoPtr MQClientInstance::getTopicPublishInfoFromTable(const std::string& topic) { std::lock_guard lock(m_topicPublishInfoTableMutex); - if (m_topicPublishInfoTable.find(topic) != m_topicPublishInfoTable.end()) { - return m_topicPublishInfoTable[topic]; + const auto& it = m_topicPublishInfoTable.find(topic); + if (it != m_topicPublishInfoTable.end()) { + return it->second; } - return TopicPublishInfoPtr(); + return nullptr; } bool MQClientInstance::isTopicInfoValidInTable(const std::string& topic) { std::lock_guard lock(m_topicPublishInfoTableMutex); - auto iter = m_topicPublishInfoTable.find(topic); - if (iter != m_topicPublishInfoTable.end()) { - return iter->second->ok(); - } - return false; + return m_topicPublishInfoTable.find(topic) != m_topicPublishInfoTable.end(); } TopicPublishInfoPtr MQClientInstance::tryToFindTopicPublishInfo(const std::string& topic) { auto topicPublishInfo = getTopicPublishInfoFromTable(topic); - if (nullptr == topicPublishInfo || !topicPublishInfo->ok()) { + if (nullptr == topicPublishInfo) { updateTopicRouteInfoFromNameServer(topic); topicPublishInfo = getTopicPublishInfoFromTable(topic); } - if (nullptr != topicPublishInfo && (topicPublishInfo->isHaveTopicRouterInfo() || topicPublishInfo->ok())) { + if (nullptr != topicPublishInfo && topicPublishInfo->ok()) { return topicPublishInfo; } else { LOG_INFO_NEW("updateTopicRouteInfoFromNameServer with default"); @@ -758,9 +786,10 @@ FindBrokerResult* MQClientInstance::findBrokerAddressInAdmin(const std::string& bool slave = false; std::string brokerAddr; - if (brokerTable.find(brokerName) != brokerTable.end()) { - std::map brokerMap(brokerTable[brokerName]); - std::map::iterator it1 = brokerMap.begin(); + const auto& it = brokerTable.find(brokerName); + if (it != brokerTable.end()) { + const auto& brokerMap = it->second; + const auto& it1 = brokerMap.begin(); if (it1 != brokerMap.end()) { slave = (it1->first != MASTER_ID); found = true; @@ -781,11 +810,12 @@ std::string MQClientInstance::findBrokerAddressInPublish(const std::string& brok std::string brokerAddr; bool found = false; - if (brokerTable.find(brokerName) != brokerTable.end()) { - const auto& brokerMap = brokerTable[brokerName]; - auto it = brokerMap.find(MASTER_ID); - if (it != brokerMap.end()) { - brokerAddr = it->second; + const auto& it = brokerTable.find(brokerName); + if (it != brokerTable.end()) { + const auto& brokerMap = it->second; + const auto& it1 = brokerMap.find(MASTER_ID); + if (it1 != brokerMap.end()) { + brokerAddr = it1->second; found = true; } } @@ -806,18 +836,19 @@ FindBrokerResult* MQClientInstance::findBrokerAddressInSubscribe(const std::stri bool found = false; BrokerAddrMAP brokerTable(getBrokerAddrTable()); - if (brokerTable.find(brokerName) != brokerTable.end()) { - std::map brokerMap(brokerTable[brokerName]); + const auto& it = brokerTable.find(brokerName); + if (it != brokerTable.end()) { + const auto& brokerMap = it->second; if (!brokerMap.empty()) { - auto iter = brokerMap.find(brokerId); - if (iter != brokerMap.end()) { - brokerAddr = iter->second; - slave = (brokerId != MASTER_ID); + const auto& it1 = brokerMap.find(brokerId); + if (it1 != brokerMap.end()) { + brokerAddr = it1->second; + slave = it1->first != MASTER_ID; found = true; } else if (!onlyThisBroker) { // not only from master - iter = brokerMap.begin(); - brokerAddr = iter->second; - slave = iter->first != MASTER_ID; + const auto& it2 = brokerMap.begin(); + brokerAddr = it2->second; + slave = it2->first != MASTER_ID; found = true; } } @@ -835,18 +866,42 @@ FindBrokerResult* MQClientInstance::findBrokerAddressInSubscribe(const std::stri void MQClientInstance::findConsumerIds(const std::string& topic, const std::string& group, std::vector& cids) { - std::string brokerAddr = findBrokerAddrByTopic(topic); + std::string brokerAddr; + + // find consumerIds from same broker every 40s + { + std::lock_guard lock(m_topicBrokerAddrTableMutex); + const auto& it = m_topicBrokerAddrTable.find(topic); + if (it != m_topicBrokerAddrTable.end()) { + if (UtilAll::currentTimeMillis() < it->second.second + 40000) { + brokerAddr = it->second.first; + } + } + } + if (brokerAddr.empty()) { - updateTopicRouteInfoFromNameServer(topic); + // select new one brokerAddr = findBrokerAddrByTopic(topic); + if (brokerAddr.empty()) { + updateTopicRouteInfoFromNameServer(topic); + brokerAddr = findBrokerAddrByTopic(topic); + } + + if (!brokerAddr.empty()) { + std::lock_guard lock(m_topicBrokerAddrTableMutex); + m_topicBrokerAddrTable[topic] = std::make_pair(brokerAddr, UtilAll::currentTimeMillis()); + } } if (!brokerAddr.empty()) { try { LOG_INFO_NEW("getConsumerIdList from broker:{}", brokerAddr); return m_mqClientAPIImpl->getConsumerIdListByGroup(brokerAddr, group, cids, 5000); - } catch (MQException& e) { - LOG_ERROR_NEW("{}", e.what()); + } catch (const MQException& e) { + LOG_ERROR_NEW("encounter exception when getConsumerIdList: {}", e.what()); + + std::lock_guard lock(m_topicBrokerAddrTableMutex); + m_topicBrokerAddrTable.erase(topic); } } } @@ -887,7 +942,7 @@ void MQClientInstance::resetOffset(const std::string& group, for (const auto& it : processQueueTable) { const auto& mq = it.first; - auto it2 = offsetTable.find(mq); + const auto& it2 = offsetTable.find(mq); if (it2 != offsetTable.end()) { auto offset = it2->second; consumer->updateConsumeOffset(mq, offset); @@ -911,19 +966,15 @@ ConsumerRunningInfo* MQClientInstance::consumerRunningInfo(const std::string& co if (consumer != nullptr) { std::unique_ptr runningInfo(consumer->consumerRunningInfo()); if (runningInfo != nullptr) { - auto nsList = m_mqClientAPIImpl->getRemotingClient()->getNameServerAddressList(); - - std::string nsAddr; - for (const auto& addr : nsList) { - nsAddr.append(addr); - } - + std::string nsAddr = getNamesrvAddr(); runningInfo->setProperty(ConsumerRunningInfo::PROP_NAMESERVER_ADDR, nsAddr); + if (consumer->consumeType() == CONSUME_PASSIVELY) { runningInfo->setProperty(ConsumerRunningInfo::PROP_CONSUME_TYPE, "CONSUME_PASSIVELY"); } else { runningInfo->setProperty(ConsumerRunningInfo::PROP_CONSUME_TYPE, "CONSUME_ACTIVELY"); } + runningInfo->setProperty(ConsumerRunningInfo::PROP_CLIENT_VERSION, MQVersion::GetVersionDesc(MQVersion::s_CurrentVersion)); @@ -938,10 +989,7 @@ ConsumerRunningInfo* MQClientInstance::consumerRunningInfo(const std::string& co void MQClientInstance::addBrokerToAddrTable(const std::string& brokerName, const std::map& brokerAddrs) { std::lock_guard lock(m_brokerAddrTableMutex); - if (m_brokerAddrTable.find(brokerName) != m_brokerAddrTable.end()) { - m_brokerAddrTable.erase(brokerName); - } - m_brokerAddrTable.emplace(brokerName, brokerAddrs); + m_brokerAddrTable[brokerName] = brokerAddrs; } void MQClientInstance::resetBrokerAddrTable(BrokerAddrMAP&& table) { diff --git a/src/MQClientInstance.h b/src/MQClientInstance.h index be6993f97..77ee4b6aa 100644 --- a/src/MQClientInstance.h +++ b/src/MQClientInstance.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "ConsumerRunningInfo.h" #include "FindBrokerResult.h" @@ -37,6 +38,8 @@ namespace rocketmq { class RPCHook; +typedef std::shared_ptr RPCHookPtr; + class MQClientAPIImpl; class MQAdminImpl; class ClientRemotingProcessor; @@ -48,15 +51,16 @@ typedef std::shared_ptr MQClientInstancePtr; class MQClientInstance { public: - MQClientInstance(MQClientConfig clientConfig, const std::string& clientId); - MQClientInstance(MQClientConfig clientConfig, const std::string& clientId, std::shared_ptr rpcHook); + MQClientInstance(const MQClientConfig& clientConfig, const std::string& clientId); + MQClientInstance(const MQClientConfig& clientConfig, const std::string& clientId, RPCHookPtr rpcHook); virtual ~MQClientInstance(); static TopicPublishInfoPtr topicRouteData2TopicPublishInfo(const std::string& topic, TopicRouteDataPtr route); static std::vector topicRouteData2TopicSubscribeInfo(const std::string& topic, TopicRouteDataPtr route); - std::string getClientId(); + const std::string& getClientId() const; + std::string getNamesrvAddr() const; void start(); void shutdown(); @@ -96,6 +100,8 @@ class MQClientInstance { public: TopicPublishInfoPtr tryToFindTopicPublishInfo(const std::string& topic); + TopicRouteDataPtr getTopicRouteData(const std::string& topic); + public: MQClientAPIImpl* getMQClientAPIImpl() const { return m_mqClientAPIImpl.get(); } MQAdminImpl* getMQAdminImpl() const { return m_mqAdminImpl.get(); } @@ -123,7 +129,6 @@ class MQClientInstance { // topic route bool topicRouteDataIsChange(TopicRouteData* old, TopicRouteData* now); - TopicRouteDataPtr getTopicRouteData(const std::string& topic); void addTopicRouteData(const std::string& topic, TopicRouteDataPtr topicRouteData); // heartbeat @@ -159,9 +164,8 @@ class MQClientInstance { bool isTopicInfoValidInTable(const std::string& topic); private: - MQClientConfig m_clientConfig; std::string m_clientId; - ServiceState m_serviceState; + volatile ServiceState m_serviceState; // group -> MQProducer typedef std::map MQPMAP; @@ -187,6 +191,11 @@ class MQClientInstance { TPMAP m_topicPublishInfoTable; std::mutex m_topicPublishInfoTableMutex; + // topic -> + typedef std::map> TBAMAP; + TBAMAP m_topicBrokerAddrTable; + std::mutex m_topicBrokerAddrTableMutex; + std::timed_mutex m_lockNamesrv; std::timed_mutex m_lockHeartbeat; diff --git a/src/MQClientManager.cpp b/src/MQClientManager.cpp index d768e8e61..a0b0fac3a 100644 --- a/src/MQClientManager.cpp +++ b/src/MQClientManager.cpp @@ -28,20 +28,20 @@ MQClientManager* MQClientManager::getInstance() { MQClientManager::MQClientManager() = default; MQClientManager::~MQClientManager() = default; -MQClientInstancePtr MQClientManager::getOrCreateMQClientInstance(const MQClientConfig* clientConfig) { +MQClientInstancePtr MQClientManager::getOrCreateMQClientInstance(const MQClientConfig& clientConfig) { return getOrCreateMQClientInstance(clientConfig, nullptr); } -MQClientInstancePtr MQClientManager::getOrCreateMQClientInstance(const MQClientConfig* clientConfig, - std::shared_ptr rpcHook) { - std::string clientId = clientConfig->buildMQClientId(); +MQClientInstancePtr MQClientManager::getOrCreateMQClientInstance(const MQClientConfig& clientConfig, + RPCHookPtr rpcHook) { + std::string clientId = clientConfig.buildMQClientId(); std::lock_guard lock(m_mutex); - auto it = m_instanceTable.find(clientId); + const auto& it = m_instanceTable.find(clientId); if (it != m_instanceTable.end()) { return it->second; } else { - // clone clientConfig - auto instance = std::make_shared(*clientConfig, clientId, rpcHook); + // Clone clientConfig in Java, but we don't now. + auto instance = std::make_shared(clientConfig, clientId, rpcHook); m_instanceTable[clientId] = instance; LOG_INFO_NEW("Created new MQClientInstance for clientId:[{}]", clientId); return instance; @@ -50,7 +50,7 @@ MQClientInstancePtr MQClientManager::getOrCreateMQClientInstance(const MQClientC void MQClientManager::removeMQClientInstance(const std::string& clientId) { std::lock_guard lock(m_mutex); - auto it = m_instanceTable.find(clientId); + const auto& it = m_instanceTable.find(clientId); if (it != m_instanceTable.end()) { m_instanceTable.erase(it); } diff --git a/src/MQClientManager.h b/src/MQClientManager.h index eee63bc87..7ecec156f 100644 --- a/src/MQClientManager.h +++ b/src/MQClientManager.h @@ -31,8 +31,8 @@ class MQClientManager { virtual ~MQClientManager(); - MQClientInstancePtr getOrCreateMQClientInstance(const MQClientConfig* clientConfig); - MQClientInstancePtr getOrCreateMQClientInstance(const MQClientConfig* clientConfig, std::shared_ptr rpcHook); + MQClientInstancePtr getOrCreateMQClientInstance(const MQClientConfig& clientConfig); + MQClientInstancePtr getOrCreateMQClientInstance(const MQClientConfig& clientConfig, RPCHookPtr rpcHook); void removeMQClientInstance(const std::string& clientId); diff --git a/src/common/ClientErrorCode.h b/src/common/ClientErrorCode.h new file mode 100644 index 000000000..d43e90ff0 --- /dev/null +++ b/src/common/ClientErrorCode.h @@ -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 __CLIENT_ERROR_CODE_H__ +#define __CLIENT_ERROR_CODE_H__ + +namespace rocketmq { + +class ClientErrorCode { + public: + static const int CONNECT_BROKER_EXCEPTION = 10001; + static const int ACCESS_BROKER_TIMEOUT = 10002; + static const int BROKER_NOT_EXIST_EXCEPTION = 10003; + static const int NO_NAME_SERVER_EXCEPTION = 10004; + static const int NOT_FOUND_TOPIC_EXCEPTION = 10005; + static const int REQUEST_TIMEOUT_EXCEPTION = 10006; + static const int CREATE_REPLY_MESSAGE_EXCEPTION = 10007; +}; + +} // namespace rocketmq + +#endif // __CLIENT_ERROR_CODE_H__ diff --git a/src/common/ClientRPCHook.cpp b/src/common/ClientRPCHook.cpp index 0f7c101df..356b0cf83 100644 --- a/src/common/ClientRPCHook.cpp +++ b/src/common/ClientRPCHook.cpp @@ -18,11 +18,10 @@ #include -#include "CommandHeader.h" #include "DataBlock.h" #include "Logging.h" #include "RemotingCommand.h" - +#include "protocol/header/CommandHeader.h" #include "spas_client.h" namespace rocketmq { @@ -55,12 +54,12 @@ void ClientRPCHook::signCommand(RemotingCommand& command) { headerMap.insert(std::make_pair(SessionCredentials::AccessKey, sessionCredentials_.getAccessKey())); headerMap.insert(std::make_pair(SessionCredentials::ONSChannelKey, sessionCredentials_.getAuthChannel())); - LOG_DEBUG("before insert declared filed, MAP SIZE is:" SIZET_FMT "", headerMap.size()); + LOG_DEBUG_NEW("before insert declared filed, MAP SIZE is:{}", headerMap.size()); auto* header = command.readCustomHeader(); if (header != nullptr) { header->SetDeclaredFieldOfCommandHeader(headerMap); } - LOG_DEBUG("after insert declared filed, MAP SIZE is:" SIZET_FMT "", headerMap.size()); + LOG_DEBUG_NEW("after insert declared filed, MAP SIZE is:{}", headerMap.size()); std::string totalMsg; for (const auto& it : headerMap) { @@ -71,18 +70,18 @@ void ClientRPCHook::signCommand(RemotingCommand& command) { LOG_DEBUG_NEW("request have msgBody, length is:{}", body->getSize()); totalMsg.append(body->getData(), body->getSize()); } - LOG_DEBUG("total msg info are:%s, size is:" SIZET_FMT "", totalMsg.c_str(), totalMsg.size()); + LOG_DEBUG_NEW("total msg info are:{}, size is:{}", totalMsg, totalMsg.size()); - char* pSignature = + char* sign = rocketmqSignature::spas_sign(totalMsg.c_str(), totalMsg.size(), sessionCredentials_.getSecretKey().c_str()); - if (pSignature != nullptr) { - std::string signature(static_cast(pSignature)); + if (sign != nullptr) { + std::string signature(static_cast(sign)); command.addExtField(SessionCredentials::Signature, signature); command.addExtField(SessionCredentials::AccessKey, sessionCredentials_.getAccessKey()); command.addExtField(SessionCredentials::ONSChannelKey, sessionCredentials_.getAuthChannel()); - rocketmqSignature::spas_mem_free(pSignature); + rocketmqSignature::spas_mem_free(sign); } else { - LOG_ERROR("signature for request failed"); + LOG_ERROR_NEW("signature for request failed"); } } diff --git a/src/common/DataBlock.cpp b/src/common/DataBlock.cpp index 7dba95a69..6592b85fa 100644 --- a/src/common/DataBlock.cpp +++ b/src/common/DataBlock.cpp @@ -127,7 +127,7 @@ void MemoryPool::reset() { void MemoryPool::reset(char* data, size_t size) { if (size != 0) { - throw std::runtime_error("MemoryBlock can't set external pointer as data."); + throw std::runtime_error("MemoryPool can't set external pointer as data."); } std::free(data_); diff --git a/src/common/InputStream.cpp b/src/common/InputStream.cpp index 046d04810..5a53819e2 100644 --- a/src/common/InputStream.cpp +++ b/src/common/InputStream.cpp @@ -78,10 +78,10 @@ int64_t InputStream::readInt64BigEndian() { float InputStream::readFloatBigEndian() { union { - int32 asInt; + int32_t asInt; float asFloat; } n; - n.asInt = (int32)readIntBigEndian(); + n.asInt = (int32_t)readIntBigEndian(); return n.asFloat; } diff --git a/src/common/InputStream.h b/src/common/InputStream.h index 12a07fb01..1a29bc8a7 100644 --- a/src/common/InputStream.h +++ b/src/common/InputStream.h @@ -14,10 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef INPUTSTREAM_H_INCLUDED -#define INPUTSTREAM_H_INCLUDED +#ifndef __INPUT_STREAM_H__ +#define __INPUT_STREAM_H__ #include "DataBlock.h" + //============================================================================== /** The base class for streams that read data. @@ -28,6 +29,7 @@ @see OutputStream, MemoryInputStream, BufferedInputStream, FileInputStream */ namespace rocketmq { + class ROCKETMQCLIENT_API InputStream { public: /** Destructor. */ @@ -189,5 +191,7 @@ class ROCKETMQCLIENT_API InputStream { //============================================================================== InputStream() {} }; + } // namespace rocketmq -#endif // INPUTSTREAM_H_INCLUDED + +#endif // __INPUT_STREAM_H__ diff --git a/src/common/MQVersion.cpp b/src/common/MQVersion.cpp index 498f01b2e..1d8e481c3 100644 --- a/src/common/MQVersion.cpp +++ b/src/common/MQVersion.cpp @@ -18,8 +18,8 @@ namespace rocketmq { -int MQVersion::s_CurrentVersion = MQVersion::V4_6_0; -std::string MQVersion::s_CurrentLanguage = "CPP"; +const int MQVersion::s_CurrentVersion = MQVersion::V4_6_0; +const std::string MQVersion::s_CurrentLanguage = "CPP"; const char* MQVersion::GetVersionDesc(int value) { int currentVersion = value; diff --git a/src/common/MQVersion.h b/src/common/MQVersion.h index eb68fbc9d..2760dad64 100644 --- a/src/common/MQVersion.h +++ b/src/common/MQVersion.h @@ -38,586 +38,304 @@ static const char* RocketMQCPPClientVersion[] = {"V3_0_0_SNAPSHOT", "V3_0_0_ALP "V3_0_7_SNAPSHOT", "V3_0_7", "V3_0_8_SNAPSHOT", "V3_0_8", "V3_0_9_SNAPSHOT", "V3_0_9", - "V3_0_10_SNAPSHOT", "V3_0_10", - "V3_0_11_SNAPSHOT", "V3_0_11", - "V3_0_12_SNAPSHOT", "V3_0_12", - "V3_0_13_SNAPSHOT", "V3_0_13", - "V3_0_14_SNAPSHOT", "V3_0_14", - "V3_0_15_SNAPSHOT", "V3_0_15", - "V3_1_0_SNAPSHOT", "V3_1_0", - "V3_1_1_SNAPSHOT", "V3_1_1", - "V3_1_2_SNAPSHOT", "V3_1_2", - "V3_1_3_SNAPSHOT", "V3_1_3", - "V3_1_4_SNAPSHOT", "V3_1_4", - "V3_1_5_SNAPSHOT", "V3_1_5", - "V3_1_6_SNAPSHOT", "V3_1_6", - "V3_1_7_SNAPSHOT", "V3_1_7", - "V3_1_8_SNAPSHOT", "V3_1_8", - "V3_1_9_SNAPSHOT", "V3_1_9", - "V3_2_0_SNAPSHOT", "V3_2_0", - "V3_2_1_SNAPSHOT", "V3_2_1", - "V3_2_2_SNAPSHOT", "V3_2_2", - "V3_2_3_SNAPSHOT", "V3_2_3", - "V3_2_4_SNAPSHOT", "V3_2_4", - "V3_2_5_SNAPSHOT", "V3_2_5", - "V3_2_6_SNAPSHOT", "V3_2_6", - "V3_2_7_SNAPSHOT", "V3_2_7", - "V3_2_8_SNAPSHOT", "V3_2_8", - "V3_2_9_SNAPSHOT", "V3_2_9", - + "V3_3_0_SNAPSHOT", "V3_3_0", "V3_3_1_SNAPSHOT", "V3_3_1", - "V3_3_2_SNAPSHOT", "V3_3_2", - "V3_3_3_SNAPSHOT", "V3_3_3", - "V3_3_4_SNAPSHOT", "V3_3_4", - "V3_3_5_SNAPSHOT", "V3_3_5", - "V3_3_6_SNAPSHOT", "V3_3_6", - "V3_3_7_SNAPSHOT", "V3_3_7", - "V3_3_8_SNAPSHOT", "V3_3_8", - "V3_3_9_SNAPSHOT", "V3_3_9", - + "V3_4_0_SNAPSHOT", "V3_4_0", "V3_4_1_SNAPSHOT", "V3_4_1", - "V3_4_2_SNAPSHOT", "V3_4_2", - "V3_4_3_SNAPSHOT", "V3_4_3", - "V3_4_4_SNAPSHOT", "V3_4_4", - "V3_4_5_SNAPSHOT", "V3_4_5", - "V3_4_6_SNAPSHOT", "V3_4_6", - "V3_4_7_SNAPSHOT", "V3_4_7", - "V3_4_8_SNAPSHOT", "V3_4_8", - "V3_4_9_SNAPSHOT", "V3_4_9", + "V3_5_0_SNAPSHOT", "V3_5_0", "V3_5_1_SNAPSHOT", "V3_5_1", - "V3_5_2_SNAPSHOT", "V3_5_2", - "V3_5_3_SNAPSHOT", "V3_5_3", - "V3_5_4_SNAPSHOT", "V3_5_4", - "V3_5_5_SNAPSHOT", "V3_5_5", - "V3_5_6_SNAPSHOT", "V3_5_6", - "V3_5_7_SNAPSHOT", "V3_5_7", - "V3_5_8_SNAPSHOT", "V3_5_8", - "V3_5_9_SNAPSHOT", "V3_5_9", - + "V3_6_0_SNAPSHOT", "V3_6_0", "V3_6_1_SNAPSHOT", "V3_6_1", - "V3_6_2_SNAPSHOT", "V3_6_2", - "V3_6_3_SNAPSHOT", "V3_6_3", - "V3_6_4_SNAPSHOT", "V3_6_4", - "V3_6_5_SNAPSHOT", "V3_6_5", - "V3_6_6_SNAPSHOT", "V3_6_6", - "V3_6_7_SNAPSHOT", "V3_6_7", - "V3_6_8_SNAPSHOT", "V3_6_8", - "V3_6_9_SNAPSHOT", "V3_6_9", - + "V3_7_0_SNAPSHOT", "V3_7_0", "V3_7_1_SNAPSHOT", "V3_7_1", - "V3_7_2_SNAPSHOT", "V3_7_2", - "V3_7_3_SNAPSHOT", "V3_7_3", - "V3_7_4_SNAPSHOT", "V3_7_4", - "V3_7_5_SNAPSHOT", "V3_7_5", - "V3_7_6_SNAPSHOT", "V3_7_6", - "V3_7_7_SNAPSHOT", "V3_7_7", - "V3_7_8_SNAPSHOT", "V3_7_8", - "V3_7_9_SNAPSHOT", "V3_7_9", - + "V3_8_0_SNAPSHOT", "V3_8_0", "V3_8_1_SNAPSHOT", "V3_8_1", - "V3_8_2_SNAPSHOT", "V3_8_2", - "V3_8_3_SNAPSHOT", "V3_8_3", - "V3_8_4_SNAPSHOT", "V3_8_4", - "V3_8_5_SNAPSHOT", "V3_8_5", - "V3_8_6_SNAPSHOT", "V3_8_6", - "V3_8_7_SNAPSHOT", "V3_8_7", - "V3_8_8_SNAPSHOT", "V3_8_8", - "V3_8_9_SNAPSHOT", "V3_8_9", - "V3_9_1_SNAPSHOT", "V3_9_1", - + "V3_9_0_SNAPSHOT", "V3_9_0", "V3_9_2_SNAPSHOT", "V3_9_2", - "V3_9_3_SNAPSHOT", "V3_9_3", - "V3_9_4_SNAPSHOT", "V3_9_4", - "V3_9_5_SNAPSHOT", "V3_9_5", - "V3_9_6_SNAPSHOT", "V3_9_6", - "V3_9_7_SNAPSHOT", "V3_9_7", - "V3_9_8_SNAPSHOT", "V3_9_8", - "V3_9_9_SNAPSHOT", "V3_9_9", - "V4_0_0_SNAPSHOT", "V4_0_0", - "V4_0_1_SNAPSHOT", "V4_0_1", - "V4_0_2_SNAPSHOT", "V4_0_2", - "V4_0_3_SNAPSHOT", "V4_0_3", - "V4_0_4_SNAPSHOT", "V4_0_4", - "V4_0_5_SNAPSHOT", "V4_0_5", - "V4_0_6_SNAPSHOT", "V4_0_6", - "V4_0_7_SNAPSHOT", "V4_0_7", - "V4_0_8_SNAPSHOT", "V4_0_8", - "V4_0_9_SNAPSHOT", "V4_0_9", - "V4_1_0_SNAPSHOT", "V4_1_0", - "V4_1_1_SNAPSHOT", "V4_1_1", - "V4_1_2_SNAPSHOT", "V4_1_2", - "V4_1_3_SNAPSHOT", "V4_1_3", - "V4_1_4_SNAPSHOT", "V4_1_4", - "V4_1_5_SNAPSHOT", "V4_1_5", - "V4_1_6_SNAPSHOT", "V4_1_6", - "V4_1_7_SNAPSHOT", "V4_1_7", - "V4_1_8_SNAPSHOT", "V4_1_8", - "V4_1_9_SNAPSHOT", "V4_1_9", - "V4_2_0_SNAPSHOT", "V4_2_0", - "V4_2_1_SNAPSHOT", "V4_2_1", - "V4_2_2_SNAPSHOT", "V4_2_2", - "V4_2_3_SNAPSHOT", "V4_2_3", - "V4_2_4_SNAPSHOT", "V4_2_4", - "V4_2_5_SNAPSHOT", "V4_2_5", - "V4_2_6_SNAPSHOT", "V4_2_6", - "V4_2_7_SNAPSHOT", "V4_2_7", - "V4_2_8_SNAPSHOT", "V4_2_8", - "V4_2_9_SNAPSHOT", "V4_2_9", - "V4_3_0_SNAPSHOT", "V4_3_0", - "V4_3_1_SNAPSHOT", "V4_3_1", - "V4_3_2_SNAPSHOT", "V4_3_2", - "V4_3_3_SNAPSHOT", "V4_3_3", - "V4_3_4_SNAPSHOT", "V4_3_4", - "V4_3_5_SNAPSHOT", "V4_3_5", - "V4_3_6_SNAPSHOT", "V4_3_6", - "V4_3_7_SNAPSHOT", "V4_3_7", - "V4_3_8_SNAPSHOT", "V4_3_8", - "V4_3_9_SNAPSHOT", "V4_3_9", - "V4_4_0_SNAPSHOT", "V4_4_0", - "V4_4_1_SNAPSHOT", "V4_4_1", - "V4_4_2_SNAPSHOT", "V4_4_2", - "V4_4_3_SNAPSHOT", "V4_4_3", - "V4_4_4_SNAPSHOT", "V4_4_4", - "V4_4_5_SNAPSHOT", "V4_4_5", - "V4_4_6_SNAPSHOT", "V4_4_6", - "V4_4_7_SNAPSHOT", "V4_4_7", - "V4_4_8_SNAPSHOT", "V4_4_8", - "V4_4_9_SNAPSHOT", "V4_4_9", - "V4_5_0_SNAPSHOT", "V4_5_0", - "V4_5_1_SNAPSHOT", "V4_5_1", - "V4_5_2_SNAPSHOT", "V4_5_2", - "V4_5_3_SNAPSHOT", "V4_5_3", - "V4_5_4_SNAPSHOT", "V4_5_4", - "V4_5_5_SNAPSHOT", "V4_5_5", - "V4_5_6_SNAPSHOT", "V4_5_6", - "V4_5_7_SNAPSHOT", "V4_5_7", - "V4_5_8_SNAPSHOT", "V4_5_8", - "V4_5_9_SNAPSHOT", "V4_5_9", - "V4_6_0_SNAPSHOT", "V4_6_0", - "V4_6_1_SNAPSHOT", "V4_6_1", - "V4_6_2_SNAPSHOT", "V4_6_2", - "V4_6_3_SNAPSHOT", "V4_6_3", - "V4_6_4_SNAPSHOT", "V4_6_4", - "V4_6_5_SNAPSHOT", "V4_6_5", - "V4_6_6_SNAPSHOT", "V4_6_6", - "V4_6_7_SNAPSHOT", "V4_6_7", - "V4_6_8_SNAPSHOT", "V4_6_8", - "V4_6_9_SNAPSHOT", "V4_6_9", - "V4_7_0_SNAPSHOT", "V4_7_0", - "V4_7_1_SNAPSHOT", "V4_7_1", - "V4_7_2_SNAPSHOT", "V4_7_2", - "V4_7_3_SNAPSHOT", "V4_7_3", - "V4_7_4_SNAPSHOT", "V4_7_4", - "V4_7_5_SNAPSHOT", "V4_7_5", - "V4_7_6_SNAPSHOT", "V4_7_6", - "V4_7_7_SNAPSHOT", "V4_7_7", - "V4_7_8_SNAPSHOT", "V4_7_8", - "V4_7_9_SNAPSHOT", "V4_7_9", - "V4_8_0_SNAPSHOT", "V4_8_0", - "V4_8_1_SNAPSHOT", "V4_8_1", - "V4_8_2_SNAPSHOT", "V4_8_2", - "V4_8_3_SNAPSHOT", "V4_8_3", - "V4_8_4_SNAPSHOT", "V4_8_4", - "V4_8_5_SNAPSHOT", "V4_8_5", - "V4_8_6_SNAPSHOT", "V4_8_6", - "V4_8_7_SNAPSHOT", "V4_8_7", - "V4_8_8_SNAPSHOT", "V4_8_8", - "V4_8_9_SNAPSHOT", "V4_8_9", - "V4_9_0_SNAPSHOT", "V4_9_0", - "V4_9_1_SNAPSHOT", "V4_9_1", - "V4_9_2_SNAPSHOT", "V4_9_2", - "V4_9_3_SNAPSHOT", "V4_9_3", - "V4_9_4_SNAPSHOT", "V4_9_4", - "V4_9_5_SNAPSHOT", "V4_9_5", - "V4_9_6_SNAPSHOT", "V4_9_6", - "V4_9_7_SNAPSHOT", "V4_9_7", - "V4_9_8_SNAPSHOT", "V4_9_8", - "V4_9_9_SNAPSHOT", "V4_9_9", - "V5_0_0_SNAPSHOT", "V5_0_0", - "V5_0_1_SNAPSHOT", "V5_0_1", - "V5_0_2_SNAPSHOT", "V5_0_2", - "V5_0_3_SNAPSHOT", "V5_0_3", - "V5_0_4_SNAPSHOT", "V5_0_4", - "V5_0_5_SNAPSHOT", "V5_0_5", - "V5_0_6_SNAPSHOT", "V5_0_6", - "V5_0_7_SNAPSHOT", "V5_0_7", - "V5_0_8_SNAPSHOT", "V5_0_8", - "V5_0_9_SNAPSHOT", "V5_0_9", - "V5_1_0_SNAPSHOT", "V5_1_0", - "V5_1_1_SNAPSHOT", "V5_1_1", - "V5_1_2_SNAPSHOT", "V5_1_2", - "V5_1_3_SNAPSHOT", "V5_1_3", - "V5_1_4_SNAPSHOT", "V5_1_4", - "V5_1_5_SNAPSHOT", "V5_1_5", - "V5_1_6_SNAPSHOT", "V5_1_6", - "V5_1_7_SNAPSHOT", "V5_1_7", - "V5_1_8_SNAPSHOT", "V5_1_8", - "V5_1_9_SNAPSHOT", "V5_1_9", - "V5_2_0_SNAPSHOT", "V5_2_0", - "V5_2_1_SNAPSHOT", "V5_2_1", - "V5_2_2_SNAPSHOT", "V5_2_2", - "V5_2_3_SNAPSHOT", "V5_2_3", - "V5_2_4_SNAPSHOT", "V5_2_4", - "V5_2_5_SNAPSHOT", "V5_2_5", - "V5_2_6_SNAPSHOT", "V5_2_6", - "V5_2_7_SNAPSHOT", "V5_2_7", - "V5_2_8_SNAPSHOT", "V5_2_8", - "V5_2_9_SNAPSHOT", "V5_2_9", - "V5_3_0_SNAPSHOT", "V5_3_0", - "V5_3_1_SNAPSHOT", "V5_3_1", - "V5_3_2_SNAPSHOT", "V5_3_2", - "V5_3_3_SNAPSHOT", "V5_3_3", - "V5_3_4_SNAPSHOT", "V5_3_4", - "V5_3_5_SNAPSHOT", "V5_3_5", - "V5_3_6_SNAPSHOT", "V5_3_6", - "V5_3_7_SNAPSHOT", "V5_3_7", - "V5_3_8_SNAPSHOT", "V5_3_8", - "V5_3_9_SNAPSHOT", "V5_3_9", - "V5_4_0_SNAPSHOT", "V5_4_0", - "V5_4_1_SNAPSHOT", "V5_4_1", - "V5_4_2_SNAPSHOT", "V5_4_2", - "V5_4_3_SNAPSHOT", "V5_4_3", - "V5_4_4_SNAPSHOT", "V5_4_4", - "V5_4_5_SNAPSHOT", "V5_4_5", - "V5_4_6_SNAPSHOT", "V5_4_6", - "V5_4_7_SNAPSHOT", "V5_4_7", - "V5_4_8_SNAPSHOT", "V5_4_8", - "V5_4_9_SNAPSHOT", "V5_4_9", - "V5_5_0_SNAPSHOT", "V5_5_0", - "V5_5_1_SNAPSHOT", "V5_5_1", - "V5_5_2_SNAPSHOT", "V5_5_2", - "V5_5_3_SNAPSHOT", "V5_5_3", - "V5_5_4_SNAPSHOT", "V5_5_4", - "V5_5_5_SNAPSHOT", "V5_5_5", - "V5_5_6_SNAPSHOT", "V5_5_6", - "V5_5_7_SNAPSHOT", "V5_5_7", - "V5_5_8_SNAPSHOT", "V5_5_8", - "V5_5_9_SNAPSHOT", "V5_5_9", - "V5_6_0_SNAPSHOT", "V5_6_0", - "V5_6_1_SNAPSHOT", "V5_6_1", - "V5_6_2_SNAPSHOT", "V5_6_2", - "V5_6_3_SNAPSHOT", "V5_6_3", - "V5_6_4_SNAPSHOT", "V5_6_4", - "V5_6_5_SNAPSHOT", "V5_6_5", - "V5_6_6_SNAPSHOT", "V5_6_6", - "V5_6_7_SNAPSHOT", "V5_6_7", - "V5_6_8_SNAPSHOT", "V5_6_8", - "V5_6_9_SNAPSHOT", "V5_6_9", - "V5_7_0_SNAPSHOT", "V5_7_0", - "V5_7_1_SNAPSHOT", "V5_7_1", - "V5_7_2_SNAPSHOT", "V5_7_2", - "V5_7_3_SNAPSHOT", "V5_7_3", - "V5_7_4_SNAPSHOT", "V5_7_4", - "V5_7_5_SNAPSHOT", "V5_7_5", - "V5_7_6_SNAPSHOT", "V5_7_6", - "V5_7_7_SNAPSHOT", "V5_7_7", - "V5_7_8_SNAPSHOT", "V5_7_8", - "V5_7_9_SNAPSHOT", "V5_7_9", - "V5_8_0_SNAPSHOT", "V5_8_0", - "V5_8_1_SNAPSHOT", "V5_8_1", - "V5_8_2_SNAPSHOT", "V5_8_2", - "V5_8_3_SNAPSHOT", "V5_8_3", - "V5_8_4_SNAPSHOT", "V5_8_4", - "V5_8_5_SNAPSHOT", "V5_8_5", - "V5_8_6_SNAPSHOT", "V5_8_6", - "V5_8_7_SNAPSHOT", "V5_8_7", - "V5_8_8_SNAPSHOT", "V5_8_8", - "V5_8_9_SNAPSHOT", "V5_8_9", - "V5_9_0_SNAPSHOT", "V5_9_0", - "V5_9_1_SNAPSHOT", "V5_9_1", - "V5_9_2_SNAPSHOT", "V5_9_2", - "V5_9_3_SNAPSHOT", "V5_9_3", - "V5_9_4_SNAPSHOT", "V5_9_4", - "V5_9_5_SNAPSHOT", "V5_9_5", - "V5_9_6_SNAPSHOT", "V5_9_6", - "V5_9_7_SNAPSHOT", "V5_9_7", - "V5_9_8_SNAPSHOT", "V5_9_8", - "V5_9_9_SNAPSHOT", "V5_9_9", - "HIGHER_VERSION" + "HIGHER_VERSION"}; -}; class MQVersion { public: enum Version { @@ -655,879 +373,605 @@ class MQVersion { V3_0_8, V3_0_9_SNAPSHOT, V3_0_9, - V3_0_10_SNAPSHOT, V3_0_10, - V3_0_11_SNAPSHOT, V3_0_11, - V3_0_12_SNAPSHOT, V3_0_12, - V3_0_13_SNAPSHOT, V3_0_13, - V3_0_14_SNAPSHOT, V3_0_14, - V3_0_15_SNAPSHOT, V3_0_15, - V3_1_0_SNAPSHOT, V3_1_0, - V3_1_1_SNAPSHOT, V3_1_1, - V3_1_2_SNAPSHOT, V3_1_2, - V3_1_3_SNAPSHOT, V3_1_3, - V3_1_4_SNAPSHOT, V3_1_4, - V3_1_5_SNAPSHOT, V3_1_5, - V3_1_6_SNAPSHOT, V3_1_6, - V3_1_7_SNAPSHOT, V3_1_7, - V3_1_8_SNAPSHOT, V3_1_8, - V3_1_9_SNAPSHOT, V3_1_9, - V3_2_0_SNAPSHOT, V3_2_0, - V3_2_1_SNAPSHOT, V3_2_1, - V3_2_2_SNAPSHOT, V3_2_2, - V3_2_3_SNAPSHOT, V3_2_3, - V3_2_4_SNAPSHOT, V3_2_4, - V3_2_5_SNAPSHOT, V3_2_5, - V3_2_6_SNAPSHOT, V3_2_6, - V3_2_7_SNAPSHOT, V3_2_7, - V3_2_8_SNAPSHOT, V3_2_8, - V3_2_9_SNAPSHOT, V3_2_9, - + V3_3_0_SNAPSHOT, + V3_3_0, V3_3_1_SNAPSHOT, V3_3_1, - V3_3_2_SNAPSHOT, V3_3_2, - V3_3_3_SNAPSHOT, V3_3_3, - V3_3_4_SNAPSHOT, V3_3_4, - V3_3_5_SNAPSHOT, V3_3_5, - V3_3_6_SNAPSHOT, V3_3_6, - V3_3_7_SNAPSHOT, V3_3_7, - V3_3_8_SNAPSHOT, V3_3_8, - V3_3_9_SNAPSHOT, V3_3_9, - + V3_4_0_SNAPSHOT, + V3_4_0, V3_4_1_SNAPSHOT, V3_4_1, - V3_4_2_SNAPSHOT, V3_4_2, - V3_4_3_SNAPSHOT, V3_4_3, - V3_4_4_SNAPSHOT, V3_4_4, - V3_4_5_SNAPSHOT, V3_4_5, - V3_4_6_SNAPSHOT, V3_4_6, - V3_4_7_SNAPSHOT, V3_4_7, - V3_4_8_SNAPSHOT, V3_4_8, - V3_4_9_SNAPSHOT, V3_4_9, + V3_5_0_SNAPSHOT, + V3_5_0, V3_5_1_SNAPSHOT, V3_5_1, - V3_5_2_SNAPSHOT, V3_5_2, - V3_5_3_SNAPSHOT, V3_5_3, - V3_5_4_SNAPSHOT, V3_5_4, - V3_5_5_SNAPSHOT, V3_5_5, - V3_5_6_SNAPSHOT, V3_5_6, - V3_5_7_SNAPSHOT, V3_5_7, - V3_5_8_SNAPSHOT, V3_5_8, - V3_5_9_SNAPSHOT, V3_5_9, - + V3_6_0_SNAPSHOT, + V3_6_0, V3_6_1_SNAPSHOT, V3_6_1, - V3_6_2_SNAPSHOT, V3_6_2, - V3_6_3_SNAPSHOT, V3_6_3, - V3_6_4_SNAPSHOT, V3_6_4, - V3_6_5_SNAPSHOT, V3_6_5, - V3_6_6_SNAPSHOT, V3_6_6, - V3_6_7_SNAPSHOT, V3_6_7, - V3_6_8_SNAPSHOT, V3_6_8, - V3_6_9_SNAPSHOT, V3_6_9, - + V3_7_0_SNAPSHOT, + V3_7_0, V3_7_1_SNAPSHOT, V3_7_1, - V3_7_2_SNAPSHOT, V3_7_2, - V3_7_3_SNAPSHOT, V3_7_3, - V3_7_4_SNAPSHOT, V3_7_4, - V3_7_5_SNAPSHOT, V3_7_5, - V3_7_6_SNAPSHOT, V3_7_6, - V3_7_7_SNAPSHOT, V3_7_7, - V3_7_8_SNAPSHOT, V3_7_8, - V3_7_9_SNAPSHOT, V3_7_9, - + V3_8_0_SNAPSHOT, + V3_8_0, V3_8_1_SNAPSHOT, V3_8_1, - V3_8_2_SNAPSHOT, V3_8_2, - V3_8_3_SNAPSHOT, V3_8_3, - V3_8_4_SNAPSHOT, V3_8_4, - V3_8_5_SNAPSHOT, V3_8_5, - V3_8_6_SNAPSHOT, V3_8_6, - V3_8_7_SNAPSHOT, V3_8_7, - V3_8_8_SNAPSHOT, V3_8_8, - V3_8_9_SNAPSHOT, V3_8_9, - + V3_9_0_SNAPSHOT, + V3_9_0, V3_9_1_SNAPSHOT, V3_9_1, - V3_9_2_SNAPSHOT, V3_9_2, - V3_9_3_SNAPSHOT, V3_9_3, - V3_9_4_SNAPSHOT, V3_9_4, - V3_9_5_SNAPSHOT, V3_9_5, - V3_9_6_SNAPSHOT, V3_9_6, - V3_9_7_SNAPSHOT, V3_9_7, - V3_9_8_SNAPSHOT, V3_9_8, - V3_9_9_SNAPSHOT, V3_9_9, - V4_0_0_SNAPSHOT, V4_0_0, - V4_0_1_SNAPSHOT, V4_0_1, - V4_0_2_SNAPSHOT, V4_0_2, - V4_0_3_SNAPSHOT, V4_0_3, - V4_0_4_SNAPSHOT, V4_0_4, - V4_0_5_SNAPSHOT, V4_0_5, - V4_0_6_SNAPSHOT, V4_0_6, - V4_0_7_SNAPSHOT, V4_0_7, - V4_0_8_SNAPSHOT, V4_0_8, - V4_0_9_SNAPSHOT, V4_0_9, - V4_1_0_SNAPSHOT, V4_1_0, - V4_1_1_SNAPSHOT, V4_1_1, - V4_1_2_SNAPSHOT, V4_1_2, - V4_1_3_SNAPSHOT, V4_1_3, - V4_1_4_SNAPSHOT, V4_1_4, - V4_1_5_SNAPSHOT, V4_1_5, - V4_1_6_SNAPSHOT, V4_1_6, - V4_1_7_SNAPSHOT, V4_1_7, - V4_1_8_SNAPSHOT, V4_1_8, - V4_1_9_SNAPSHOT, V4_1_9, - V4_2_0_SNAPSHOT, V4_2_0, - V4_2_1_SNAPSHOT, V4_2_1, - V4_2_2_SNAPSHOT, V4_2_2, - V4_2_3_SNAPSHOT, V4_2_3, - V4_2_4_SNAPSHOT, V4_2_4, - V4_2_5_SNAPSHOT, V4_2_5, - V4_2_6_SNAPSHOT, V4_2_6, - V4_2_7_SNAPSHOT, V4_2_7, - V4_2_8_SNAPSHOT, V4_2_8, - V4_2_9_SNAPSHOT, V4_2_9, - V4_3_0_SNAPSHOT, V4_3_0, - V4_3_1_SNAPSHOT, V4_3_1, - V4_3_2_SNAPSHOT, V4_3_2, - V4_3_3_SNAPSHOT, V4_3_3, - V4_3_4_SNAPSHOT, V4_3_4, - V4_3_5_SNAPSHOT, V4_3_5, - V4_3_6_SNAPSHOT, V4_3_6, - V4_3_7_SNAPSHOT, V4_3_7, - V4_3_8_SNAPSHOT, V4_3_8, - V4_3_9_SNAPSHOT, V4_3_9, - V4_4_0_SNAPSHOT, V4_4_0, - V4_4_1_SNAPSHOT, V4_4_1, - V4_4_2_SNAPSHOT, V4_4_2, - V4_4_3_SNAPSHOT, V4_4_3, - V4_4_4_SNAPSHOT, V4_4_4, - V4_4_5_SNAPSHOT, V4_4_5, - V4_4_6_SNAPSHOT, V4_4_6, - V4_4_7_SNAPSHOT, V4_4_7, - V4_4_8_SNAPSHOT, V4_4_8, - V4_4_9_SNAPSHOT, V4_4_9, - V4_5_0_SNAPSHOT, V4_5_0, - V4_5_1_SNAPSHOT, V4_5_1, - V4_5_2_SNAPSHOT, V4_5_2, - V4_5_3_SNAPSHOT, V4_5_3, - V4_5_4_SNAPSHOT, V4_5_4, - V4_5_5_SNAPSHOT, V4_5_5, - V4_5_6_SNAPSHOT, V4_5_6, - V4_5_7_SNAPSHOT, V4_5_7, - V4_5_8_SNAPSHOT, V4_5_8, - V4_5_9_SNAPSHOT, V4_5_9, - V4_6_0_SNAPSHOT, V4_6_0, - V4_6_1_SNAPSHOT, V4_6_1, - V4_6_2_SNAPSHOT, V4_6_2, - V4_6_3_SNAPSHOT, V4_6_3, - V4_6_4_SNAPSHOT, V4_6_4, - V4_6_5_SNAPSHOT, V4_6_5, - V4_6_6_SNAPSHOT, V4_6_6, - V4_6_7_SNAPSHOT, V4_6_7, - V4_6_8_SNAPSHOT, V4_6_8, - V4_6_9_SNAPSHOT, V4_6_9, - V4_7_0_SNAPSHOT, V4_7_0, - V4_7_1_SNAPSHOT, V4_7_1, - V4_7_2_SNAPSHOT, V4_7_2, - V4_7_3_SNAPSHOT, V4_7_3, - V4_7_4_SNAPSHOT, V4_7_4, - V4_7_5_SNAPSHOT, V4_7_5, - V4_7_6_SNAPSHOT, V4_7_6, - V4_7_7_SNAPSHOT, V4_7_7, - V4_7_8_SNAPSHOT, V4_7_8, - V4_7_9_SNAPSHOT, V4_7_9, - V4_8_0_SNAPSHOT, V4_8_0, - V4_8_1_SNAPSHOT, V4_8_1, - V4_8_2_SNAPSHOT, V4_8_2, - V4_8_3_SNAPSHOT, V4_8_3, - V4_8_4_SNAPSHOT, V4_8_4, - V4_8_5_SNAPSHOT, V4_8_5, - V4_8_6_SNAPSHOT, V4_8_6, - V4_8_7_SNAPSHOT, V4_8_7, - V4_8_8_SNAPSHOT, V4_8_8, - V4_8_9_SNAPSHOT, V4_8_9, - V4_9_0_SNAPSHOT, V4_9_0, - V4_9_1_SNAPSHOT, V4_9_1, - V4_9_2_SNAPSHOT, V4_9_2, - V4_9_3_SNAPSHOT, V4_9_3, - V4_9_4_SNAPSHOT, V4_9_4, - V4_9_5_SNAPSHOT, V4_9_5, - V4_9_6_SNAPSHOT, V4_9_6, - V4_9_7_SNAPSHOT, V4_9_7, - V4_9_8_SNAPSHOT, V4_9_8, - V4_9_9_SNAPSHOT, V4_9_9, - V5_0_0_SNAPSHOT, V5_0_0, - V5_0_1_SNAPSHOT, V5_0_1, - V5_0_2_SNAPSHOT, V5_0_2, - V5_0_3_SNAPSHOT, V5_0_3, - V5_0_4_SNAPSHOT, V5_0_4, - V5_0_5_SNAPSHOT, V5_0_5, - V5_0_6_SNAPSHOT, V5_0_6, - V5_0_7_SNAPSHOT, V5_0_7, - V5_0_8_SNAPSHOT, V5_0_8, - V5_0_9_SNAPSHOT, V5_0_9, - V5_1_0_SNAPSHOT, V5_1_0, - V5_1_1_SNAPSHOT, V5_1_1, - V5_1_2_SNAPSHOT, V5_1_2, - V5_1_3_SNAPSHOT, V5_1_3, - V5_1_4_SNAPSHOT, V5_1_4, - V5_1_5_SNAPSHOT, V5_1_5, - V5_1_6_SNAPSHOT, V5_1_6, - V5_1_7_SNAPSHOT, V5_1_7, - V5_1_8_SNAPSHOT, V5_1_8, - V5_1_9_SNAPSHOT, V5_1_9, - V5_2_0_SNAPSHOT, V5_2_0, - V5_2_1_SNAPSHOT, V5_2_1, - V5_2_2_SNAPSHOT, V5_2_2, - V5_2_3_SNAPSHOT, V5_2_3, - V5_2_4_SNAPSHOT, V5_2_4, - V5_2_5_SNAPSHOT, V5_2_5, - V5_2_6_SNAPSHOT, V5_2_6, - V5_2_7_SNAPSHOT, V5_2_7, - V5_2_8_SNAPSHOT, V5_2_8, - V5_2_9_SNAPSHOT, V5_2_9, - V5_3_0_SNAPSHOT, V5_3_0, - V5_3_1_SNAPSHOT, V5_3_1, - V5_3_2_SNAPSHOT, V5_3_2, - V5_3_3_SNAPSHOT, V5_3_3, - V5_3_4_SNAPSHOT, V5_3_4, - V5_3_5_SNAPSHOT, V5_3_5, - V5_3_6_SNAPSHOT, V5_3_6, - V5_3_7_SNAPSHOT, V5_3_7, - V5_3_8_SNAPSHOT, V5_3_8, - V5_3_9_SNAPSHOT, V5_3_9, - V5_4_0_SNAPSHOT, V5_4_0, - V5_4_1_SNAPSHOT, V5_4_1, - V5_4_2_SNAPSHOT, V5_4_2, - V5_4_3_SNAPSHOT, V5_4_3, - V5_4_4_SNAPSHOT, V5_4_4, - V5_4_5_SNAPSHOT, V5_4_5, - V5_4_6_SNAPSHOT, V5_4_6, - V5_4_7_SNAPSHOT, V5_4_7, - V5_4_8_SNAPSHOT, V5_4_8, - V5_4_9_SNAPSHOT, V5_4_9, - V5_5_0_SNAPSHOT, V5_5_0, - V5_5_1_SNAPSHOT, V5_5_1, - V5_5_2_SNAPSHOT, V5_5_2, - V5_5_3_SNAPSHOT, V5_5_3, - V5_5_4_SNAPSHOT, V5_5_4, - V5_5_5_SNAPSHOT, V5_5_5, - V5_5_6_SNAPSHOT, V5_5_6, - V5_5_7_SNAPSHOT, V5_5_7, - V5_5_8_SNAPSHOT, V5_5_8, - V5_5_9_SNAPSHOT, V5_5_9, - V5_6_0_SNAPSHOT, V5_6_0, - V5_6_1_SNAPSHOT, V5_6_1, - V5_6_2_SNAPSHOT, V5_6_2, - V5_6_3_SNAPSHOT, V5_6_3, - V5_6_4_SNAPSHOT, V5_6_4, - V5_6_5_SNAPSHOT, V5_6_5, - V5_6_6_SNAPSHOT, V5_6_6, - V5_6_7_SNAPSHOT, V5_6_7, - V5_6_8_SNAPSHOT, V5_6_8, - V5_6_9_SNAPSHOT, V5_6_9, - V5_7_0_SNAPSHOT, V5_7_0, - V5_7_1_SNAPSHOT, V5_7_1, - V5_7_2_SNAPSHOT, V5_7_2, - V5_7_3_SNAPSHOT, V5_7_3, - V5_7_4_SNAPSHOT, V5_7_4, - V5_7_5_SNAPSHOT, V5_7_5, - V5_7_6_SNAPSHOT, V5_7_6, - V5_7_7_SNAPSHOT, V5_7_7, - V5_7_8_SNAPSHOT, V5_7_8, - V5_7_9_SNAPSHOT, V5_7_9, - V5_8_0_SNAPSHOT, V5_8_0, - V5_8_1_SNAPSHOT, V5_8_1, - V5_8_2_SNAPSHOT, V5_8_2, - V5_8_3_SNAPSHOT, V5_8_3, - V5_8_4_SNAPSHOT, V5_8_4, - V5_8_5_SNAPSHOT, V5_8_5, - V5_8_6_SNAPSHOT, V5_8_6, - V5_8_7_SNAPSHOT, V5_8_7, - V5_8_8_SNAPSHOT, V5_8_8, - V5_8_9_SNAPSHOT, V5_8_9, - V5_9_0_SNAPSHOT, V5_9_0, - V5_9_1_SNAPSHOT, V5_9_1, - V5_9_2_SNAPSHOT, V5_9_2, - V5_9_3_SNAPSHOT, V5_9_3, - V5_9_4_SNAPSHOT, V5_9_4, - V5_9_5_SNAPSHOT, V5_9_5, - V5_9_6_SNAPSHOT, V5_9_6, - V5_9_7_SNAPSHOT, V5_9_7, - V5_9_8_SNAPSHOT, V5_9_8, - V5_9_9_SNAPSHOT, V5_9_9, - HIGHER_VERSION }; + static const int s_CurrentVersion; + static const std::string s_CurrentLanguage; + static const char* GetVersionDesc(int value); - static int s_CurrentVersion; - static std::string s_CurrentLanguage; }; } // namespace rocketmq diff --git a/src/common/MemoryInputStream.h b/src/common/MemoryInputStream.h index c6f94e4ef..2097ec6df 100644 --- a/src/common/MemoryInputStream.h +++ b/src/common/MemoryInputStream.h @@ -14,12 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef MEMORYINPUTSTREAM_H_INCLUDED -#define MEMORYINPUTSTREAM_H_INCLUDED +#ifndef __MEMORY_INTPUT_STREAM_H__ +#define __MEMORY_INTPUT_STREAM_H__ #include "InputStream.h" namespace rocketmq { + //============================================================================== /** Allows a block of data to be accessed as a stream. @@ -91,5 +92,7 @@ class ROCKETMQCLIENT_API MemoryInputStream : public InputStream { void createInternalCopy(); }; + } // namespace rocketmq -#endif + +#endif // __MEMORY_INTPUT_STREAM_H__ diff --git a/src/common/MemoryOutputStream.cpp b/src/common/MemoryOutputStream.cpp index f51444dc3..1c4f4da41 100644 --- a/src/common/MemoryOutputStream.cpp +++ b/src/common/MemoryOutputStream.cpp @@ -99,7 +99,7 @@ bool MemoryOutputStream::write(const void* const buffer, size_t howMany) { return false; } -bool MemoryOutputStream::writeRepeatedByte(uint8 byte, size_t howMany) { +bool MemoryOutputStream::writeRepeatedByte(uint8_t byte, size_t howMany) { if (howMany == 0) { return true; } @@ -121,8 +121,8 @@ const void* MemoryOutputStream::getData() const { return externalData; } - if ((unsigned int)poolToUse->getSize() > size) { - static_cast(poolToUse->getData())[size] = 0; + if (poolToUse->getSize() > size) { + poolToUse->getData()[size] = 0; } return poolToUse->getData(); diff --git a/src/common/MemoryOutputStream.h b/src/common/MemoryOutputStream.h index 6b24e3063..ece1a19a8 100644 --- a/src/common/MemoryOutputStream.h +++ b/src/common/MemoryOutputStream.h @@ -14,12 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef MEMORYOUTPUTSTREAM_H_INCLUDED -#define MEMORYOUTPUTSTREAM_H_INCLUDED +#ifndef __MEMORY_OUTPUT_STREAM_H__ +#define __MEMORY_OUTPUT_STREAM_H__ #include "OutputStream.h" namespace rocketmq { + //============================================================================== /** Writes data to an internal memory buffer, which grows as required. @@ -109,7 +110,7 @@ class ROCKETMQCLIENT_API MemoryOutputStream : public OutputStream { int64_t getPosition() { return (int64_t)position; } bool setPosition(int64_t); int64_t writeFromInputStream(InputStream&, int64_t maxNumBytesToWrite); - bool writeRepeatedByte(uint8 byte, size_t numTimesToRepeat); + bool writeRepeatedByte(uint8_t byte, size_t numTimesToRepeat); private: //============================================================================== @@ -125,5 +126,7 @@ class ROCKETMQCLIENT_API MemoryOutputStream : public OutputStream { /** 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 + +#endif // __MEMORY_OUTPUT_STREAM_H__ diff --git a/src/common/NamesrvConfig.h b/src/common/NamesrvConfig.h index 0276f5391..e74a6b35e 100644 --- a/src/common/NamesrvConfig.h +++ b/src/common/NamesrvConfig.h @@ -17,8 +17,8 @@ #ifndef __NAMESRV_CONFIG_H__ #define __NAMESRV_CONFIG_H__ -#include #include + #include "UtilAll.h" namespace rocketmq { @@ -32,17 +32,17 @@ class NamesrvConfig { } } - const string& getRocketmqHome() const { return m_rocketmqHome; } + const std::string& getRocketmqHome() const { return m_rocketmqHome; } - void setRocketmqHome(const string& rocketmqHome) { m_rocketmqHome = rocketmqHome; } + void setRocketmqHome(const std::string& rocketmqHome) { m_rocketmqHome = rocketmqHome; } - const string& getKvConfigPath() const { return m_kvConfigPath; } + const std::string& getKvConfigPath() const { return m_kvConfigPath; } - void setKvConfigPath(const string& kvConfigPath) { m_kvConfigPath = kvConfigPath; } + void setKvConfigPath(const std::string& kvConfigPath) { m_kvConfigPath = kvConfigPath; } private: - string m_rocketmqHome; - string m_kvConfigPath; + std::string m_rocketmqHome; + std::string m_kvConfigPath; }; } // namespace rocketmq diff --git a/src/common/OutputStream.cpp b/src/common/OutputStream.cpp index 49162ce3e..4a9501330 100644 --- a/src/common/OutputStream.cpp +++ b/src/common/OutputStream.cpp @@ -36,7 +36,7 @@ bool OutputStream::writeByte(char byte) { return write(&byte, 1); } -bool OutputStream::writeRepeatedByte(uint8 byte, size_t numTimesToRepeat) { +bool OutputStream::writeRepeatedByte(uint8_t byte, size_t numTimesToRepeat) { for (size_t i = 0; i < numTimesToRepeat; ++i) if (!writeByte((char)byte)) return false; diff --git a/src/common/OutputStream.h b/src/common/OutputStream.h index a6b2c26ba..46378a2f3 100644 --- a/src/common/OutputStream.h +++ b/src/common/OutputStream.h @@ -14,11 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef OUTPUTSTREAM_H_INCLUDED -#define OUTPUTSTREAM_H_INCLUDED +#ifndef __OUTPUT_STREAM_H__ +#define __OUTPUT_STREAM_H__ #include "InputStream.h" + namespace rocketmq { + //============================================================================== /** The base class for streams that write data to some kind of destination. @@ -128,7 +130,7 @@ class ROCKETMQCLIENT_API OutputStream { /** 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); + virtual bool writeRepeatedByte(uint8_t byte, size_t numTimesToRepeat); /** Reads data from an input stream and writes it to this stream. @@ -142,6 +144,7 @@ class ROCKETMQCLIENT_API OutputStream { */ virtual int64_t writeFromInputStream(InputStream& source, int64_t maxNumBytesToWrite); }; + } // namespace rocketmq -#endif // OUTPUTSTREAM_H_INCLUDED +#endif // __OUTPUT_STREAM_H__ diff --git a/src/common/SendCallbackWrap.cpp b/src/common/SendCallbackWrap.cpp index 66bf51ac8..4df888365 100755 --- a/src/common/SendCallbackWrap.cpp +++ b/src/common/SendCallbackWrap.cpp @@ -18,7 +18,6 @@ #include -#include "CommandHeader.h" #include "DefaultMQProducer.h" #include "Logging.h" #include "MQClientAPIImpl.h" @@ -29,6 +28,7 @@ #include "PullAPIWrapper.h" #include "PullResultExt.h" #include "TopicPublishInfo.h" +#include "protocol/header/CommandHeader.h" namespace rocketmq { @@ -60,7 +60,7 @@ void SendCallbackWrap::operationComplete(ResponseFuture* responseFuture) noexcep m_sendCallback->onException(exception); // auto delete callback - if (m_sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_ATUO_DELETE) { + if (m_sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { deleteAndZero(m_sendCallback); } return; @@ -107,7 +107,7 @@ void SendCallbackWrap::operationComplete(ResponseFuture* responseFuture) noexcep false); // auto delete callback - if (m_sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_ATUO_DELETE) { + if (m_sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { deleteAndZero(m_sendCallback); } } catch (MQException& e) { @@ -140,7 +140,7 @@ void SendCallbackWrap::onExceptionImpl(ResponseFuture* responseFuture, m_sendCallback->onException(exception); // auto delete callback - if (m_sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_ATUO_DELETE) { + if (m_sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { deleteAndZero(m_sendCallback); } return; @@ -184,7 +184,7 @@ void SendCallbackWrap::onExceptionImpl(ResponseFuture* responseFuture, m_sendCallback->onException(e); // auto delete callback - if (m_sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_ATUO_DELETE) { + if (m_sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { deleteAndZero(m_sendCallback); } } diff --git a/src/common/SubscriptionData.h b/src/common/SubscriptionData.h index 85ba26156..9db58d905 100644 --- a/src/common/SubscriptionData.h +++ b/src/common/SubscriptionData.h @@ -17,11 +17,11 @@ #ifndef __SUBSCRIPTION_DATA_H__ #define __SUBSCRIPTION_DATA_H__ +#include + #include #include -#include - #include "RocketMQClient.h" namespace rocketmq { @@ -51,9 +51,11 @@ class ROCKETMQCLIENT_API SubscriptionData { bool containTag(const std::string& tag); std::vector& getTagsSet(); - void putCodeSet(const int32 code); + void putCodeSet(int32_t code); bool operator==(const SubscriptionData& other) const; + bool operator!=(const SubscriptionData& other) const { return !operator==(other); } + bool operator<(const SubscriptionData& other) const; Json::Value toJson() const; diff --git a/src/common/TopicConfig.cpp b/src/common/TopicConfig.cpp index a08659b0c..3a7a19655 100644 --- a/src/common/TopicConfig.cpp +++ b/src/common/TopicConfig.cpp @@ -16,7 +16,6 @@ */ #include "TopicConfig.h" -#include #include #include "PermName.h" @@ -52,6 +51,7 @@ TopicConfig::~TopicConfig() {} std::string TopicConfig::encode() { std::stringstream ss; + ss << m_topicName << SEPARATOR << m_readQueueNums << SEPARATOR << m_writeQueueNums << SEPARATOR << m_perm << SEPARATOR << m_topicFilterType; diff --git a/src/common/UtilAll.cpp b/src/common/UtilAll.cpp index 74a769c4d..4333ecdae 100644 --- a/src/common/UtilAll.cpp +++ b/src/common/UtilAll.cpp @@ -59,7 +59,7 @@ bool UtilAll::try_lock_for(std::timed_mutex& mutex, long timeout) { int32_t UtilAll::HashCode(const std::string& str) { // FIXME: don't equal to String#hashCode in Java - int32 h = 0; + int32_t h = 0; if (!str.empty()) { for (const auto& c : str) { h = 31 * h + c; @@ -114,6 +114,10 @@ std::string UtilAll::getRetryTopic(const std::string& consumerGroup) { return RETRY_GROUP_TOPIC_PREFIX + consumerGroup; } +std::string UtilAll::getReplyTopic(const std::string& clusterName) { + return clusterName + "_" + REPLY_TOPIC_POSTFIX; +} + void UtilAll::Trim(std::string& str) { str.erase(0, str.find_first_not_of(' ')); // prefixing spaces str.erase(str.find_last_not_of(' ') + 1); // surfixing spaces @@ -221,7 +225,7 @@ std::string UtilAll::getLocalAddress() { auto hostname = getLocalHostName(); if (!hostname.empty()) { try { - s_localIpAddress = lookupNameServers(hostname); + s_localIpAddress = socketAddress2String(lookupNameServers(hostname)); } catch (std::exception& e) { LOG_WARN(e.what()); s_localIpAddress = "127.0.0.1"; diff --git a/src/common/UtilAll.h b/src/common/UtilAll.h index 63042a947..2e2c34f0e 100644 --- a/src/common/UtilAll.h +++ b/src/common/UtilAll.h @@ -17,6 +17,7 @@ #ifndef __UTIL_ALL_H__ #define __UTIL_ALL_H__ +#include #include #include #include @@ -39,6 +40,8 @@ const std::string CLIENT_INNER_PRODUCER_GROUP = "CLIENT_INNER_PRODUCER"; const std::string SELF_TEST_TOPIC = "SELF_TEST_TOPIC"; const std::string RETRY_GROUP_TOPIC_PREFIX = "%RETRY%"; const std::string DLQ_GROUP_TOPIC_PREFIX = "%DLQ%"; +const std::string REPLY_TOPIC_POSTFIX = "REPLY_TOPIC"; +const std::string REPLY_MESSAGE_FLAG = "reply"; const std::string ROCKETMQ_HOME_PROPERTY = "rocketmq.home.dir"; const std::string MESSAGE_COMPRESS_LEVEL = "rocketmq.message.compressLevel"; @@ -96,6 +99,7 @@ class UtilAll { static bool isRetryTopic(const std::string& topic); static std::string getRetryTopic(const std::string& consumerGroup); + static std::string getReplyTopic(const std::string& clusterName); static void Trim(std::string& str); static bool isBlank(const std::string& str); diff --git a/src/common/Validators.cpp b/src/common/Validators.cpp index 138417239..c293aa4ea 100644 --- a/src/common/Validators.cpp +++ b/src/common/Validators.cpp @@ -16,8 +16,7 @@ */ #include "Validators.h" -#include -#include +#include #include "MQProtos.h" #include "UtilAll.h" @@ -36,19 +35,30 @@ bool Validators::regularExpressionMatcher(const std::string& origin, const std:: return true; } - // Pattern pattern = Pattern.compile(patternStr); - // Matcher matcher = pattern.matcher(origin); - - // return matcher.matches(); +#if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ <= 8)) return true; +#else + const std::regex regex(patternStr, std::regex::extended); + return std::regex_match(origin, regex); +#endif } std::string Validators::getGroupWithRegularExpression(const std::string& origin, const std::string& patternStr) { - /*Pattern pattern = Pattern.compile(patternStr); - Matcher matcher = pattern.matcher(origin); - while (matcher.find()) { - return matcher.group(0); - }*/ + if (!UtilAll::isBlank(patternStr)) { +#if !defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 8) + const std::regex regex(patternStr, std::regex::extended); + std::smatch match; + + if (std::regex_match(origin, match, regex)) { + // The first sub_match is the whole string; the next + // sub_match is the first parenthesized expression. + if (match.size() == 2) { + std::ssub_match base_sub_match = match[1]; + return base_sub_match.str(); + } + } +#endif + } return ""; } diff --git a/src/concurrent/concurrent_queue.hpp b/src/concurrent/concurrent_queue.hpp index 1a844e895..5a67e8f17 100644 --- a/src/concurrent/concurrent_queue.hpp +++ b/src/concurrent/concurrent_queue.hpp @@ -56,9 +56,19 @@ class concurrent_queue { typedef T value_type; typedef concurrent_queue_node node_type; - ~concurrent_queue() { delete[](char*) sentinel; } + ~concurrent_queue() { + // clear this queue + while (_clear_when_destruct) { + if (nullptr == pop_front()) { + break; + } + } + + delete[](char*) sentinel; + } - concurrent_queue() : sentinel((node_type*)new char[sizeof(node_type)]) { + concurrent_queue(bool clear_when_destruct = true) + : sentinel((node_type*)new char[sizeof(node_type)]), _clear_when_destruct(clear_when_destruct) { sentinel->next_ = sentinel; head_ = tail_ = sentinel; } @@ -136,6 +146,7 @@ class concurrent_queue { std::atomic head_, tail_; node_type* const sentinel; + bool _clear_when_destruct; }; } // namespace rocketmq diff --git a/src/concurrent/executor.hpp b/src/concurrent/executor.hpp index 06c62b5d4..3ed5ad5fb 100644 --- a/src/concurrent/executor.hpp +++ b/src/concurrent/executor.hpp @@ -69,7 +69,7 @@ class executor { class executor_service : virtual public executor { public: - virtual void shutdown() = 0; + virtual void shutdown(bool immediately) = 0; virtual bool is_shutdown() = 0; virtual std::future submit(const handler_type& task) = 0; }; diff --git a/src/concurrent/executor_impl.hpp b/src/concurrent/executor_impl.hpp index b4b94720e..0c0a0cb2b 100644 --- a/src/concurrent/executor_impl.hpp +++ b/src/concurrent/executor_impl.hpp @@ -61,11 +61,12 @@ class thread_pool_executor : public abstract_executor_service { } } - void shutdown() override { + void shutdown(bool immediately = true) override { if (state_ == RUNNING) { - state_ = STOP; + state_ = immediately ? STOP : SHUTDOWN; wakeup_event_.notify_all(); thread_group_.join(); + state_ = STOP; } } @@ -206,7 +207,7 @@ class scheduled_thread_pool_executor : public thread_pool_executor, virtual publ } } - void shutdown() override { + void shutdown(bool immediately = true) override { if (!stopped_) { stopped_ = true; @@ -214,7 +215,7 @@ class scheduled_thread_pool_executor : public thread_pool_executor, virtual publ timer_thread_.join(); if (!single_thread_) { - thread_pool_executor::shutdown(); + thread_pool_executor::shutdown(immediately); } } } diff --git a/src/consumer/AllocateMQAveragely.h b/src/consumer/AllocateMQAveragely.h index 6fe0ff75e..d0acc2027 100644 --- a/src/consumer/AllocateMQAveragely.h +++ b/src/consumer/AllocateMQAveragely.h @@ -21,18 +21,19 @@ #include "AllocateMQStrategy.h" #include "Logging.h" +#include "MQClientException.h" namespace rocketmq { class AllocateMQAveragely : public AllocateMQStrategy { public: - void allocate(const std::string& currentCID, + void allocate(const std::string& currentCid, std::vector& mqAll, std::vector& cidAll, std::vector& outReuslt) override { outReuslt.clear(); - if (currentCID.empty()) { + if (currentCid.empty()) { THROW_MQEXCEPTION(MQClientException, "currentCID is empty", -1); } @@ -47,7 +48,7 @@ class AllocateMQAveragely : public AllocateMQStrategy { int index = -1; int cidAllSize = cidAll.size(); for (int i = 0; i < cidAllSize; i++) { - if (cidAll[i] == currentCID) { + if (cidAll[i] == currentCid) { index = i; break; } diff --git a/src/consumer/ConsumeMessageConcurrentlyService.cpp b/src/consumer/ConsumeMessageConcurrentlyService.cpp index 5f7d7e881..26063e574 100755 --- a/src/consumer/ConsumeMessageConcurrentlyService.cpp +++ b/src/consumer/ConsumeMessageConcurrentlyService.cpp @@ -35,9 +35,11 @@ ConsumeMessageConcurrentlyService::~ConsumeMessageConcurrentlyService() = defaul void ConsumeMessageConcurrentlyService::start() { // start callback threadpool m_consumeExecutor.startup(); + m_scheduledExecutorService.startup(); } void ConsumeMessageConcurrentlyService::shutdown() { + m_scheduledExecutorService.shutdown(); m_consumeExecutor.shutdown(); } @@ -86,64 +88,69 @@ void ConsumeMessageConcurrentlyService::ConsumeRequest(std::vectorconsumeMessage(msgs); - } catch (std::exception& e) { - // ... + } catch (const std::exception& e) { + LOG_WARN_NEW("encounter unexpected exception when consume messages.\n{}", e.what()); } + if (processQueue->isDropped()) { + LOG_WARN_NEW("processQueue is dropped without process consume result. messageQueue={}", messageQueue.toString()); + return; + } + + // // processConsumeResult - if (!processQueue->isDropped()) { - int ackIndex = -1; - switch (status) { - case CONSUME_SUCCESS: - ackIndex = msgs.size() - 1; - break; - case RECONSUME_LATER: - ackIndex = -1; - break; - default: - break; - } - switch (m_consumer->messageModel()) { - case BROADCASTING: - // Note: broadcasting reconsume should do by application, as it has big affect to broker cluster - for (size_t i = ackIndex + 1; i < msgs.size(); i++) { - const auto& msg = msgs[i]; - LOG_WARN_NEW("BROADCASTING, the message consume failed, drop it, {}", msg->toString()); - } - break; - case CLUSTERING: { - // send back msg to broker - std::vector msgBackFailed; - int idx = ackIndex + 1; - for (auto iter = msgs.begin() + idx; iter != msgs.end(); idx++) { - LOG_WARN_NEW("consume fail, MQ is:{}, its msgId is:{}, index is:{}, reconsume times is:{}", - messageQueue.toString(), (*iter)->getMsgId(), idx, (*iter)->getReconsumeTimes()); - auto& msg = (*iter); - bool result = m_consumer->sendMessageBack(*msg, 0, messageQueue.getBrokerName()); - if (!result) { - msg->setReconsumeTimes(msg->getReconsumeTimes() + 1); - msgBackFailed.push_back(msg); - iter = msgs.erase(iter); - } else { - iter++; - } - } + int ackIndex = -1; + switch (status) { + case CONSUME_SUCCESS: + ackIndex = msgs.size() - 1; + break; + case RECONSUME_LATER: + ackIndex = -1; + break; + default: + break; + } - if (!msgBackFailed.empty()) { - // send back failed, reconsume later - submitConsumeRequestLater(msgBackFailed, processQueue, messageQueue); + switch (m_consumer->messageModel()) { + case BROADCASTING: + // Note: broadcasting reconsume should do by application, as it has big affect to broker cluster + for (size_t i = ackIndex + 1; i < msgs.size(); i++) { + const auto& msg = msgs[i]; + LOG_WARN_NEW("BROADCASTING, the message consume failed, drop it, {}", msg->toString()); + } + break; + case CLUSTERING: { + // send back msg to broker + std::vector msgBackFailed; + int idx = ackIndex + 1; + for (auto iter = msgs.begin() + idx; iter != msgs.end(); idx++) { + LOG_WARN_NEW("consume fail, MQ is:{}, its msgId is:{}, index is:{}, reconsume times is:{}", + messageQueue.toString(), (*iter)->getMsgId(), idx, (*iter)->getReconsumeTimes()); + auto& msg = (*iter); + bool result = m_consumer->sendMessageBack(*msg, 0, messageQueue.getBrokerName()); + if (!result) { + msg->setReconsumeTimes(msg->getReconsumeTimes() + 1); + msgBackFailed.push_back(msg); + iter = msgs.erase(iter); + } else { + iter++; } - } break; - default: - break; - } + } - // update offset - int64_t offset = processQueue->removeMessage(msgs); - if (offset >= 0 && !processQueue->isDropped()) { - m_consumer->getOffsetStore()->updateOffset(messageQueue, offset, true); - } + if (!msgBackFailed.empty()) { + // send back failed, reconsume later + submitConsumeRequestLater(msgBackFailed, processQueue, messageQueue); + } + } break; + default: + break; + } + + // update offset + int64_t offset = processQueue->removeMessage(msgs); + if (offset >= 0 && !processQueue->isDropped()) { + m_consumer->getOffsetStore()->updateOffset(messageQueue, offset, true); } } diff --git a/src/consumer/ConsumeMessageOrderlyService.cpp b/src/consumer/ConsumeMessageOrderlyService.cpp index 449281b80..9411666d0 100755 --- a/src/consumer/ConsumeMessageOrderlyService.cpp +++ b/src/consumer/ConsumeMessageOrderlyService.cpp @@ -159,8 +159,8 @@ void ConsumeMessageOrderlyService::ConsumeRequest(ProcessQueuePtr processQueue, } status = m_messageListener->consumeMessage(msgs); - } catch (std::exception& e) { - // ... + } catch (const std::exception& e) { + LOG_WARN_NEW("encounter unexpected exception when consume messages.\n{}", e.what()); } // processConsumeResult diff --git a/src/consumer/DefaultMQPullConsumer.cpp b/src/consumer/DefaultMQPullConsumer.cpp index 295e73da4..4512a381c 100644 --- a/src/consumer/DefaultMQPullConsumer.cpp +++ b/src/consumer/DefaultMQPullConsumer.cpp @@ -16,17 +16,15 @@ */ #include "DefaultMQPullConsumer.h" -#include "AllocateMQAveragely.h" #include "UtilAll.h" namespace rocketmq { -DefaultMQPullConsumerConfig::DefaultMQPullConsumerConfig() : m_allocateMQStrategy(new AllocateMQAveragely()) {} - DefaultMQPullConsumer::DefaultMQPullConsumer(const std::string& groupname) : DefaultMQPullConsumer(groupname, nullptr) {} -DefaultMQPullConsumer::DefaultMQPullConsumer(const std::string& groupname, std::shared_ptr rpcHook) { +DefaultMQPullConsumer::DefaultMQPullConsumer(const std::string& groupname, RPCHookPtr rpcHook) + : DefaultMQPullConsumerConfigProxy(nullptr), m_pullConsumerDelegate(nullptr) { // set default group name if (groupname.empty()) { setGroupName(DEFAULT_CONSUMER_GROUP); @@ -105,7 +103,7 @@ void DefaultMQPullConsumer::fetchMessageQueuesInBalance(const std::string& topic m_pullConsumerDelegate->fetchMessageQueuesInBalance(topic, mqs); } -void DefaultMQPullConsumer::setRPCHook(std::shared_ptr rpcHook) { +void DefaultMQPullConsumer::setRPCHook(RPCHookPtr rpcHook) { // dynamic_cast(m_pullConsumerDelegate.get())->setRPCHook(rpcHook); } diff --git a/src/consumer/DefaultMQPullConsumerImpl.cpp b/src/consumer/DefaultMQPullConsumerImpl.cpp index c9eea3872..e72defd01 100644 --- a/src/consumer/DefaultMQPullConsumerImpl.cpp +++ b/src/consumer/DefaultMQPullConsumerImpl.cpp @@ -39,7 +39,7 @@ // DefaultMQPullConsumer::DefaultMQPullConsumer(const string& groupname) : DefaultMQPullConsumer(groupname, nullptr) {} -// DefaultMQPullConsumer::DefaultMQPullConsumer(const string& groupname, std::shared_ptr rpcHook) +// DefaultMQPullConsumer::DefaultMQPullConsumer(const string& groupname, RPCHookPtr rpcHook) // : MQClient(rpcHook), // m_rebalanceImpl(new RebalancePullImpl(this)), // m_pullAPIWrapper(nullptr), @@ -318,7 +318,8 @@ // } // } -// void DefaultMQPullConsumer::fetchMessageQueuesInBalance(const std::string& topic, std::vector& mqs) {} +// void DefaultMQPullConsumer::fetchMessageQueuesInBalance(const std::string& topic, std::vector& mqs) +// {} // void DefaultMQPullConsumer::checkConfig() { // string groupname = getGroupName(); diff --git a/src/consumer/DefaultMQPushConsumer.cpp b/src/consumer/DefaultMQPushConsumer.cpp index 4116b4175..0d717fd9e 100644 --- a/src/consumer/DefaultMQPushConsumer.cpp +++ b/src/consumer/DefaultMQPushConsumer.cpp @@ -16,27 +16,18 @@ */ #include "DefaultMQPushConsumer.h" -#include "AllocateMQAveragely.h" +#include "DefaultMQPushConsumerConfigImpl.h" #include "DefaultMQPushConsumerImpl.h" #include "UtilAll.h" namespace rocketmq { -DefaultMQPushConsumerConfig::DefaultMQPushConsumerConfig() - : m_consumeFromWhere(CONSUME_FROM_LAST_OFFSET), - m_consumeTimestamp("0"), - m_consumeThreadNum(std::min(8, (int)std::thread::hardware_concurrency())), - m_consumeMessageBatchMaxSize(1), - m_maxMsgCacheSize(1000), - m_asyncPullTimeout(30 * 1000), - m_maxReconsumeTimes(-1), - m_allocateMQStrategy(new AllocateMQAveragely()) {} - DefaultMQPushConsumer::DefaultMQPushConsumer(const std::string& groupname) : DefaultMQPushConsumer(groupname, nullptr) {} -DefaultMQPushConsumer::DefaultMQPushConsumer(const std::string& groupname, std::shared_ptr rpcHook) - : m_pushConsumerDelegate(nullptr) { +DefaultMQPushConsumer::DefaultMQPushConsumer(const std::string& groupname, RPCHookPtr rpcHook) + : DefaultMQPushConsumerConfigProxy(std::make_shared()), + m_pushConsumerDelegate(nullptr) { // set default group name if (groupname.empty()) { setGroupName(DEFAULT_CONSUMER_GROUP); @@ -44,7 +35,7 @@ DefaultMQPushConsumer::DefaultMQPushConsumer(const std::string& groupname, std:: setGroupName(groupname); } - m_pushConsumerDelegate = DefaultMQPushConsumerImpl::create(this, rpcHook); + m_pushConsumerDelegate = DefaultMQPushConsumerImpl::create(getRealConfig(), rpcHook); } DefaultMQPushConsumer::~DefaultMQPushConsumer() = default; @@ -81,6 +72,10 @@ void DefaultMQPushConsumer::registerMessageListener(MessageListenerOrderly* mess m_pushConsumerDelegate->registerMessageListener(messageListener); } +MQMessageListener* DefaultMQPushConsumer::getMessageListener() const { + return m_pushConsumerDelegate->getMessageListener(); +} + void DefaultMQPushConsumer::subscribe(const std::string& topic, const std::string& subExpression) { m_pushConsumerDelegate->subscribe(topic, subExpression); } @@ -93,8 +88,8 @@ void DefaultMQPushConsumer::resume() { m_pushConsumerDelegate->resume(); } -void DefaultMQPushConsumer::setRPCHook(std::shared_ptr rpcHook) { - dynamic_cast(m_pushConsumerDelegate.get())->setRPCHook(rpcHook); +void DefaultMQPushConsumer::setRPCHook(RPCHookPtr rpcHook) { + std::dynamic_pointer_cast(m_pushConsumerDelegate)->setRPCHook(rpcHook); } } // namespace rocketmq diff --git a/src/consumer/DefaultMQPushConsumerConfigImpl.cpp b/src/consumer/DefaultMQPushConsumerConfigImpl.cpp new file mode 100644 index 000000000..560a6be02 --- /dev/null +++ b/src/consumer/DefaultMQPushConsumerConfigImpl.cpp @@ -0,0 +1,125 @@ + +/* + * 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 "DefaultMQPushConsumerConfigImpl.h" + +#include +#include + +#include "AllocateMQAveragely.h" + +namespace rocketmq { + +DefaultMQPushConsumerConfigImpl::DefaultMQPushConsumerConfigImpl() + : m_messageModel(CLUSTERING), + m_consumeFromWhere(CONSUME_FROM_LAST_OFFSET), + m_consumeTimestamp("0"), + m_consumeThreadNum(std::min(8, (int)std::thread::hardware_concurrency())), + m_consumeMessageBatchMaxSize(1), + m_maxMsgCacheSize(1000), + m_asyncPullTimeout(30 * 1000), + m_maxReconsumeTimes(-1), + m_pullTimeDelayMillsWhenException(3000), + m_allocateMQStrategy(new AllocateMQAveragely()) {} + +MessageModel DefaultMQPushConsumerConfigImpl::getMessageModel() const { + return m_messageModel; +} + +void DefaultMQPushConsumerConfigImpl::setMessageModel(MessageModel messageModel) { + m_messageModel = messageModel; +} + +ConsumeFromWhere DefaultMQPushConsumerConfigImpl::getConsumeFromWhere() const { + return m_consumeFromWhere; +} + +void DefaultMQPushConsumerConfigImpl::setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) { + m_consumeFromWhere = consumeFromWhere; +} + +std::string DefaultMQPushConsumerConfigImpl::getConsumeTimestamp() { + return m_consumeTimestamp; +} + +void DefaultMQPushConsumerConfigImpl::setConsumeTimestamp(std::string consumeTimestamp) { + m_consumeTimestamp = consumeTimestamp; +} + +int DefaultMQPushConsumerConfigImpl::getConsumeThreadNum() const { + return m_consumeThreadNum; +} + +void DefaultMQPushConsumerConfigImpl::setConsumeThreadNum(int threadNum) { + if (threadNum > 0) { + m_consumeThreadNum = threadNum; + } +} + +int DefaultMQPushConsumerConfigImpl::getConsumeMessageBatchMaxSize() const { + return m_consumeMessageBatchMaxSize; +} + +void DefaultMQPushConsumerConfigImpl::setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) { + if (consumeMessageBatchMaxSize >= 1) { + m_consumeMessageBatchMaxSize = consumeMessageBatchMaxSize; + } +} + +int DefaultMQPushConsumerConfigImpl::getMaxCacheMsgSizePerQueue() const { + return m_maxMsgCacheSize; +} + +void DefaultMQPushConsumerConfigImpl::setMaxCacheMsgSizePerQueue(int maxCacheSize) { + if (maxCacheSize > 0 && maxCacheSize < 65535) { + m_maxMsgCacheSize = maxCacheSize; + } +} + +int DefaultMQPushConsumerConfigImpl::getAsyncPullTimeout() const { + return m_asyncPullTimeout; +} + +void DefaultMQPushConsumerConfigImpl::setAsyncPullTimeout(int asyncPullTimeout) { + m_asyncPullTimeout = asyncPullTimeout; +} + +int DefaultMQPushConsumerConfigImpl::getMaxReconsumeTimes() const { + return m_maxReconsumeTimes; +} + +void DefaultMQPushConsumerConfigImpl::setMaxReconsumeTimes(int maxReconsumeTimes) { + m_maxReconsumeTimes = maxReconsumeTimes; +} + +long DefaultMQPushConsumerConfigImpl::getPullTimeDelayMillsWhenException() const { + return m_pullTimeDelayMillsWhenException; +} + +void DefaultMQPushConsumerConfigImpl::setPullTimeDelayMillsWhenException(long pullTimeDelayMillsWhenException) { + m_pullTimeDelayMillsWhenException = pullTimeDelayMillsWhenException; +} + +AllocateMQStrategy* DefaultMQPushConsumerConfigImpl::getAllocateMQStrategy() const { + return m_allocateMQStrategy.get(); +} + +void DefaultMQPushConsumerConfigImpl::setAllocateMQStrategy(AllocateMQStrategy* strategy) { + m_allocateMQStrategy.reset(strategy); +} + +} // namespace rocketmq diff --git a/src/consumer/DefaultMQPushConsumerConfigImpl.h b/src/consumer/DefaultMQPushConsumerConfigImpl.h new file mode 100644 index 000000000..1ca601328 --- /dev/null +++ b/src/consumer/DefaultMQPushConsumerConfigImpl.h @@ -0,0 +1,81 @@ + +/* + * 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 __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_IMPL_H__ +#define __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_IMPL_H__ + +#include "DefaultMQPushConsumerConfig.h" +#include "MQClientConfigImpl.h" + +namespace rocketmq { + +class DefaultMQPushConsumerConfigImpl : virtual public DefaultMQPushConsumerConfig, public MQClientConfigImpl { + public: + DefaultMQPushConsumerConfigImpl(); + virtual ~DefaultMQPushConsumerConfigImpl() = default; + + MessageModel getMessageModel() const override; + void setMessageModel(MessageModel messageModel) override; + + ConsumeFromWhere getConsumeFromWhere() const override; + void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) override; + + std::string getConsumeTimestamp() override; + void setConsumeTimestamp(std::string consumeTimestamp) override; + + int getConsumeThreadNum() const override; + void setConsumeThreadNum(int threadNum) override; + + int getConsumeMessageBatchMaxSize() const override; + void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) override; + + int getMaxCacheMsgSizePerQueue() const override; + void setMaxCacheMsgSizePerQueue(int maxCacheSize) override; + + int getAsyncPullTimeout() const override; + void setAsyncPullTimeout(int asyncPullTimeout) override; + + int getMaxReconsumeTimes() const override; + void setMaxReconsumeTimes(int maxReconsumeTimes) override; + + long getPullTimeDelayMillsWhenException() const override; + void setPullTimeDelayMillsWhenException(long pullTimeDelayMillsWhenException) override; + + AllocateMQStrategy* getAllocateMQStrategy() const override; + void setAllocateMQStrategy(AllocateMQStrategy* strategy) override; + + protected: + MessageModel m_messageModel; + + ConsumeFromWhere m_consumeFromWhere; + std::string m_consumeTimestamp; + + int m_consumeThreadNum; + int m_consumeMessageBatchMaxSize; + int m_maxMsgCacheSize; + + int m_asyncPullTimeout; // 30s + int m_maxReconsumeTimes; + + long m_pullTimeDelayMillsWhenException; // 3000 + + std::unique_ptr m_allocateMQStrategy; +}; + +} // namespace rocketmq + +#endif // __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_IMPL_H__ \ No newline at end of file diff --git a/src/consumer/DefaultMQPushConsumerImpl.cpp b/src/consumer/DefaultMQPushConsumerImpl.cpp index 80e214f78..40630f3f3 100644 --- a/src/consumer/DefaultMQPushConsumerImpl.cpp +++ b/src/consumer/DefaultMQPushConsumerImpl.cpp @@ -20,7 +20,6 @@ #include #endif -#include "AllocateMQAveragely.h" #include "CommunicationMode.h" #include "ConsumeMsgService.h" #include "ConsumerRunningInfo.h" @@ -33,7 +32,7 @@ #include "MQProtos.h" #include "OffsetStore.h" #include "PullAPIWrapper.h" -#include "PullMessageService.h" +#include "PullMessageService.hpp" #include "PullSysFlag.h" #include "RebalancePushImpl.h" #include "SocketUtil.h" @@ -95,6 +94,13 @@ class AsyncPullCallback : public AutoDeletePullCallback { defaultMQPushConsumer->correctTagsOffset(m_pullRequest); defaultMQPushConsumer->executePullRequestImmediately(m_pullRequest); break; + case NO_LATEST_MSG: + m_pullRequest->setNextOffset(result.nextBeginOffset); + defaultMQPushConsumer->correctTagsOffset(m_pullRequest); + defaultMQPushConsumer->executePullRequestLater( + m_pullRequest, + defaultMQPushConsumer->getDefaultMQPushConsumerConfig()->getPullTimeDelayMillsWhenException()); + break; case OFFSET_ILLEGAL: { LOG_WARN_NEW("the pull request offset illegal, {} {}", m_pullRequest->toString(), result.toString()); @@ -134,7 +140,9 @@ class AsyncPullCallback : public AutoDeletePullCallback { LOG_WARN_NEW("execute the pull request exception: {}", e.what()); } - defaultMQPushConsumer->executePullRequestLater(m_pullRequest, 3000); + // TODO + defaultMQPushConsumer->executePullRequestLater( + m_pullRequest, defaultMQPushConsumer->getDefaultMQPushConsumerConfig()->getPullTimeDelayMillsWhenException()); } private: @@ -143,11 +151,10 @@ class AsyncPullCallback : public AutoDeletePullCallback { SubscriptionDataPtr m_subscriptionData; }; -DefaultMQPushConsumerImpl::DefaultMQPushConsumerImpl(DefaultMQPushConsumerConfig* config) +DefaultMQPushConsumerImpl::DefaultMQPushConsumerImpl(DefaultMQPushConsumerConfigPtr config) : DefaultMQPushConsumerImpl(config, nullptr) {} -DefaultMQPushConsumerImpl::DefaultMQPushConsumerImpl(DefaultMQPushConsumerConfig* config, - std::shared_ptr rpcHook) +DefaultMQPushConsumerImpl::DefaultMQPushConsumerImpl(DefaultMQPushConsumerConfigPtr config, RPCHookPtr rpcHook) : MQClientImpl(config, rpcHook), m_pushConsumerConfig(config), m_startTime(UtilAll::currentTimeMillis()), @@ -176,13 +183,13 @@ bool DefaultMQPushConsumerImpl::sendMessageBack(MQMessageExt& msg, int delayLeve bool DefaultMQPushConsumerImpl::sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) { try { - std::string brokerAddr = brokerName.empty() ? socketAddress2IPPort(&msg.getStoreHost()) + std::string brokerAddr = brokerName.empty() ? socketAddress2String(msg.getStoreHost()) : m_clientInstance->findBrokerAddressInPublish(brokerName); m_clientInstance->getMQClientAPIImpl()->consumerSendMessageBack( brokerAddr, msg, m_pushConsumerConfig->getGroupName(), delayLevel, 5000, getMaxReconsumeTimes()); return true; - } catch (std::exception& e) { + } catch (const std::exception& e) { LOG_ERROR_NEW("sendMessageBack exception, group: {}, msg: {}. {}", m_pushConsumerConfig->getGroupName(), msg.toString(), e.what()); } @@ -243,14 +250,14 @@ void DefaultMQPushConsumerImpl::start() { m_pushConsumerConfig->changeInstanceNameToPID(); } - // ensure m_clientFactory + // ensure m_clientInstance MQClientImpl::start(); // reset rebalance m_rebalanceImpl->setConsumerGroup(m_pushConsumerConfig->getGroupName()); m_rebalanceImpl->setMessageModel(m_pushConsumerConfig->getMessageModel()); m_rebalanceImpl->setAllocateMQStrategy(m_pushConsumerConfig->getAllocateMQStrategy()); - m_rebalanceImpl->setMQClientFactory(m_clientInstance.get()); + m_rebalanceImpl->setClientInstance(m_clientInstance.get()); m_pullAPIWrapper.reset(new PullAPIWrapper(m_clientInstance.get(), m_pushConsumerConfig->getGroupName())); @@ -337,11 +344,15 @@ void DefaultMQPushConsumerImpl::registerMessageListener(MQMessageListener* messa } void DefaultMQPushConsumerImpl::registerMessageListener(MessageListenerConcurrently* messageListener) { - registerMessageListener((MQMessageListener*)messageListener); + registerMessageListener(static_cast(messageListener)); } void DefaultMQPushConsumerImpl::registerMessageListener(MessageListenerOrderly* messageListener) { - registerMessageListener((MQMessageListener*)messageListener); + registerMessageListener(static_cast(messageListener)); +} + +MQMessageListener* DefaultMQPushConsumerImpl::getMessageListener() const { + return m_messageListener; } void DefaultMQPushConsumerImpl::subscribe(const std::string& topic, const std::string& subExpression) { @@ -515,7 +526,7 @@ void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pullRequest) { pullRequest->setNextOffset(offset); } } else { - executePullRequestLater(pullRequest, 3000); + executePullRequestLater(pullRequest, m_pushConsumerConfig->getPullTimeDelayMillsWhenException()); LOG_INFO_NEW("pull message later because not locked in broker, {}", pullRequest->toString()); return; } @@ -524,7 +535,7 @@ void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pullRequest) { const auto& messageQueue = pullRequest->getMessageQueue(); SubscriptionDataPtr subscriptionData = m_rebalanceImpl->getSubscriptionData(messageQueue.getTopic()); if (nullptr == subscriptionData) { - executePullRequestLater(pullRequest, 3000); + executePullRequestLater(pullRequest, m_pushConsumerConfig->getPullTimeDelayMillsWhenException()); LOG_WARN_NEW("find the consumer's subscription failed, {}", pullRequest->toString()); return; } @@ -560,7 +571,7 @@ void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pullRequest) { callback); // 11 } catch (MQException& e) { LOG_ERROR_NEW("pullKernelImpl exception: {}", e.what()); - executePullRequestLater(pullRequest, 3000); + executePullRequestLater(pullRequest, m_pushConsumerConfig->getPullTimeDelayMillsWhenException()); } } diff --git a/src/consumer/DefaultMQPushConsumerImpl.h b/src/consumer/DefaultMQPushConsumerImpl.h index bd3a5909e..67f03efb9 100755 --- a/src/consumer/DefaultMQPushConsumerImpl.h +++ b/src/consumer/DefaultMQPushConsumerImpl.h @@ -44,7 +44,7 @@ class DefaultMQPushConsumerImpl : public std::enable_shared_from_this fetchLockObject(const MQMessageQueue& mq) { std::lock_guard lock(m_mqLockTableMutex); - if (m_mqLockTable.find(mq) == m_mqLockTable.end()) { - m_mqLockTable.emplace(mq, std::shared_ptr(new std::mutex())); + const auto& it = m_mqLockTable.find(mq); + if (it != m_mqLockTable.end()) { + return it->second; + } else { + return m_mqLockTable[mq] = std::make_shared(); } - return m_mqLockTable[mq]; } private: diff --git a/src/consumer/OffsetStore.cpp b/src/consumer/OffsetStore.cpp index d68cf2c0a..55305cf84 100644 --- a/src/consumer/OffsetStore.cpp +++ b/src/consumer/OffsetStore.cpp @@ -83,7 +83,7 @@ int64_t LocalFileOffsetStore::readOffset(const MQMessageQueue& mq, ReadOffsetTyp case MEMORY_FIRST_THEN_STORE: case READ_FROM_MEMORY: { std::lock_guard lock(m_lock); - auto it = m_offsetTable.find(mq); + const auto& it = m_offsetTable.find(mq); if (it != m_offsetTable.end()) { return it->second; } else if (READ_FROM_MEMORY == type) { @@ -93,7 +93,7 @@ int64_t LocalFileOffsetStore::readOffset(const MQMessageQueue& mq, ReadOffsetTyp case READ_FROM_STORE: { auto offsetTable = readLocalOffset(); if (!offsetTable.empty()) { - auto it = offsetTable.find(mq); + const auto& it = offsetTable.find(mq); if (it != offsetTable.end()) { auto offset = it->second; updateOffset(mq, offset, false); @@ -124,7 +124,7 @@ void LocalFileOffsetStore::persistAll(const std::vector& mqs) { Json::Value root(Json::objectValue); Json::Value jOffsetTable(Json::objectValue); for (const auto& mq : mqs) { - auto it = offsetTable.find(mq); + const auto& it = offsetTable.find(mq); if (it != offsetTable.end()) { std::string strMQ = RemotingSerializable::toJson(toJson(mq)); jOffsetTable[strMQ] = Json::Value((Json::Int64)it->second); @@ -184,7 +184,7 @@ std::map LocalFileOffsetStore::readLocalOffsetBak() { auto& offset = jOffsetTable[strMQ]; Json::Value jMQ = RemotingSerializable::fromJson(strMQ); MQMessageQueue mq(jMQ["topic"].asString(), jMQ["brokerName"].asString(), jMQ["queueId"].asInt()); - offsetTable.emplace(mq, offset.asInt64()); + offsetTable.emplace(std::move(mq), offset.asInt64()); } } catch (const std::exception& e) { LOG_WARN_NEW("readLocalOffset Exception {}", e.what()); @@ -211,12 +211,8 @@ void RemoteBrokerOffsetStore::load() {} void RemoteBrokerOffsetStore::updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) { std::lock_guard lock(m_lock); - auto it = m_offsetTable.find(mq); - if (it != m_offsetTable.end()) { - if (!increaseOnly || offset > it->second) { - it->second = offset; - } - } else { + const auto& it = m_offsetTable.find(mq); + if (it == m_offsetTable.end() || !increaseOnly || offset > it->second) { m_offsetTable[mq] = offset; } } @@ -227,7 +223,7 @@ int64_t RemoteBrokerOffsetStore::readOffset(const MQMessageQueue& mq, ReadOffset case READ_FROM_MEMORY: { std::lock_guard lock(m_lock); - auto it = m_offsetTable.find(mq); + const auto& it = m_offsetTable.find(mq); if (it != m_offsetTable.end()) { return it->second; } else if (READ_FROM_MEMORY == type) { @@ -261,7 +257,7 @@ void RemoteBrokerOffsetStore::persist(const MQMessageQueue& mq) { offsetTable = m_offsetTable; } - auto it = offsetTable.find(mq); + const auto& it = offsetTable.find(mq); if (it != offsetTable.end()) { try { updateConsumeOffsetToBroker(mq, it->second); @@ -275,8 +271,9 @@ void RemoteBrokerOffsetStore::persistAll(const std::vector& mq) void RemoteBrokerOffsetStore::removeOffset(const MQMessageQueue& mq) { std::lock_guard lock(m_lock); - if (m_offsetTable.find(mq) != m_offsetTable.end()) { - m_offsetTable.erase(mq); + const auto& it = m_offsetTable.find(mq); + if (it != m_offsetTable.end()) { + m_offsetTable.erase(it); } } diff --git a/src/consumer/ProcessQueue.cpp b/src/consumer/ProcessQueue.cpp index 79425d198..53554486c 100644 --- a/src/consumer/ProcessQueue.cpp +++ b/src/consumer/ProcessQueue.cpp @@ -58,7 +58,7 @@ void ProcessQueue::putMessage(std::vector& msgs) { } } - LOG_DEBUG("ProcessQueue: putMessage m_queueOffsetMax:%lld ", m_queueOffsetMax); + LOG_DEBUG_NEW("ProcessQueue: putMessage m_queueOffsetMax:{}", m_queueOffsetMax); } int64_t ProcessQueue::removeMessage(std::vector& msgs) { @@ -70,11 +70,10 @@ int64_t ProcessQueue::removeMessage(std::vector& msgs) { 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()); + LOG_DEBUG_NEW("offset result is:{}, m_queueOffsetMax is:{}, msgs size:{}", result, m_queueOffsetMax, msgs.size()); for (auto& msg : msgs) { - LOG_DEBUG("remove these msg from m_msgTreeMap, its offset:%lld", msg->getQueueOffset()); + LOG_DEBUG_NEW("remove these msg from m_msgTreeMap, its offset:{}", msg->getQueueOffset()); m_msgTreeMap.erase(msg->getQueueOffset()); } @@ -156,7 +155,7 @@ void ProcessQueue::clearAllMsgs() { std::lock_guard lock(m_lockTreeMap); if (isDropped()) { - LOG_DEBUG("clear m_msgTreeMap as PullRequest had been dropped."); + LOG_DEBUG_NEW("clear m_msgTreeMap as PullRequest had been dropped."); m_msgTreeMap.clear(); m_consumingMsgOrderlyTreeMap.clear(); m_queueOffsetMax = 0; diff --git a/src/consumer/PullAPIWrapper.cpp b/src/consumer/PullAPIWrapper.cpp index cd1b49dfb..7af5f8e87 100644 --- a/src/consumer/PullAPIWrapper.cpp +++ b/src/consumer/PullAPIWrapper.cpp @@ -42,8 +42,9 @@ void PullAPIWrapper::updatePullFromWhichNode(const MQMessageQueue& mq, int broke int PullAPIWrapper::recalculatePullFromWhichNode(const MQMessageQueue& mq) { std::lock_guard lock(m_lock); - if (m_pullFromWhichNodeTable.find(mq) != m_pullFromWhichNodeTable.end()) { - return m_pullFromWhichNodeTable[mq]; + const auto& it = m_pullFromWhichNodeTable.find(mq); + if (it != m_pullFromWhichNodeTable.end()) { + return it->second; } return MASTER_ID; } @@ -76,8 +77,8 @@ PullResult PullAPIWrapper::processPullResult(const MQMessageQueue& mq, } for (auto& msg : msgListFilterAgain) { - const auto& traFlag = msg->getProperty(MQMessageConst::PROPERTY_TRANSACTION_PREPARED); - if (UtilAll::stob(traFlag)) { + const auto& tranMsg = msg->getProperty(MQMessageConst::PROPERTY_TRANSACTION_PREPARED); + if (UtilAll::stob(tranMsg)) { msg->setTransactionId(msg->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX)); } MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_MIN_OFFSET, UtilAll::to_string(pullResult.minOffset)); diff --git a/src/consumer/PullMessageService.h b/src/consumer/PullMessageService.hpp similarity index 91% rename from src/consumer/PullMessageService.h rename to src/consumer/PullMessageService.hpp index 7c7b11a1c..8f6a6d5e9 100644 --- a/src/consumer/PullMessageService.h +++ b/src/consumer/PullMessageService.hpp @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __PULL_MESSAGE_SERVICE_H__ -#define __PULL_MESSAGE_SERVICE_H__ +#ifndef __PULL_MESSAGE_SERVICE_HPP__ +#define __PULL_MESSAGE_SERVICE_HPP__ #include "DefaultMQPushConsumerImpl.h" #include "Logging.h" @@ -57,7 +57,8 @@ class PullMessageService { private: void pullMessage(PullRequestPtr pullRequest) { MQConsumerInner* consumer = m_clientInstance->selectConsumer(pullRequest->getConsumerGroup()); - if (consumer != nullptr && std::type_index(typeid(*consumer)) == std::type_index(typeid(DefaultMQPushConsumerImpl))) { + if (consumer != nullptr && + std::type_index(typeid(*consumer)) == std::type_index(typeid(DefaultMQPushConsumerImpl))) { auto* impl = static_cast(consumer); impl->pullMessage(pullRequest); } else { @@ -72,4 +73,4 @@ class PullMessageService { } // namespace rocketmq -#endif // __PULL_MESSAGE_SERVICE_H__ +#endif // __PULL_MESSAGE_SERVICE_HPP__ diff --git a/src/consumer/PullResult.cpp b/src/consumer/PullResult.cpp index ec9f4d6ef..8fe82f2dc 100644 --- a/src/consumer/PullResult.cpp +++ b/src/consumer/PullResult.cpp @@ -20,6 +20,11 @@ namespace rocketmq { +static const char* EnumStrings[] = {"FOUND", "NO_NEW_MSG", "NO_MATCHED_MSG", + "NO_LATEST_MSG" + "OFFSET_ILLEGAL", + "BROKER_TIMEOUT"}; + PullResult::PullResult() : pullStatus(NO_MATCHED_MSG), nextBeginOffset(0), minOffset(0), maxOffset(0) {} PullResult::PullResult(PullStatus status) : pullStatus(status), nextBeginOffset(0), minOffset(0), maxOffset(0) {} @@ -51,4 +56,11 @@ PullResult::PullResult(PullStatus pullStatus, PullResult::~PullResult() = default; +std::string PullResult::toString() const { + std::stringstream ss; + ss << "PullResult [ pullStatus=" << EnumStrings[pullStatus] << ", nextBeginOffset=" << nextBeginOffset + << ", minOffset=" << minOffset << ", maxOffset=" << maxOffset << ", msgFoundList=" << msgFoundList.size() << " ]"; + return ss.str(); +} + } // namespace rocketmq diff --git a/src/consumer/PullResultExt.h b/src/consumer/PullResultExt.h index 5a3c61426..420419cfc 100644 --- a/src/consumer/PullResultExt.h +++ b/src/consumer/PullResultExt.h @@ -38,7 +38,7 @@ class PullResultExt : public PullResult { int64_t minOffset, int64_t maxOffset, int suggestWhichBrokerId, - const MemoryBlockPtr2& messageBinary) + MemoryBlockPtr2 messageBinary) : PullResult(pullStatus, nextBeginOffset, minOffset, maxOffset), suggestWhichBrokerId(suggestWhichBrokerId), msgMemBlock(messageBinary) {} diff --git a/src/consumer/RebalanceImpl.cpp b/src/consumer/RebalanceImpl.cpp index 2eec0ee01..d3b8e78c0 100644 --- a/src/consumer/RebalanceImpl.cpp +++ b/src/consumer/RebalanceImpl.cpp @@ -16,9 +16,9 @@ */ #include "RebalanceImpl.h" -#include "LockBatchBody.h" #include "MQClientAPIImpl.h" #include "MQClientInstance.h" +#include "protocol/body/LockBatchBody.h" namespace rocketmq { @@ -107,8 +107,8 @@ void RebalanceImpl::unlockAll(const bool oneway) { } std::shared_ptr RebalanceImpl::buildProcessQueueTableByBrokerName() { - std::shared_ptr brokerMqs = std::make_shared(); - MQ2PQ processQueueTable = getProcessQueueTable(); + auto brokerMqs = std::make_shared(); + auto processQueueTable = getProcessQueueTable(); for (const auto& it : processQueueTable) { const auto& mq = it.first; std::string brokerName = mq.getBrokerName(); @@ -404,9 +404,9 @@ bool RebalanceImpl::updateProcessQueueTableInRebalance(const std::string& topic, void RebalanceImpl::removeProcessQueue(const MQMessageQueue& mq) { std::lock_guard lock(m_processQueueTableMutex); - auto it = m_processQueueTable.find(mq); + const auto& it = m_processQueueTable.find(mq); if (it != m_processQueueTable.end()) { - ProcessQueuePtr prev = it->second; + auto prev = it->second; m_processQueueTable.erase(it); bool dropped = prev->isDropped(); @@ -419,33 +419,33 @@ void RebalanceImpl::removeProcessQueue(const MQMessageQueue& mq) { ProcessQueuePtr RebalanceImpl::removeProcessQueueDirectly(const MQMessageQueue& mq) { std::lock_guard lock(m_processQueueTableMutex); - auto it = m_processQueueTable.find(mq); + const auto& it = m_processQueueTable.find(mq); if (it != m_processQueueTable.end()) { - ProcessQueuePtr old = it->second; + auto old = it->second; m_processQueueTable.erase(it); return old; } - return ProcessQueuePtr(); + return nullptr; } ProcessQueuePtr RebalanceImpl::putProcessQueueIfAbsent(const MQMessageQueue& mq, ProcessQueuePtr pq) { std::lock_guard lock(m_processQueueTableMutex); - auto it = m_processQueueTable.find(mq); + const auto& it = m_processQueueTable.find(mq); if (it != m_processQueueTable.end()) { return it->second; } else { m_processQueueTable[mq] = pq; - return ProcessQueuePtr(); + return nullptr; } } ProcessQueuePtr RebalanceImpl::getProcessQueue(const MQMessageQueue& mq) { std::lock_guard lock(m_processQueueTableMutex); - if (m_processQueueTable.find(mq) != m_processQueueTable.end()) { - return m_processQueueTable[mq]; + const auto& it = m_processQueueTable.find(mq); + if (it != m_processQueueTable.end()) { + return it->second; } else { - ProcessQueuePtr ptr; - return ptr; + return nullptr; } } @@ -477,7 +477,7 @@ TOPIC2SD& RebalanceImpl::getSubscriptionInner() { } SubscriptionDataPtr RebalanceImpl::getSubscriptionData(const std::string& topic) { - auto it = m_subscriptionInner.find(topic); + const auto& it = m_subscriptionInner.find(topic); if (it != m_subscriptionInner.end()) { return it->second; } @@ -486,7 +486,7 @@ SubscriptionDataPtr RebalanceImpl::getSubscriptionData(const std::string& topic) void RebalanceImpl::setSubscriptionData(const std::string& topic, SubscriptionDataPtr subscriptionData) noexcept { if (subscriptionData != nullptr) { - auto it = m_subscriptionInner.find(topic); + const auto& it = m_subscriptionInner.find(topic); if (it != m_subscriptionInner.end()) { deleteAndZero(it->second); } @@ -496,8 +496,9 @@ void RebalanceImpl::setSubscriptionData(const std::string& topic, SubscriptionDa bool RebalanceImpl::getTopicSubscribeInfo(const std::string& topic, std::vector& mqs) { std::lock_guard lock(m_topicSubscribeInfoTableMutex); - if (m_topicSubscribeInfoTable.find(topic) != m_topicSubscribeInfoTable.end()) { - mqs = m_topicSubscribeInfoTable[topic]; + const auto& it = m_topicSubscribeInfoTable.find(topic); + if (it != m_topicSubscribeInfoTable.end()) { + mqs = it->second; // mqs will out return true; } return false; @@ -510,8 +511,6 @@ void RebalanceImpl::setTopicSubscribeInfo(const std::string& topic, std::vector< { std::lock_guard lock(m_topicSubscribeInfoTableMutex); - if (m_topicSubscribeInfoTable.find(topic) != m_topicSubscribeInfoTable.end()) - m_topicSubscribeInfoTable.erase(topic); m_topicSubscribeInfoTable[topic] = mqs; } diff --git a/src/consumer/RebalanceImpl.h b/src/consumer/RebalanceImpl.h index 69d2b3d42..0a62f4927 100755 --- a/src/consumer/RebalanceImpl.h +++ b/src/consumer/RebalanceImpl.h @@ -40,7 +40,7 @@ class RebalanceImpl { RebalanceImpl(const std::string& consumerGroup, MessageModel messageModel, AllocateMQStrategy* allocateMqStrategy, - MQClientInstance* mqClientFactory); + MQClientInstance* clientInstance); virtual ~RebalanceImpl(); void unlock(MQMessageQueue mq, const bool oneway = false); @@ -91,7 +91,7 @@ class RebalanceImpl { void setConsumerGroup(const std::string& groupname) { m_consumerGroup = groupname; } void setMessageModel(MessageModel messageModel) { m_messageModel = messageModel; } void setAllocateMQStrategy(AllocateMQStrategy* allocateMqStrategy) { m_allocateMQStrategy = allocateMqStrategy; } - void setMQClientFactory(MQClientInstance* instance) { m_clientInstance = instance; } + void setClientInstance(MQClientInstance* instance) { m_clientInstance = instance; } protected: MQ2PQ m_processQueueTable; diff --git a/src/consumer/RebalancePushImpl.cpp b/src/consumer/RebalancePushImpl.cpp index ef8c1b8c1..7ba0a53ea 100644 --- a/src/consumer/RebalancePushImpl.cpp +++ b/src/consumer/RebalancePushImpl.cpp @@ -116,7 +116,7 @@ int64_t RebalancePushImpl::computePullFromWhere(const MQMessageQueue& mq) { } } else { try { - // TODO: parseDate by YYYYMMDDHHMMSS + // FIXME: parseDate by YYYYMMDDHHMMSS auto timestamp = std::stoull(m_defaultMQPushConsumer->getDefaultMQPushConsumerConfig()->getConsumeTimestamp()); result = m_defaultMQPushConsumer->searchOffset(mq, timestamp); diff --git a/src/consumer/SubscriptionData.cpp b/src/consumer/SubscriptionData.cpp index 455b1cb9a..e67a5b805 100644 --- a/src/consumer/SubscriptionData.cpp +++ b/src/consumer/SubscriptionData.cpp @@ -70,7 +70,7 @@ std::vector& SubscriptionData::getTagsSet() { return m_tagSet; } -void SubscriptionData::putCodeSet(const int32 code) { +void SubscriptionData::putCodeSet(int32_t code) { m_codeSet.push_back(code); } diff --git a/src/extern/CBatchMessage.cpp b/src/extern/CBatchMessage.cpp index f92125ddc..2ea6ece2a 100644 --- a/src/extern/CBatchMessage.cpp +++ b/src/extern/CBatchMessage.cpp @@ -20,12 +20,11 @@ #include "MQMessage.h" -using std::vector; using namespace rocketmq; CBatchMessage* CreateBatchMessage() { - vector* msgs = new vector(); - return (CBatchMessage*)msgs; + auto* msgs = new std::vector(); + return reinterpret_cast(msgs); } int AddMessage(CBatchMessage* batchMsg, CMessage* msg) { @@ -35,8 +34,8 @@ int AddMessage(CBatchMessage* batchMsg, CMessage* msg) { if (batchMsg == NULL) { return NULL_POINTER; } - MQMessage* message = (MQMessage*)msg; - ((vector*)batchMsg)->push_back(message); + auto* message = reinterpret_cast(msg); + reinterpret_cast*>(batchMsg)->push_back(message); return OK; } @@ -44,9 +43,10 @@ int DestroyBatchMessage(CBatchMessage* batchMsg) { if (batchMsg == NULL) { return NULL_POINTER; } - for (auto* msg : *(vector*)batchMsg) { + auto* msgs = reinterpret_cast*>(batchMsg); + for (auto* msg : *msgs) { delete msg; } - delete (vector*)batchMsg; + delete msgs; return OK; } diff --git a/src/extern/CMessage.cpp b/src/extern/CMessage.cpp index 4a28260e9..588668d7f 100644 --- a/src/extern/CMessage.cpp +++ b/src/extern/CMessage.cpp @@ -21,18 +21,18 @@ using namespace rocketmq; CMessage* CreateMessage(const char* topic) { - MQMessage* mqMessage = new MQMessage(); + auto* msg = new MQMessage(); if (topic != NULL) { - mqMessage->setTopic(topic); + msg->setTopic(topic); } - return (CMessage*)mqMessage; + return reinterpret_cast(msg); } int DestroyMessage(CMessage* msg) { if (msg == NULL) { return NULL_POINTER; } - delete (MQMessage*)msg; + delete reinterpret_cast(msg); return OK; } @@ -40,7 +40,7 @@ int SetMessageTopic(CMessage* msg, const char* topic) { if (msg == NULL) { return NULL_POINTER; } - ((MQMessage*)msg)->setTopic(topic); + reinterpret_cast(msg)->setTopic(topic); return OK; } @@ -48,7 +48,7 @@ int SetMessageTags(CMessage* msg, const char* tags) { if (msg == NULL) { return NULL_POINTER; } - ((MQMessage*)msg)->setTags(tags); + reinterpret_cast(msg)->setTags(tags); return OK; } @@ -56,7 +56,7 @@ int SetMessageKeys(CMessage* msg, const char* keys) { if (msg == NULL) { return NULL_POINTER; } - ((MQMessage*)msg)->setKeys(keys); + reinterpret_cast(msg)->setKeys(keys); return OK; } @@ -64,7 +64,7 @@ int SetMessageBody(CMessage* msg, const char* body) { if (msg == NULL) { return NULL_POINTER; } - ((MQMessage*)msg)->setBody(body); + reinterpret_cast(msg)->setBody(body); return OK; } @@ -72,7 +72,7 @@ int SetByteMessageBody(CMessage* msg, const char* body, int len) { if (msg == NULL) { return NULL_POINTER; } - ((MQMessage*)msg)->setBody(body, len); + reinterpret_cast(msg)->setBody(body, len); return OK; } @@ -80,7 +80,7 @@ int SetMessageProperty(CMessage* msg, const char* key, const char* value) { if (msg == NULL) { return NULL_POINTER; } - ((MQMessage*)msg)->putProperty(key, value); + reinterpret_cast(msg)->putProperty(key, value); return OK; } @@ -88,6 +88,48 @@ int SetDelayTimeLevel(CMessage* msg, int level) { if (msg == NULL) { return NULL_POINTER; } - ((MQMessage*)msg)->setDelayTimeLevel(level); + reinterpret_cast(msg)->setDelayTimeLevel(level); return OK; } + +const char* GetOriginMessageTopic(CMessage* msg) { + if (msg == NULL) { + return NULL; + } + return reinterpret_cast(msg)->getTopic().c_str(); +} + +const char* GetOriginMessageTags(CMessage* msg) { + if (msg == NULL) { + return NULL; + } + return reinterpret_cast(msg)->getTags().c_str(); +} + +const char* GetOriginMessageKeys(CMessage* msg) { + if (msg == NULL) { + return NULL; + } + return reinterpret_cast(msg)->getKeys().c_str(); +} + +const char* GetOriginMessageBody(CMessage* msg) { + if (msg == NULL) { + return NULL; + } + return reinterpret_cast(msg)->getBody().c_str(); +} + +const char* GetOriginMessageProperty(CMessage* msg, const char* key) { + if (msg == NULL) { + return NULL; + } + return reinterpret_cast(msg)->getProperty(key).c_str(); +} + +int GetOriginDelayTimeLevel(CMessage* msg) { + if (msg == NULL) { + return -1; + } + return reinterpret_cast(msg)->getDelayTimeLevel(); +} diff --git a/src/extern/CMessageExt.cpp b/src/extern/CMessageExt.cpp index 35dc2812d..247ba5b85 100644 --- a/src/extern/CMessageExt.cpp +++ b/src/extern/CMessageExt.cpp @@ -24,103 +24,103 @@ const char* GetMessageTopic(CMessageExt* msg) { if (msg == NULL) { return NULL; } - return ((MQMessageExt*)msg)->getTopic().c_str(); + return reinterpret_cast(msg)->getTopic().c_str(); } const char* GetMessageTags(CMessageExt* msg) { if (msg == NULL) { return NULL; } - return ((MQMessageExt*)msg)->getTags().c_str(); + return reinterpret_cast(msg)->getTags().c_str(); } const char* GetMessageKeys(CMessageExt* msg) { if (msg == NULL) { return NULL; } - return ((MQMessageExt*)msg)->getKeys().c_str(); + return reinterpret_cast(msg)->getKeys().c_str(); } const char* GetMessageBody(CMessageExt* msg) { if (msg == NULL) { return NULL; } - return ((MQMessageExt*)msg)->getBody().c_str(); + return reinterpret_cast(msg)->getBody().c_str(); } const char* GetMessageProperty(CMessageExt* msg, const char* key) { if (msg == NULL) { return NULL; } - return ((MQMessageExt*)msg)->getProperty(key).c_str(); + return reinterpret_cast(msg)->getProperty(key).c_str(); } const char* GetMessageId(CMessageExt* msg) { if (msg == NULL) { return NULL; } - return ((MQMessageExt*)msg)->getMsgId().c_str(); + return reinterpret_cast(msg)->getMsgId().c_str(); } int GetMessageDelayTimeLevel(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return ((MQMessageExt*)msg)->getDelayTimeLevel(); + return reinterpret_cast(msg)->getDelayTimeLevel(); } int GetMessageQueueId(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return ((MQMessageExt*)msg)->getQueueId(); + return reinterpret_cast(msg)->getQueueId(); } int GetMessageReconsumeTimes(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return ((MQMessageExt*)msg)->getReconsumeTimes(); + return reinterpret_cast(msg)->getReconsumeTimes(); } int GetMessageStoreSize(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return ((MQMessageExt*)msg)->getStoreSize(); + return reinterpret_cast(msg)->getStoreSize(); } long long GetMessageBornTimestamp(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return ((MQMessageExt*)msg)->getBornTimestamp(); + return reinterpret_cast(msg)->getBornTimestamp(); } long long GetMessageStoreTimestamp(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return ((MQMessageExt*)msg)->getStoreTimestamp(); + return reinterpret_cast(msg)->getStoreTimestamp(); } long long GetMessageQueueOffset(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return ((MQMessageExt*)msg)->getQueueOffset(); + return reinterpret_cast(msg)->getQueueOffset(); } long long GetMessageCommitLogOffset(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return ((MQMessageExt*)msg)->getCommitLogOffset(); + return reinterpret_cast(msg)->getCommitLogOffset(); } long long GetMessagePreparedTransactionOffset(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return ((MQMessageExt*)msg)->getPreparedTransactionOffset(); + return reinterpret_cast(msg)->getPreparedTransactionOffset(); } diff --git a/src/extern/CProducer.cpp b/src/extern/CProducer.cpp index 3a4029f40..60502c2d3 100644 --- a/src/extern/CProducer.cpp +++ b/src/extern/CProducer.cpp @@ -24,47 +24,104 @@ #include "DefaultMQProducer.h" #include "Logging.h" #include "MQClientErrorContainer.h" +#include "TransactionMQProducer.h" #include "UtilAll.h" using namespace rocketmq; +class LocalTransactionExecutorInner { + public: + LocalTransactionExecutorInner(CLocalTransactionExecutorCallback callback, CMessage* message, void* userData) + : m_excutorCallback(callback), m_message(message), m_userData(userData) {} + + ~LocalTransactionExecutorInner() = default; + + public: + CLocalTransactionExecutorCallback m_excutorCallback; + CMessage* m_message; + void* m_userData; +}; + +class LocalTransactionListenerInner : public TransactionListener { + public: + LocalTransactionListenerInner(CProducer* producer, CLocalTransactionCheckerCallback callback, void* userData) + : m_producer(producer), m_checkerCallback(callback), m_userData(userData) {} + + ~LocalTransactionListenerInner() = default; + + LocalTransactionState executeLocalTransaction(const MQMessage& message, void* arg) override { + if (m_checkerCallback == nullptr) { + return LocalTransactionState::UNKNOWN; + } + auto* msg = reinterpret_cast(const_cast(&message)); + auto* executorInner = reinterpret_cast(arg); + auto status = executorInner->m_excutorCallback(m_producer, msg, executorInner->m_userData); + 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& message) override { + if (m_checkerCallback == NULL) { + return LocalTransactionState::UNKNOWN; + } + auto* msgExt = reinterpret_cast(const_cast(&message)); + auto status = m_checkerCallback(m_producer, msgExt, m_userData); + switch (status) { + case E_COMMIT_TRANSACTION: + return LocalTransactionState::COMMIT_MESSAGE; + case E_ROLLBACK_TRANSACTION: + return LocalTransactionState::ROLLBACK_MESSAGE; + default: + return LocalTransactionState::UNKNOWN; + } + } + + private: + CProducer* m_producer; + CLocalTransactionCheckerCallback m_checkerCallback; + void* m_userData; +}; + class SelectMessageQueueInner : public MessageQueueSelector { public: - MQMessageQueue select(const std::vector& mqs, const MQMessage& msg, void* arg) { - int index = 0; + MQMessageQueue select(const std::vector& mqs, const MQMessage& msg, void* arg) override { std::string shardingKey = UtilAll::to_string((char*)arg); - - index = std::hash{}(shardingKey) % mqs.size(); + auto index = std::hash{}(shardingKey) % mqs.size(); return mqs[index % mqs.size()]; } }; class SelectMessageQueue : public MessageQueueSelector { public: - SelectMessageQueue(QueueSelectorCallback callback) { m_pCallback = callback; } + SelectMessageQueue(QueueSelectorCallback callback) { m_callback = callback; } - MQMessageQueue select(const std::vector& mqs, const MQMessage& msg, void* arg) { - CMessage* message = (CMessage*)&msg; + MQMessageQueue select(const std::vector& mqs, const MQMessage& msg, void* arg) override { + auto* message = reinterpret_cast(const_cast(&msg)); // Get the index of sending MQMessageQueue through callback function. - int index = m_pCallback(mqs.size(), message, arg); + auto index = m_callback(mqs.size(), message, arg); return mqs[index]; } private: - QueueSelectorCallback m_pCallback; + QueueSelectorCallback m_callback; }; 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; - } + COnSendCallback(COnSendSuccessCallback sendSuccessCallback, + COnSendExceptionCallback sendExceptionCallback, + CMessage* message, + void* userData) + : m_sendSuccessCallback(sendSuccessCallback), + m_sendExceptionCallback(sendExceptionCallback), + m_message(message), + m_userData(userData) {} virtual ~COnSendCallback() = default; @@ -74,7 +131,7 @@ class COnSendCallback : public AutoDeleteSendCallback { 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); + m_sendSuccessCallback(result, m_message, m_userData); } void onException(MQException& e) noexcept override { @@ -83,22 +140,20 @@ class COnSendCallback : public AutoDeleteSendCallback { 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); + m_sendExceptionCallback(exception, m_message, m_userData); } private: - COnSendSuccessCallback m_cSendSuccessCallback; - COnSendExceptionCallback m_cSendExceptionCallback; - void* m_message; + COnSendSuccessCallback m_sendSuccessCallback; + COnSendExceptionCallback m_sendExceptionCallback; + CMessage* m_message; void* m_userData; }; class CSendCallback : public AutoDeleteSendCallback { public: - CSendCallback(CSendSuccessCallback cSendSuccessCallback, CSendExceptionCallback cSendExceptionCallback) { - m_cSendSuccessCallback = cSendSuccessCallback; - m_cSendExceptionCallback = cSendExceptionCallback; - } + CSendCallback(CSendSuccessCallback sendSuccessCallback, CSendExceptionCallback sendExceptionCallback) + : m_sendSuccessCallback(sendSuccessCallback), m_sendExceptionCallback(sendExceptionCallback) {} virtual ~CSendCallback() = default; @@ -108,7 +163,7 @@ class CSendCallback : public AutoDeleteSendCallback { 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); + m_sendSuccessCallback(result); } void onException(MQException& e) noexcept override { @@ -117,12 +172,12 @@ class CSendCallback : public AutoDeleteSendCallback { 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); + m_sendExceptionCallback(exception); } private: - CSendSuccessCallback m_cSendSuccessCallback; - CSendExceptionCallback m_cSendExceptionCallback; + CSendSuccessCallback m_sendSuccessCallback; + CSendExceptionCallback m_sendExceptionCallback; }; CProducer* CreateProducer(const char* groupId) { @@ -130,13 +185,24 @@ CProducer* CreateProducer(const char* groupId) { return NULL; } auto* defaultMQProducer = new DefaultMQProducer(groupId); - return (CProducer*)defaultMQProducer; + return reinterpret_cast(defaultMQProducer); } CProducer* CreateOrderlyProducer(const char* groupId) { return CreateProducer(groupId); } +CProducer* CreateTransactionProducer(const char* groupId, CLocalTransactionCheckerCallback callback, void* userData) { + if (groupId == NULL) { + return NULL; + } + auto* transactionMQProducer = new TransactionMQProducer(groupId); + auto* producer = reinterpret_cast(static_cast(transactionMQProducer)); + auto* transcationListener = new LocalTransactionListenerInner(producer, callback, userData); + transactionMQProducer->setTransactionListener(transcationListener); + return producer; +} + int DestroyProducer(CProducer* producer) { if (producer == nullptr) { return NULL_POINTER; @@ -184,14 +250,13 @@ int SetProducerNameServerDomain(CProducer* producer, const char* domain) { } int SendMessageSync(CProducer* producer, CMessage* msg, CSendResult* result) { - // CSendResult sendResult; if (producer == NULL || msg == NULL || result == NULL) { return NULL_POINTER; } try { - DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)producer; - MQMessage* message = (MQMessage*)msg; - SendResult sendResult = defaultMQProducer->send(message); + auto* defaultMQProducer = reinterpret_cast(producer); + auto* message = reinterpret_cast(msg); + auto sendResult = defaultMQProducer->send(message); switch (sendResult.getSendStatus()) { case SEND_OK: result->sendStatus = E_SEND_OK; @@ -220,14 +285,13 @@ int SendMessageSync(CProducer* producer, CMessage* msg, CSendResult* result) { } int SendBatchMessage(CProducer* producer, CBatchMessage* batcMsg, CSendResult* result) { - // CSendResult sendResult; if (producer == NULL || batcMsg == NULL || result == NULL) { return NULL_POINTER; } try { - DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)producer; - std::vector* message = (std::vector*)batcMsg; - SendResult sendResult = defaultMQProducer->send(*message); + auto* defaultMQProducer = reinterpret_cast(producer); + auto* message = reinterpret_cast*>(batcMsg); + auto sendResult = defaultMQProducer->send(*message); switch (sendResult.getSendStatus()) { case SEND_OK: result->sendStatus = E_SEND_OK; @@ -256,30 +320,30 @@ int SendBatchMessage(CProducer* producer, CBatchMessage* batcMsg, CSendResult* r int SendMessageAsync(CProducer* producer, CMessage* msg, - CSendSuccessCallback cSendSuccessCallback, - CSendExceptionCallback cSendExceptionCallback) { - if (producer == NULL || msg == NULL || cSendSuccessCallback == NULL || cSendExceptionCallback == NULL) { + CSendSuccessCallback sendSuccessCallback, + CSendExceptionCallback sendExceptionCallback) { + if (producer == NULL || msg == NULL || sendSuccessCallback == NULL || sendExceptionCallback == NULL) { return NULL_POINTER; } - DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)producer; - MQMessage* message = (MQMessage*)msg; - CSendCallback* cSendCallback = new CSendCallback(cSendSuccessCallback, cSendExceptionCallback); - defaultMQProducer->send(message, cSendCallback); + auto* defaultMQProducer = reinterpret_cast(producer); + auto* message = reinterpret_cast(msg); + auto* sendCallback = new CSendCallback(sendSuccessCallback, sendExceptionCallback); + defaultMQProducer->send(message, sendCallback); return OK; } int SendAsync(CProducer* producer, CMessage* msg, - COnSendSuccessCallback onSuccess, - COnSendExceptionCallback onException, - void* usrData) { - if (producer == NULL || msg == NULL || onSuccess == NULL || onException == NULL) { + COnSendSuccessCallback sendSuccessCallback, + COnSendExceptionCallback sendExceptionCallback, + void* userData) { + if (producer == NULL || msg == NULL || sendSuccessCallback == NULL || sendExceptionCallback == NULL) { return NULL_POINTER; } - DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)producer; - MQMessage* message = (MQMessage*)msg; - COnSendCallback* cSendCallback = new COnSendCallback(onSuccess, onException, (void*)msg, usrData); - defaultMQProducer->send(message, cSendCallback); + auto* defaultMQProducer = reinterpret_cast(producer); + auto* message = reinterpret_cast(msg); + auto* sendCallback = new COnSendCallback(sendSuccessCallback, sendExceptionCallback, msg, userData); + defaultMQProducer->send(message, sendCallback); return OK; } @@ -287,8 +351,8 @@ int SendMessageOneway(CProducer* producer, CMessage* msg) { if (producer == NULL || msg == NULL) { return NULL_POINTER; } - DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)producer; - MQMessage* message = (MQMessage*)msg; + auto* defaultMQProducer = reinterpret_cast(producer); + auto* message = reinterpret_cast(msg); try { defaultMQProducer->sendOneway(message); } catch (std::exception& e) { @@ -301,8 +365,8 @@ int SendMessageOnewayOrderly(CProducer* producer, CMessage* msg, QueueSelectorCa if (producer == NULL || msg == NULL) { return NULL_POINTER; } - DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)producer; - MQMessage* message = (MQMessage*)msg; + auto* defaultMQProducer = reinterpret_cast(producer); + auto* message = reinterpret_cast(msg); try { SelectMessageQueue selectMessageQueue(selector); defaultMQProducer->sendOneway(message, &selectMessageQueue, arg); @@ -315,37 +379,37 @@ int SendMessageOnewayOrderly(CProducer* producer, CMessage* msg, QueueSelectorCa int SendMessageOrderlyAsync(CProducer* producer, CMessage* msg, - QueueSelectorCallback callback, + QueueSelectorCallback selectorCallback, void* arg, - CSendSuccessCallback cSendSuccessCallback, - CSendExceptionCallback cSendExceptionCallback) { - if (producer == NULL || msg == NULL || callback == NULL || cSendSuccessCallback == NULL || - cSendExceptionCallback == NULL) { + CSendSuccessCallback sendSuccessCallback, + CSendExceptionCallback sendExceptionCallback) { + if (producer == NULL || msg == NULL || selectorCallback == NULL || sendSuccessCallback == NULL || + sendExceptionCallback == NULL) { return NULL_POINTER; } - DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)producer; - MQMessage* message = (MQMessage*)msg; - CSendCallback* cSendCallback = new CSendCallback(cSendSuccessCallback, cSendExceptionCallback); + auto* defaultMQProducer = reinterpret_cast(producer); + auto* message = reinterpret_cast(msg); + auto* cSendCallback = new CSendCallback(sendSuccessCallback, sendExceptionCallback); // Constructing SelectMessageQueue objects through function pointer callback - SelectMessageQueue selectMessageQueue(callback); + SelectMessageQueue selectMessageQueue(selectorCallback); defaultMQProducer->send(message, &selectMessageQueue, arg, cSendCallback); return OK; } int SendMessageOrderly(CProducer* producer, CMessage* msg, - QueueSelectorCallback callback, + QueueSelectorCallback selectorCallback, void* arg, int autoRetryTimes, CSendResult* result) { - if (producer == NULL || msg == NULL || callback == NULL || arg == NULL || result == NULL) { + if (producer == NULL || msg == NULL || selectorCallback == NULL || arg == NULL || result == NULL) { return NULL_POINTER; } - DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)producer; - MQMessage* message = (MQMessage*)msg; + auto* defaultMQProducer = reinterpret_cast(producer); + auto* message = reinterpret_cast(msg); try { // Constructing SelectMessageQueue objects through function pointer callback - SelectMessageQueue selectMessageQueue(callback); + SelectMessageQueue selectMessageQueue(selectorCallback); SendResult sendResult = defaultMQProducer->send(message, &selectMessageQueue, arg); // Convert SendStatus to CSendStatus result->sendStatus = CSendStatus((int)sendResult.getSendStatus()); @@ -363,8 +427,8 @@ int SendMessageOrderlyByShardingKey(CProducer* producer, CMessage* msg, const ch if (producer == NULL || msg == NULL || shardingKey == NULL || result == NULL) { return NULL_POINTER; } - DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)producer; - MQMessage* message = (MQMessage*)msg; + auto* defaultMQProducer = reinterpret_cast(producer); + auto* message = reinterpret_cast(msg); try { // Constructing SelectMessageQueue objects through function pointer callback int retryTimes = 3; @@ -382,6 +446,30 @@ int SendMessageOrderlyByShardingKey(CProducer* producer, CMessage* msg, const ch 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 { + auto* transactionMQProducer = reinterpret_cast(producer); + auto* message = reinterpret_cast(msg); + LocalTransactionExecutorInner executorInner(callback, msg, userData); + auto sendResult = transactionMQProducer->sendMessageInTransaction(message, &executorInner); + 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 (std::exception& e) { + MQClientErrorContainer::setErr(std::string(e.what())); + return PRODUCER_SEND_TRANSACTION_FAILED; + } + return OK; +} + int SetProducerGroupName(CProducer* producer, const char* groupName) { if (producer == NULL) { return NULL_POINTER; @@ -414,7 +502,7 @@ int SetProducerLogPath(CProducer* producer, const char* logPath) { if (producer == NULL) { return NULL_POINTER; } - // Todo, This api should be implemented by core api. + // TODO: This api should be implemented by core api. // reinterpret_cast(producer)->setLogFileSizeAndNum(3, 102400000); return OK; } diff --git a/src/extern/CPullConsumer.cpp b/src/extern/CPullConsumer.cpp index 497b8960b..61210a382 100644 --- a/src/extern/CPullConsumer.cpp +++ b/src/extern/CPullConsumer.cpp @@ -29,8 +29,8 @@ CPullConsumer* CreatePullConsumer(const char* groupId) { if (groupId == NULL) { return NULL; } - DefaultMQPullConsumer* defaultMQPullConsumer = new DefaultMQPullConsumer(groupId); - return (CPullConsumer*)defaultMQPullConsumer; + auto* defaultMQPullConsumer = new DefaultMQPullConsumer(groupId); + return reinterpret_cast(defaultMQPullConsumer); } int DestroyPullConsumer(CPullConsumer* consumer) { diff --git a/src/extern/CPushConsumer.cpp b/src/extern/CPushConsumer.cpp index add5ef323..40fbd2b93 100644 --- a/src/extern/CPushConsumer.cpp +++ b/src/extern/CPushConsumer.cpp @@ -27,23 +27,19 @@ using namespace rocketmq; class MessageListenerInner : public MessageListenerConcurrently { public: - MessageListenerInner() {} + MessageListenerInner(CPushConsumer* consumer, MessageCallBack callback) + : m_consumer(consumer), m_msgReceivedCallback(callback) {} - MessageListenerInner(CPushConsumer* consumer, MessageCallBack pCallback) { - m_pconsumer = consumer; - m_pMsgReceiveCallback = pCallback; - } - - ~MessageListenerInner() {} + ~MessageListenerInner() = default; - ConsumeStatus consumeMessage(const std::vector& msgs) { + ConsumeStatus consumeMessage(const std::vector& msgs) override { // to do user call back - if (m_pMsgReceiveCallback == nullptr) { + if (m_msgReceivedCallback == nullptr) { return RECONSUME_LATER; } - for (size_t i = 0; i < msgs.size(); ++i) { - CMessageExt* message = (CMessageExt*)msgs[i]; - if (m_pMsgReceiveCallback(m_pconsumer, message) != E_CONSUME_SUCCESS) { + for (auto msg : msgs) { + auto* message = reinterpret_cast(msg); + if (m_msgReceivedCallback(m_consumer, message) != E_CONSUME_SUCCESS) { return RECONSUME_LATER; } } @@ -51,24 +47,22 @@ class MessageListenerInner : public MessageListenerConcurrently { } private: - MessageCallBack m_pMsgReceiveCallback; - CPushConsumer* m_pconsumer; + CPushConsumer* m_consumer; + MessageCallBack m_msgReceivedCallback; }; class MessageListenerOrderlyInner : public MessageListenerOrderly { public: - MessageListenerOrderlyInner(CPushConsumer* consumer, MessageCallBack pCallback) { - m_pconsumer = consumer; - m_pMsgReceiveCallback = pCallback; - } + MessageListenerOrderlyInner(CPushConsumer* consumer, MessageCallBack callback) + : m_consumer(consumer), m_msgReceivedCallback(callback) {} ConsumeStatus consumeMessage(const std::vector& msgs) { - if (m_pMsgReceiveCallback == nullptr) { + if (m_msgReceivedCallback == nullptr) { return RECONSUME_LATER; } - for (size_t i = 0; i < msgs.size(); ++i) { - CMessageExt* message = (CMessageExt*)msgs[i]; - if (m_pMsgReceiveCallback(m_pconsumer, message) != E_CONSUME_SUCCESS) { + for (auto msg : msgs) { + auto* message = reinterpret_cast(msg); + if (m_msgReceivedCallback(m_consumer, message) != E_CONSUME_SUCCESS) { return RECONSUME_LATER; } } @@ -76,13 +70,10 @@ class MessageListenerOrderlyInner : public MessageListenerOrderly { } private: - MessageCallBack m_pMsgReceiveCallback; - CPushConsumer* m_pconsumer; + CPushConsumer* m_consumer; + MessageCallBack m_msgReceivedCallback; }; -std::map g_ListenerMap; -std::map g_OrderListenerMap; - CPushConsumer* CreatePushConsumer(const char* groupId) { if (groupId == NULL) { return NULL; @@ -160,23 +151,21 @@ int Subscribe(CPushConsumer* consumer, const char* topic, const char* expression return OK; } -int RegisterMessageCallback(CPushConsumer* consumer, MessageCallBack pCallback) { - if (consumer == NULL || pCallback == NULL) { +int RegisterMessageCallback(CPushConsumer* consumer, MessageCallBack callback) { + if (consumer == NULL || callback == NULL) { return NULL_POINTER; } - MessageListenerInner* listenerInner = new MessageListenerInner(consumer, pCallback); + auto* listenerInner = new MessageListenerInner(consumer, callback); reinterpret_cast(consumer)->registerMessageListener(listenerInner); - g_ListenerMap[consumer] = listenerInner; return OK; } -int RegisterMessageCallbackOrderly(CPushConsumer* consumer, MessageCallBack pCallback) { - if (consumer == NULL || pCallback == NULL) { +int RegisterMessageCallbackOrderly(CPushConsumer* consumer, MessageCallBack callback) { + if (consumer == NULL || callback == NULL) { return NULL_POINTER; } - MessageListenerOrderlyInner* messageListenerOrderlyInner = new MessageListenerOrderlyInner(consumer, pCallback); + auto* messageListenerOrderlyInner = new MessageListenerOrderlyInner(consumer, callback); reinterpret_cast(consumer)->registerMessageListener(messageListenerOrderlyInner); - g_OrderListenerMap[consumer] = messageListenerOrderlyInner; return OK; } @@ -184,15 +173,8 @@ int UnregisterMessageCallbackOrderly(CPushConsumer* consumer) { if (consumer == NULL) { return NULL_POINTER; } - std::map::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); - } + auto* listenerInner = reinterpret_cast(consumer)->getMessageListener(); + delete listenerInner; return OK; } @@ -200,16 +182,8 @@ int UnregisterMessageCallback(CPushConsumer* consumer) { if (consumer == NULL) { return NULL_POINTER; } - std::map::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); - } + auto* listenerInner = reinterpret_cast(consumer)->getMessageListener(); + delete listenerInner; return OK; } @@ -275,7 +249,7 @@ int SetPushConsumerLogPath(CPushConsumer* consumer, const char* logPath) { if (consumer == NULL) { return NULL_POINTER; } - // Todo, This api should be implemented by core api. + // TODO: This api should be implemented by core api. // reinterpret_cast(consumer)->setInstanceName(instanceName); return OK; } diff --git a/src/message/MQDecoder.cpp b/src/message/MQDecoder.cpp index 931057497..863fa41e0 100644 --- a/src/message/MQDecoder.cpp +++ b/src/message/MQDecoder.cpp @@ -41,13 +41,13 @@ int MQDecoder::MessageFlagPostion = 16; int MQDecoder::MessagePhysicOffsetPostion = 28; int MQDecoder::MessageStoreTimestampPostion = 56; -std::string MQDecoder::createMessageId(sockaddr addr, int64_t offset) { - struct sockaddr_in* sa = (struct sockaddr_in*)&addr; +std::string MQDecoder::createMessageId(const struct sockaddr* sa, int64_t offset) { + const struct sockaddr_in* sin = (struct sockaddr_in*)sa; MemoryOutputStream outputmen(MSG_ID_LENGTH); - outputmen.writeIntBigEndian(sa->sin_addr.s_addr); + outputmen.writeIntBigEndian(sin->sin_addr.s_addr); outputmen.writeRepeatedByte(0, 2); - outputmen.write(&(sa->sin_port), 2); + outputmen.write(&(sin->sin_port), 2); outputmen.writeInt64BigEndian(offset); const char* bytes = static_cast(outputmen.getData()); @@ -67,12 +67,12 @@ MQMessageId MQDecoder::decodeMessageId(const std::string& msgId) { uint64_t offset = UtilAll::hexstr2ull(offsetStr.c_str()); - struct sockaddr_in sa; - sa.sin_family = AF_INET; - sa.sin_port = htons(portInt); - sa.sin_addr.s_addr = htonl(ipInt); + struct sockaddr_in sin; + sin.sin_family = AF_INET; + sin.sin_port = htons(portInt); + sin.sin_addr.s_addr = htonl(ipInt); - return MQMessageId(*((sockaddr*)&sa), offset); + return MQMessageId((struct sockaddr*)&sin, offset); } MQMessageExtPtr MQDecoder::clientDecode(MemoryInputStream& byteBuffer, bool readBody) { @@ -130,18 +130,16 @@ MQMessageExtPtr MQDecoder::decode(MemoryInputStream& byteBuffer, bool readBody, // 10 BORNHOST int32_t bornHost = byteBuffer.readIntBigEndian(); int32_t bornPort = byteBuffer.readIntBigEndian(); - sockaddr bornAddr = IPPort2socketAddress(bornHost, bornPort); - msgExt->setBornHost(bornAddr); + msgExt->setBornHost(ipPort2SocketAddress(bornHost, bornPort)); // 11 STORETIMESTAMP int64_t storeTimestamp = byteBuffer.readInt64BigEndian(); msgExt->setStoreTimestamp(storeTimestamp); - // // 12 STOREHOST + // 12 STOREHOST int32_t storeHost = byteBuffer.readIntBigEndian(); int32_t storePort = byteBuffer.readIntBigEndian(); - sockaddr storeAddr = IPPort2socketAddress(storeHost, storePort); - msgExt->setStoreHost(storeAddr); + msgExt->setStoreHost(ipPort2SocketAddress(storeHost, storePort)); // 13 RECONSUMETIMES int32_t reconsumeTimes = byteBuffer.readIntBigEndian(); diff --git a/src/message/MQDecoder.h b/src/message/MQDecoder.h index 01b6f84c4..8b9eea3f5 100644 --- a/src/message/MQDecoder.h +++ b/src/message/MQDecoder.h @@ -25,13 +25,12 @@ #include "MQMessageExt.h" #include "MQMessageId.h" #include "MemoryInputStream.h" -#include "SocketUtil.h" namespace rocketmq { class MQDecoder { public: - static std::string createMessageId(sockaddr addr, int64_t offset); + static std::string createMessageId(const struct sockaddr* sa, int64_t offset); static MQMessageId decodeMessageId(const std::string& msgId); static MQMessageExtPtr2 decode(MemoryBlock& mem); diff --git a/src/message/MQMessage.cpp b/src/message/MQMessage.cpp index c745a3f71..3f2a29ce4 100644 --- a/src/message/MQMessage.cpp +++ b/src/message/MQMessage.cpp @@ -15,6 +15,7 @@ * limitations under the License. */ #include "MQMessage.h" + #include "MessageSysFlag.h" #include "UtilAll.h" @@ -47,6 +48,13 @@ const std::string MQMessageConst::PROPERTY_TRANSACTION_PREPARED_QUEUE_OFFSET = " const std::string MQMessageConst::PROPERTY_TRANSACTION_CHECK_TIMES = "TRANSACTION_CHECK_TIMES"; const std::string MQMessageConst::PROPERTY_CHECK_IMMUNITY_TIME_IN_SECONDS = "CHECK_IMMUNITY_TIME_IN_SECONDS"; const std::string MQMessageConst::PROPERTY_INSTANCE_ID = "INSTANCE_ID"; +const std::string MQMessageConst::PROPERTY_CORRELATION_ID = "CORRELATION_ID"; +const std::string MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT = "REPLY_TO_CLIENT"; +const std::string MQMessageConst::PROPERTY_MESSAGE_TTL = "TTL"; +const std::string MQMessageConst::PROPERTY_REPLY_MESSAGE_ARRIVE_TIME = "ARRIVE_TIME"; +const std::string MQMessageConst::PROPERTY_PUSH_REPLY_TIME = "PUSH_REPLY_TIME"; +const std::string MQMessageConst::PROPERTY_CLUSTER = "CLUSTER"; +const std::string MQMessageConst::PROPERTY_MESSAGE_TYPE = "MSG_TYPE"; const std::string MQMessageConst::PROPERTY_ALREADY_COMPRESSED_FLAG = "__ALREADY_COMPRESSED__"; @@ -54,12 +62,12 @@ const std::string MQMessageConst::KEY_SEPARATOR = " "; static const std::string EMPTY_STRING = ""; -MQMessage::MQMessage() : MQMessage(null, "*", null, 0, null, true) {} +MQMessage::MQMessage() : MQMessage(null, null) {} -MQMessage::MQMessage(const std::string& topic, const std::string& body) : MQMessage(topic, "*", null, 0, body, true) {} +MQMessage::MQMessage(const std::string& topic, const std::string& body) : MQMessage(topic, "", body) {} MQMessage::MQMessage(const std::string& topic, const std::string& tags, const std::string& body) - : MQMessage(topic, tags, null, 0, body, true) {} + : MQMessage(topic, tags, null, body) {} MQMessage::MQMessage(const std::string& topic, const std::string& tags, @@ -105,7 +113,7 @@ MQMessage& MQMessage::operator=(const MQMessage& other) { MQMessage::~MQMessage() = default; const std::string& MQMessage::getProperty(const std::string& name) const { - const auto it = m_properties.find(name); + const auto& it = m_properties.find(name); if (it != m_properties.end()) { return it->second; } diff --git a/src/message/MQMessageExt.cpp b/src/message/MQMessageExt.cpp index 4beef805e..e76a84423 100644 --- a/src/message/MQMessageExt.cpp +++ b/src/message/MQMessageExt.cpp @@ -25,26 +25,13 @@ namespace rocketmq { -MQMessageExt::MQMessageExt() - : m_storeSize(0), - m_bodyCRC(0), - m_queueId(0), - m_queueOffset(0), - m_commitLogOffset(0), - m_sysFlag(0), - m_bornTimestamp(0), - m_storeTimestamp(0), - m_reconsumeTimes(3), - m_preparedTransactionOffset(0) { - memset(&m_bornHost, 0, sizeof(m_bornHost)); - memset(&m_storeHost, 0, sizeof(m_storeHost)); -} +MQMessageExt::MQMessageExt() : MQMessageExt(0, 0, nullptr, 0, nullptr, "") {} MQMessageExt::MQMessageExt(int queueId, int64_t bornTimestamp, - sockaddr bornHost, + const struct sockaddr* bornHost, int64_t storeTimestamp, - sockaddr storeHost, + const struct sockaddr* storeHost, std::string msgId) : m_storeSize(0), m_bodyCRC(0), @@ -53,14 +40,20 @@ MQMessageExt::MQMessageExt(int queueId, m_commitLogOffset(0), m_sysFlag(0), m_bornTimestamp(bornTimestamp), - m_bornHost(bornHost), + m_bornHost(nullptr), m_storeTimestamp(storeTimestamp), - m_storeHost(storeHost), + m_storeHost(nullptr), m_reconsumeTimes(3), m_preparedTransactionOffset(0), - m_msgId(msgId) {} + m_msgId(msgId) { + m_bornHost = copySocketAddress(m_bornHost, bornHost); + m_storeHost = copySocketAddress(m_storeHost, storeHost); +} -MQMessageExt::~MQMessageExt() = default; +MQMessageExt::~MQMessageExt() { + free(m_bornHost); + free(m_storeHost); +} TopicFilterType MQMessageExt::parseTopicFilterType(int32_t sysFlag) { if ((sysFlag & MessageSysFlag::MultiTagsFlag) == MessageSysFlag::MultiTagsFlag) { @@ -125,16 +118,16 @@ void MQMessageExt::setBornTimestamp(int64_t bornTimestamp) { m_bornTimestamp = bornTimestamp; } -const sockaddr& MQMessageExt::getBornHost() const { +const struct sockaddr* MQMessageExt::getBornHost() const { return m_bornHost; } std::string MQMessageExt::getBornHostString() const { - return socketAddress2String(&m_bornHost); + return socketAddress2String(m_bornHost); } -void MQMessageExt::setBornHost(const sockaddr& bornHost) { - m_bornHost = bornHost; +void MQMessageExt::setBornHost(const struct sockaddr* bornHost) { + m_bornHost = copySocketAddress(m_bornHost, bornHost); } int64_t MQMessageExt::getStoreTimestamp() const { @@ -145,16 +138,16 @@ void MQMessageExt::setStoreTimestamp(int64_t storeTimestamp) { m_storeTimestamp = storeTimestamp; } -const sockaddr& MQMessageExt::getStoreHost() const { +const struct sockaddr* MQMessageExt::getStoreHost() const { return m_storeHost; } std::string MQMessageExt::getStoreHostString() const { - return socketAddress2String(&m_storeHost); + return socketAddress2String(m_storeHost); } -void MQMessageExt::setStoreHost(const sockaddr& storeHost) { - m_storeHost = storeHost; +void MQMessageExt::setStoreHost(const struct sockaddr* storeHost) { + m_storeHost = copySocketAddress(m_storeHost, storeHost); } const std::string& MQMessageExt::getMsgId() const { diff --git a/src/message/MQMessageId.h b/src/message/MQMessageId.h index da98e1f37..2e31e7838 100644 --- a/src/message/MQMessageId.h +++ b/src/message/MQMessageId.h @@ -24,27 +24,29 @@ namespace rocketmq { class MQMessageId { public: - MQMessageId() {} - MQMessageId(sockaddr address, int64_t offset) : m_address(address), m_offset(offset) {} + MQMessageId() : MQMessageId(nullptr, 0) {} + MQMessageId(struct sockaddr* address, int64_t offset) : m_address(nullptr), m_offset(offset) { setAddress(address); } + ~MQMessageId() { free(m_address); } + MQMessageId& operator=(const MQMessageId& id) { if (&id == this) { return *this; } - this->m_address = id.m_address; + setAddress(id.m_address); this->m_offset = id.m_offset; return *this; } - const sockaddr& getAddress() const { return m_address; } + const struct sockaddr* getAddress() const { return m_address; } - void setAddress(sockaddr address) { m_address = address; } + void setAddress(struct sockaddr* address) { m_address = copySocketAddress(m_address, address); } int64_t getOffset() const { return m_offset; } void setOffset(int64_t offset) { m_offset = offset; } private: - sockaddr m_address; // FIXME: store a pointer for ipv6 + struct sockaddr* m_address; int64_t m_offset; }; diff --git a/src/message/MessageUtil.cpp b/src/message/MessageUtil.cpp new file mode 100644 index 000000000..c5d283281 --- /dev/null +++ b/src/message/MessageUtil.cpp @@ -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. + */ +#include "MessageUtil.h" + +#include + +#include "ClientErrorCode.h" +#include "MQMessageConst.h" +#include "MessageAccessor.h" +#include "UtilAll.h" + +namespace rocketmq { + +MQMessagePtr MessageUtil::createReplyMessage(const MQMessagePtr requestMessage, + const std::string& body) throw(MQClientException) { + if (requestMessage != nullptr) { + std::unique_ptr replyMessage(new MQMessage()); + const auto& cluster = requestMessage->getProperty(MQMessageConst::PROPERTY_CLUSTER); + const auto& replyTo = requestMessage->getProperty(MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT); + const auto& correlationId = requestMessage->getProperty(MQMessageConst::PROPERTY_CORRELATION_ID); + const auto& ttl = requestMessage->getProperty(MQMessageConst::PROPERTY_MESSAGE_TTL); + replyMessage->setBody(body); + if (!cluster.empty()) { + auto replyTopic = UtilAll::getReplyTopic(cluster); + replyMessage->setTopic(replyTopic); + MessageAccessor::putProperty(*replyMessage, MQMessageConst::PROPERTY_MESSAGE_TYPE, REPLY_MESSAGE_FLAG); + MessageAccessor::putProperty(*replyMessage, MQMessageConst::PROPERTY_CORRELATION_ID, correlationId); + MessageAccessor::putProperty(*replyMessage, MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT, replyTo); + MessageAccessor::putProperty(*replyMessage, MQMessageConst::PROPERTY_MESSAGE_TTL, ttl); + + return replyMessage.release(); + } else { + THROW_MQEXCEPTION(MQClientException, "create reply message fail, requestMessage error, property[" + + MQMessageConst::PROPERTY_CLUSTER + "] is null.", + ClientErrorCode::CREATE_REPLY_MESSAGE_EXCEPTION); + } + } + THROW_MQEXCEPTION(MQClientException, "create reply message fail, requestMessage cannot be null.", + ClientErrorCode::CREATE_REPLY_MESSAGE_EXCEPTION); +} + +const std::string& MessageUtil::getReplyToClient(const MQMessagePtr msg) { + return msg->getProperty(MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT); +} + +} // namespace rocketmq diff --git a/src/producer/CorrelationIdUtil.hpp b/src/producer/CorrelationIdUtil.hpp new file mode 100644 index 000000000..e34bd116c --- /dev/null +++ b/src/producer/CorrelationIdUtil.hpp @@ -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. + */ +#ifndef __CORRELATION_ID_UTIL_HPP__ +#define __CORRELATION_ID_UTIL_HPP__ + +#include +#include + +#include "UtilAll.h" + +namespace rocketmq { + +class CorrelationIdUtil { + public: + static std::string createCorrelationId() { + static std::atomic seqAllocator; + return UtilAll::to_string(seqAllocator.fetch_add(1)); + } +}; + +} // namespace rocketmq + +#endif // __CORRELATION_ID_UTIL_HPP__ diff --git a/src/producer/DefaultMQProducer.cpp b/src/producer/DefaultMQProducer.cpp index a7f11ee41..ce7e1a56b 100644 --- a/src/producer/DefaultMQProducer.cpp +++ b/src/producer/DefaultMQProducer.cpp @@ -16,24 +16,21 @@ */ #include "DefaultMQProducer.h" +#include "DefaultMQProducerConfigImpl.h" #include "DefaultMQProducerImpl.h" #include "UtilAll.h" namespace rocketmq { -DefaultMQProducerConfig::DefaultMQProducerConfig() - : m_maxMessageSize(1024 * 1024 * 4), - m_compressMsgBodyOverHowmuch(1024 * 4), - m_compressLevel(5), - m_sendMsgTimeout(3000), - m_retryTimes(2), - m_retryTimes4Async(2), - m_retryAnotherBrokerWhenNotStoreOK(false) {} - DefaultMQProducer::DefaultMQProducer(const std::string& groupname) : DefaultMQProducer(groupname, nullptr) {} -DefaultMQProducer::DefaultMQProducer(const std::string& groupname, std::shared_ptr rpcHook) - : m_producerDelegate(nullptr) { +DefaultMQProducer::DefaultMQProducer(const std::string& groupname, RPCHookPtr rpcHook) + : DefaultMQProducer(groupname, rpcHook, std::make_shared()) {} + +DefaultMQProducer::DefaultMQProducer(const std::string& groupname, + RPCHookPtr rpcHook, + DefaultMQProducerConfigPtr producerConfig) + : DefaultMQProducerConfigProxy(producerConfig), m_producerDelegate(nullptr) { // set default group name if (groupname.empty()) { setGroupName(DEFAULT_PRODUCER_GROUP); @@ -41,7 +38,7 @@ DefaultMQProducer::DefaultMQProducer(const std::string& groupname, std::shared_p setGroupName(groupname); } - m_producerDelegate = DefaultMQProducerImpl::create(this, rpcHook); + m_producerDelegate = DefaultMQProducerImpl::create(getRealConfig(), rpcHook); } DefaultMQProducer::~DefaultMQProducer() = default; @@ -145,16 +142,21 @@ SendResult DefaultMQProducer::send(std::vector& msgs, const MQMess return m_producerDelegate->send(msgs, mq, timeout); } +MQMessagePtr DefaultMQProducer::request(MQMessagePtr msg, long timeout) { + return m_producerDelegate->request(msg, timeout); +} + bool DefaultMQProducer::isSendLatencyFaultEnable() const { - return dynamic_cast(m_producerDelegate.get())->isSendLatencyFaultEnable(); + return std::dynamic_pointer_cast(m_producerDelegate)->isSendLatencyFaultEnable(); } void DefaultMQProducer::setSendLatencyFaultEnable(bool sendLatencyFaultEnable) { - dynamic_cast(m_producerDelegate.get())->setSendLatencyFaultEnable(sendLatencyFaultEnable); + std::dynamic_pointer_cast(m_producerDelegate) + ->setSendLatencyFaultEnable(sendLatencyFaultEnable); } -void DefaultMQProducer::setRPCHook(std::shared_ptr rpcHook) { - dynamic_cast(m_producerDelegate.get())->setRPCHook(rpcHook); +void DefaultMQProducer::setRPCHook(RPCHookPtr rpcHook) { + std::dynamic_pointer_cast(m_producerDelegate)->setRPCHook(rpcHook); } } // namespace rocketmq diff --git a/src/producer/DefaultMQProducerConfigImpl.cpp b/src/producer/DefaultMQProducerConfigImpl.cpp new file mode 100644 index 000000000..19545a12f --- /dev/null +++ b/src/producer/DefaultMQProducerConfigImpl.cpp @@ -0,0 +1,88 @@ +/* + * 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 "DefaultMQProducerConfigImpl.h" + +namespace rocketmq { + +DefaultMQProducerConfigImpl::DefaultMQProducerConfigImpl() + : m_maxMessageSize(1024 * 1024 * 4), // 4MB + m_compressMsgBodyOverHowmuch(1024 * 4), // 4KB + m_compressLevel(5), + m_sendMsgTimeout(3000), + m_retryTimes(2), + m_retryTimes4Async(2), + m_retryAnotherBrokerWhenNotStoreOK(false) {} + +int DefaultMQProducerConfigImpl::getMaxMessageSize() const { + return m_maxMessageSize; +} + +void DefaultMQProducerConfigImpl::setMaxMessageSize(int maxMessageSize) { + m_maxMessageSize = maxMessageSize; +} + +int DefaultMQProducerConfigImpl::getCompressMsgBodyOverHowmuch() const { + return m_compressMsgBodyOverHowmuch; +} + +void DefaultMQProducerConfigImpl::setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch) { + m_compressMsgBodyOverHowmuch = compressMsgBodyOverHowmuch; +} + +int DefaultMQProducerConfigImpl::getCompressLevel() const { + return m_compressLevel; +} + +void DefaultMQProducerConfigImpl::setCompressLevel(int compressLevel) { + if ((compressLevel >= 0 && compressLevel <= 9) || compressLevel == -1) { + m_compressLevel = compressLevel; + } +} + +int DefaultMQProducerConfigImpl::getSendMsgTimeout() const { + return m_sendMsgTimeout; +} + +void DefaultMQProducerConfigImpl::setSendMsgTimeout(int sendMsgTimeout) { + m_sendMsgTimeout = sendMsgTimeout; +} + +int DefaultMQProducerConfigImpl::getRetryTimes() const { + return m_retryTimes; +} + +void DefaultMQProducerConfigImpl::setRetryTimes(int times) { + m_retryTimes = std::min(std::max(0, times), 15); +} + +int DefaultMQProducerConfigImpl::getRetryTimes4Async() const { + return m_retryTimes4Async; +} + +void DefaultMQProducerConfigImpl::setRetryTimes4Async(int times) { + m_retryTimes4Async = std::min(std::max(0, times), 15); +} + +bool DefaultMQProducerConfigImpl::isRetryAnotherBrokerWhenNotStoreOK() const { + return m_retryAnotherBrokerWhenNotStoreOK; +} + +void DefaultMQProducerConfigImpl::setRetryAnotherBrokerWhenNotStoreOK(bool retryAnotherBrokerWhenNotStoreOK) { + m_retryAnotherBrokerWhenNotStoreOK = retryAnotherBrokerWhenNotStoreOK; +} + +} // namespace rocketmq diff --git a/src/producer/DefaultMQProducerConfigImpl.h b/src/producer/DefaultMQProducerConfigImpl.h new file mode 100644 index 000000000..3ae0530e8 --- /dev/null +++ b/src/producer/DefaultMQProducerConfigImpl.h @@ -0,0 +1,63 @@ +/* + * 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 __DEFAULT_MQ_PRODUCER_CONFIG_IMPL_H__ +#define __DEFAULT_MQ_PRODUCER_CONFIG_IMPL_H__ + +#include "DefaultMQProducerConfig.h" +#include "MQClientConfigImpl.h" + +namespace rocketmq { + +class DefaultMQProducerConfigImpl : virtual public DefaultMQProducerConfig, public MQClientConfigImpl { + public: + DefaultMQProducerConfigImpl(); + virtual ~DefaultMQProducerConfigImpl() = default; + + int getMaxMessageSize() const override; + void setMaxMessageSize(int maxMessageSize) override; + + int getCompressMsgBodyOverHowmuch() const override; + void setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch) override; + + int getCompressLevel() const override; + void setCompressLevel(int compressLevel) override; + + int getSendMsgTimeout() const override; + void setSendMsgTimeout(int sendMsgTimeout) override; + + int getRetryTimes() const override; + void setRetryTimes(int times) override; + + int getRetryTimes4Async() const override; + void setRetryTimes4Async(int times) override; + + bool isRetryAnotherBrokerWhenNotStoreOK() const override; + void setRetryAnotherBrokerWhenNotStoreOK(bool retryAnotherBrokerWhenNotStoreOK) override; + + protected: + int m_maxMessageSize; // default: 4 MB + int m_compressMsgBodyOverHowmuch; // default: 4 KB + int m_compressLevel; + int m_sendMsgTimeout; + int m_retryTimes; + int m_retryTimes4Async; + bool m_retryAnotherBrokerWhenNotStoreOK; +}; + +} // namespace rocketmq + +#endif // __DEFAULT_MQ_PRODUCER_CONFIG_IMPL_H__ diff --git a/src/producer/DefaultMQProducerImpl.cpp b/src/producer/DefaultMQProducerImpl.cpp index c79b2363b..3baa27614 100644 --- a/src/producer/DefaultMQProducerImpl.cpp +++ b/src/producer/DefaultMQProducerImpl.cpp @@ -23,8 +23,9 @@ #include #endif -#include "CommandHeader.h" +#include "ClientErrorCode.h" #include "CommunicationMode.h" +#include "CorrelationIdUtil.hpp" #include "Logging.h" #include "MQClientAPIImpl.h" #include "MQClientException.h" @@ -36,16 +37,18 @@ #include "MessageBatch.h" #include "MessageClientIDSetter.h" #include "MessageSysFlag.h" +#include "RequestFutureTable.h" #include "TopicPublishInfo.h" #include "TransactionMQProducer.h" #include "Validators.h" +#include "protocol/header/CommandHeader.h" namespace rocketmq { -DefaultMQProducerImpl::DefaultMQProducerImpl(DefaultMQProducerConfig* config) +DefaultMQProducerImpl::DefaultMQProducerImpl(DefaultMQProducerConfigPtr config) : DefaultMQProducerImpl(config, nullptr) {} -DefaultMQProducerImpl::DefaultMQProducerImpl(DefaultMQProducerConfig* config, std::shared_ptr rpcHook) +DefaultMQProducerImpl::DefaultMQProducerImpl(DefaultMQProducerConfigPtr config, RPCHookPtr rpcHook) : MQClientImpl(config, rpcHook), m_producerConfig(config), m_mqFaultStrategy(new MQFaultStrategy()), @@ -69,7 +72,7 @@ void DefaultMQProducerImpl::start() { m_producerConfig->changeInstanceNameToPID(); - LOG_INFO_NEW("DefaultMQProducerImpl:{} start", m_producerConfig->getGroupName()); + LOG_INFO_NEW("DefaultMQProducerImpl: {} start", m_producerConfig->getGroupName()); MQClientImpl::start(); @@ -136,7 +139,7 @@ SendResult DefaultMQProducerImpl::send(MQMessagePtr msg, long timeout) { std::unique_ptr sendResult(sendDefaultImpl(msg, ComMode_SYNC, nullptr, timeout)); return *sendResult; } catch (MQException& e) { - LOG_ERROR(e.what()); + LOG_ERROR_NEW("send failed, exception:{}", e.what()); throw e; } } @@ -156,7 +159,7 @@ SendResult DefaultMQProducerImpl::send(MQMessagePtr msg, const MQMessageQueue& m std::unique_ptr sendResult(sendKernelImpl(msg, mq, ComMode_SYNC, nullptr, nullptr, timeout)); return *sendResult; } catch (MQException& e) { - LOG_ERROR(e.what()); + LOG_ERROR_NEW("send failed, exception:{}", e.what()); throw e; } } @@ -169,9 +172,9 @@ void DefaultMQProducerImpl::send(MQMessagePtr msg, SendCallback* sendCallback, l try { (void)sendDefaultImpl(msg, ComMode_ASYNC, sendCallback, timeout); } catch (MQException& e) { - LOG_ERROR(e.what()); + LOG_ERROR_NEW("send failed, exception:{}", e.what()); sendCallback->onException(e); - if (sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_ATUO_DELETE) { + if (sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { deleteAndZero(sendCallback); } } catch (std::exception& e) { @@ -202,9 +205,9 @@ void DefaultMQProducerImpl::send(MQMessagePtr msg, THROW_MQEXCEPTION(MQClientException, info, e.GetError()); } } catch (MQException& e) { - LOG_ERROR(e.what()); + LOG_ERROR_NEW("send failed, exception:{}", e.what()); sendCallback->onException(e); - if (sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_ATUO_DELETE) { + if (sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { deleteAndZero(sendCallback); } } catch (std::exception& e) { @@ -246,7 +249,7 @@ SendResult DefaultMQProducerImpl::send(MQMessagePtr msg, MessageQueueSelector* s std::unique_ptr result(sendSelectImpl(msg, selector, arg, ComMode_SYNC, nullptr, timeout)); return *result.get(); } catch (MQException& e) { - LOG_ERROR(e.what()); + LOG_ERROR_NEW("send failed, exception:{}", e.what()); throw e; } } @@ -271,9 +274,9 @@ void DefaultMQProducerImpl::send(MQMessagePtr msg, THROW_MQEXCEPTION(MQClientException, info, e.GetError()); } } catch (MQException& e) { - LOG_ERROR(e.what()); + LOG_ERROR_NEW("send failed, exception:{}", e.what()); sendCallback->onException(e); - if (sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_ATUO_DELETE) { + if (sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { deleteAndZero(sendCallback); } } catch (std::exception& e) { @@ -297,7 +300,7 @@ TransactionSendResult DefaultMQProducerImpl::sendMessageInTransaction(MQMessageP sendMessageInTransactionImpl(msg, arg, m_producerConfig->getSendMsgTimeout())); return *sendResult; } catch (MQException& e) { - LOG_ERROR(e.what()); + LOG_ERROR_NEW("sendMessageInTransaction failed, exception:{}", e.what()); throw e; } } @@ -328,19 +331,94 @@ MessageBatch* DefaultMQProducerImpl::batch(std::vector& msgs) { } try { - MessageBatch* msgBatch = MessageBatch::generateFromList(msgs); + std::unique_ptr msgBatch(MessageBatch::generateFromList(msgs)); for (auto& message : msgBatch->getMessages()) { Validators::checkMessage(*message, m_producerConfig->getMaxMessageSize()); MessageClientIDSetter::setUniqID(*message); } msgBatch->setBody(msgBatch->encode()); - return msgBatch; + return msgBatch.release(); } catch (std::exception& e) { THROW_MQEXCEPTION(MQClientException, "Failed to initiate the MessageBatch", -1); } } -const MQMessageQueue& DefaultMQProducerImpl::selectOneMessageQueue(TopicPublishInfo* tpInfo, +class RequestSendCallback : public AutoDeleteSendCallback { + public: + RequestSendCallback(std::shared_ptr requestFuture) : m_requestFuture(requestFuture) {} + + void onSuccess(SendResult& sendResult) override { m_requestFuture->setSendRequestOk(true); } + + void onException(MQException& e) noexcept override { + m_requestFuture->setSendRequestOk(false); + m_requestFuture->putResponseMessage(nullptr); + m_requestFuture->setCause(std::make_exception_ptr(e)); + } + + private: + std::shared_ptr m_requestFuture; +}; + +MQMessagePtr DefaultMQProducerImpl::request(MQMessagePtr msg, long timeout) { + auto beginTimestamp = UtilAll::currentTimeMillis(); + prepareSendRequest(msg, timeout); + const auto& correlationId = msg->getProperty(MQMessageConst::PROPERTY_CORRELATION_ID); + + std::exception_ptr eptr = nullptr; + std::unique_ptr responseMessage; + try { + auto requestResponseFuture = std::make_shared(correlationId, timeout, nullptr); + RequestFutureTable::putRequestFuture(correlationId, requestResponseFuture); + + auto cost = UtilAll::currentTimeMillis() - beginTimestamp; + sendDefaultImpl(msg, CommunicationMode::ComMode_ASYNC, new RequestSendCallback(requestResponseFuture), + timeout - cost); + + responseMessage.reset(requestResponseFuture->waitResponseMessage(timeout - cost)); + if (responseMessage == nullptr) { + if (requestResponseFuture->isSendRequestOk()) { + std::string info = "send request message to <" + msg->getTopic() + "> OK, but wait reply message timeout, " + + UtilAll::to_string(timeout) + " ms."; + THROW_MQEXCEPTION(RequestTimeoutException, info, ClientErrorCode::REQUEST_TIMEOUT_EXCEPTION); + } else { + std::string info = "send request message to <" + msg->getTopic() + "> fail"; + THROW_MQEXCEPTION2(MQClientException, info, -1, requestResponseFuture->getCause()); + } + } + } catch (...) { + eptr = std::current_exception(); + } + + // finally + RequestFutureTable::removeRequestFuture(correlationId); + + if (eptr != nullptr) { + std::rethrow_exception(eptr); + } + + return responseMessage.release(); +} + +void DefaultMQProducerImpl::prepareSendRequest(MQMessagePtr msg, long timeout) { + const auto correlationId = CorrelationIdUtil::createCorrelationId(); + const auto& requestClientId = m_clientInstance->getClientId(); + MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_CORRELATION_ID, correlationId); + MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT, requestClientId); + MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_MESSAGE_TTL, UtilAll::to_string(timeout)); + + auto hasRouteData = m_clientInstance->getTopicRouteData(msg->getTopic()) != nullptr; + if (!hasRouteData) { + auto beginTimestamp = UtilAll::currentTimeMillis(); + m_clientInstance->tryToFindTopicPublishInfo(msg->getTopic()); + m_clientInstance->sendHeartbeatToAllBrokerWithLock(); + auto cost = UtilAll::currentTimeMillis() - beginTimestamp; + if (cost > 500) { + LOG_WARN_NEW("prepare send request for <{}> cost {} ms", msg->getTopic(), cost); + } + } +} + +const MQMessageQueue& DefaultMQProducerImpl::selectOneMessageQueue(const TopicPublishInfo* tpInfo, const std::string& lastBrokerName) { return m_mqFaultStrategy->selectOneMessageQueue(tpInfo, lastBrokerName); } @@ -358,7 +436,7 @@ SendResult* DefaultMQProducerImpl::sendDefaultImpl(MQMessagePtr msg, uint64_t beginTimestampFirst = UtilAll::currentTimeMillis(); uint64_t beginTimestampPrev = beginTimestampFirst; uint64_t endTimestamp = beginTimestampFirst; - TopicPublishInfoPtr topicPublishInfo = m_clientInstance->tryToFindTopicPublishInfo(msg->getTopic()); + auto topicPublishInfo = m_clientInstance->tryToFindTopicPublishInfo(msg->getTopic()); if (topicPublishInfo != nullptr && topicPublishInfo->ok()) { bool callTimeout = false; std::unique_ptr sendResult; @@ -370,7 +448,7 @@ SendResult* DefaultMQProducerImpl::sendDefaultImpl(MQMessagePtr msg, lastBrokerName = mq.getBrokerName(); try { - LOG_DEBUG("send to mq:%s", mq.toString().data()); + LOG_DEBUG_NEW("send to mq: {}", mq.toString()); beginTimestampPrev = UtilAll::currentTimeMillis(); if (times > 0) { @@ -402,11 +480,11 @@ SendResult* DefaultMQProducerImpl::sendDefaultImpl(MQMessagePtr msg, default: break; } - } catch (std::exception& e) { + } catch (const std::exception& e) { // TODO: 区分异常类型 endTimestamp = UtilAll::currentTimeMillis(); updateFaultItem(mq.getBrokerName(), endTimestamp - beginTimestampPrev, true); - LOG_ERROR_NEW("send failed of times:{}, brokerName:{}. exception:{}", times, mq.getBrokerName(), e.what()); + LOG_WARN_NEW("send failed of times:{}, brokerName:{}. exception:{}", times, mq.getBrokerName(), e.what()); continue; } @@ -609,9 +687,9 @@ TransactionSendResult* DefaultMQProducerImpl::sendMessageInTransactionImpl(MQMes } TransactionListener* DefaultMQProducerImpl::getCheckListener() { - if (std::type_index(typeid(*m_producerConfig)) == std::type_index(typeid(TransactionMQProducer))) { - auto* producer = static_cast(m_producerConfig); - return producer->getTransactionListener(); + auto transactionProducerConfig = std::dynamic_pointer_cast(m_producerConfig); + if (transactionProducerConfig != nullptr) { + return transactionProducerConfig->getTransactionListener(); } return nullptr; }; @@ -645,7 +723,7 @@ void DefaultMQProducerImpl::checkTransactionStateImpl(const std::string& addr, } LocalTransactionState localTransactionState = UNKNOWN; - std::exception_ptr exception; + std::exception_ptr exception = nullptr; try { localTransactionState = transactionCheckListener->checkLocalTransaction(*message); } catch (MQException& e) { @@ -683,7 +761,7 @@ void DefaultMQProducerImpl::checkTransactionStateImpl(const std::string& addr, } std::string remark; - if (exception) { + if (exception != nullptr) { remark = "checkLocalTransactionState Exception: " + UtilAll::to_string(exception); } diff --git a/src/producer/DefaultMQProducerImpl.h b/src/producer/DefaultMQProducerImpl.h index 990763aa3..4a2f27385 100644 --- a/src/producer/DefaultMQProducerImpl.h +++ b/src/producer/DefaultMQProducerImpl.h @@ -37,7 +37,7 @@ class DefaultMQProducerImpl : public std::enable_shared_from_this& msgs, const MQMessageQueue& mq) override; SendResult send(std::vector& msgs, const MQMessageQueue& mq, long timeout) override; + MQMessagePtr request(MQMessagePtr msg, long timeout) override; + public: // MQProducerInner TransactionListener* getCheckListener() override; @@ -103,7 +105,7 @@ class DefaultMQProducerImpl : public std::enable_shared_from_this topicPublishInfo, + std::shared_ptr topicPublishInfo, long timeout); SendResult* sendSelectImpl(MQMessagePtr msg, MessageQueueSelector* selector, @@ -144,8 +146,10 @@ class DefaultMQProducerImpl : public std::enable_shared_from_this& msgs); + void prepareSendRequest(MQMessagePtr msg, long timeout); + private: - DefaultMQProducerConfig* m_producerConfig; + DefaultMQProducerConfigPtr m_producerConfig; std::unique_ptr m_mqFaultStrategy; std::unique_ptr m_checkTransactionExecutor; }; diff --git a/src/producer/LatencyFaultTolerancyImpl.cpp b/src/producer/LatencyFaultTolerancyImpl.cpp index 1826b8a06..7d428ed48 100644 --- a/src/producer/LatencyFaultTolerancyImpl.cpp +++ b/src/producer/LatencyFaultTolerancyImpl.cpp @@ -38,7 +38,7 @@ void LatencyFaultTolerancyImpl::updateFaultItem(const std::string& name, bool LatencyFaultTolerancyImpl::isAvailable(const std::string& name) { std::lock_guard lock(m_faultItemTableMutex); - auto it = m_faultItemTable.find(name); + const auto& it = m_faultItemTable.find(name); if (it != m_faultItemTable.end()) { return it->second.isAvailable(); } diff --git a/src/producer/MQFaultStrategy.cpp b/src/producer/MQFaultStrategy.cpp index 6ce139c98..a73b14920 100644 --- a/src/producer/MQFaultStrategy.cpp +++ b/src/producer/MQFaultStrategy.cpp @@ -23,18 +23,16 @@ MQFaultStrategy::MQFaultStrategy() : m_sendLatencyFaultEnable(false) { m_notAvailableDuration = std::vector{0L, 0L, 30000L, 60000L, 120000L, 180000L, 600000L}; } -const MQMessageQueue& MQFaultStrategy::selectOneMessageQueue(TopicPublishInfo* tpInfo, +const MQMessageQueue& MQFaultStrategy::selectOneMessageQueue(const TopicPublishInfo* tpInfo, const std::string& lastBrokerName) { if (m_sendLatencyFaultEnable) { { auto index = tpInfo->getSendWhichQueue().fetch_add(1); - std::lock_guard lock(tpInfo->getMessageQueueListMutex()); - auto& messageQueueList = tpInfo->getMessageQueueList(); + const auto& messageQueueList = tpInfo->getMessageQueueList(); for (size_t i = 0; i < messageQueueList.size(); i++) { auto pos = index++ % messageQueueList.size(); const auto& mq = messageQueueList[pos]; if (m_latencyFaultTolerance.isAvailable(mq.getBrokerName())) { - // FIXME: why not mq.getBrokerName() != lastBrokerName if (lastBrokerName.empty() || mq.getBrokerName() != lastBrokerName) { return mq; } diff --git a/src/producer/MQFaultStrategy.h b/src/producer/MQFaultStrategy.h index 2615cc3b6..4110d7fc9 100644 --- a/src/producer/MQFaultStrategy.h +++ b/src/producer/MQFaultStrategy.h @@ -46,7 +46,7 @@ class MQFaultStrategy { m_sendLatencyFaultEnable = sendLatencyFaultEnable; } - const MQMessageQueue& selectOneMessageQueue(TopicPublishInfo* tpInfo, const std::string& lastBrokerName); + const MQMessageQueue& selectOneMessageQueue(const TopicPublishInfo* tpInfo, const std::string& lastBrokerName); void updateFaultItem(const std::string& brokerName, const long currentLatency, bool isolation); diff --git a/src/producer/RequestFutureTable.cpp b/src/producer/RequestFutureTable.cpp new file mode 100644 index 000000000..5a8b444d9 --- /dev/null +++ b/src/producer/RequestFutureTable.cpp @@ -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. + */ +#include "RequestFutureTable.h" + +namespace rocketmq { + +std::map> RequestFutureTable::s_futureTable; +std::mutex RequestFutureTable::s_futureTableMutex; + +void RequestFutureTable::putRequestFuture(std::string correlationId, std::shared_ptr future) { + std::lock_guard lock(s_futureTableMutex); + s_futureTable[correlationId] = future; +} + +std::shared_ptr RequestFutureTable::removeRequestFuture(std::string correlationId) { + std::lock_guard lock(s_futureTableMutex); + const auto& it = s_futureTable.find(correlationId); + if (it != s_futureTable.end()) { + auto requestFuture = it->second; + s_futureTable.erase(it); + return requestFuture; + } + return nullptr; +} + +} // namespace rocketmq diff --git a/src/producer/RequestFutureTable.h b/src/producer/RequestFutureTable.h new file mode 100644 index 000000000..ed589ecc3 --- /dev/null +++ b/src/producer/RequestFutureTable.h @@ -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 __REQUEST_FUTURE_TABLE__ +#define __REQUEST_FUTURE_TABLE__ + +#include +#include +#include + +#include "RequestResponseFuture.h" + +namespace rocketmq { + +class RequestFutureTable { + public: + static void putRequestFuture(std::string correlationId, std::shared_ptr future); + static std::shared_ptr removeRequestFuture(std::string correlationId); + + private: + static std::map> s_futureTable; + static std::mutex s_futureTableMutex; +}; + +} // namespace rocketmq + +#endif // __REQUEST_FUTURE_TABLE__ diff --git a/src/producer/RequestResponseFuture.cpp b/src/producer/RequestResponseFuture.cpp new file mode 100644 index 000000000..92e86a403 --- /dev/null +++ b/src/producer/RequestResponseFuture.cpp @@ -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 "RequestResponseFuture.h" + +#include "Logging.h" +#include "UtilAll.h" + +namespace rocketmq { + +RequestResponseFuture::RequestResponseFuture(const std::string& correlationId, + long timeoutMillis, + RequestCallback* requestCallback) + : m_correlationId(correlationId), + m_requestCallback(requestCallback), + m_beginTimestamp(UtilAll::currentTimeMillis()), + m_requestMsg(nullptr), + m_timeoutMillis(timeoutMillis), + m_countDownLatch(nullptr), + m_responseMsg(nullptr), + m_sendRequestOk(false), + m_cause(nullptr) { + if (nullptr == requestCallback) { + m_countDownLatch.reset(new latch(1)); + } +} + +void RequestResponseFuture::executeRequestCallback() noexcept { + if (m_requestCallback != nullptr) { + if (m_sendRequestOk && m_cause == nullptr) { + try { + m_requestCallback->onSuccess(std::move(m_responseMsg)); + } catch (const std::exception& e) { + LOG_WARN_NEW("RequestCallback throw an exception: {}", e.what()); + } + } else { + try { + std::rethrow_exception(m_cause); + } catch (MQException& e) { + m_requestCallback->onException(e); + } catch (const std::exception& e) { + LOG_WARN_NEW("unexpected exception in RequestResponseFuture: {}", e.what()); + } + } + + // auto delete callback + if (m_requestCallback->getRequestCallbackType() == REQUEST_CALLBACK_TYPE_AUTO_DELETE) { + deleteAndZero(m_requestCallback); + } + } +} + +bool RequestResponseFuture::isTimeout() { + auto diff = UtilAll::currentTimeMillis() - m_beginTimestamp; + return diff > m_timeoutMillis; +} + +MQMessagePtr RequestResponseFuture::waitResponseMessage(int64_t timeout) { + if (m_countDownLatch != nullptr) { + if (timeout < 0) { + timeout = 0; + } + m_countDownLatch->wait(timeout, time_unit::milliseconds); + } + return m_responseMsg.release(); +} + +void RequestResponseFuture::putResponseMessage(MQMessagePtr3 responseMsg) { + m_responseMsg = std::move(responseMsg); + if (m_countDownLatch != nullptr) { + m_countDownLatch->count_down(); + } +} + +bool RequestResponseFuture::isSendRequestOk() { + return m_sendRequestOk; +} + +void RequestResponseFuture::setSendRequestOk(bool sendRequestOk) { + m_sendRequestOk = sendRequestOk; +} + +std::exception_ptr RequestResponseFuture::getCause() { + return m_cause; +} + +void RequestResponseFuture::setCause(std::exception_ptr cause) { + m_cause = cause; +} + +} // namespace rocketmq diff --git a/src/producer/RequestResponseFuture.h b/src/producer/RequestResponseFuture.h new file mode 100644 index 000000000..0ebb2351d --- /dev/null +++ b/src/producer/RequestResponseFuture.h @@ -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 __REQUEST_RESPONSE_FUTURE__ +#define __REQUEST_RESPONSE_FUTURE__ + +#include +#include + +#include "MQMessage.h" +#include "RequestCallback.h" +#include "concurrent/latch.hpp" + +namespace rocketmq { + +class RequestResponseFuture { + public: + RequestResponseFuture(const std::string& correlationId, long timeoutMillis, RequestCallback* requestCallback); + + void executeRequestCallback() noexcept; + + bool isTimeout(); + + MQMessagePtr waitResponseMessage(int64_t timeout); + void putResponseMessage(MQMessagePtr3 responseMsg); + + bool isSendRequestOk(); + void setSendRequestOk(bool sendRequestOk); + + std::exception_ptr getCause(); + void setCause(std::exception_ptr cause); + + private: + std::string m_correlationId; + RequestCallback* m_requestCallback; + uint64_t m_beginTimestamp; + MQMessagePtr m_requestMsg; + long m_timeoutMillis; + std::unique_ptr m_countDownLatch; // use for synchronization rpc + MQMessagePtr3 m_responseMsg; + bool m_sendRequestOk; + std::exception_ptr m_cause; +}; + +} // namespace rocketmq + +#endif // __REQUEST_RESPONSE_FUTURE__ diff --git a/src/producer/TopicPublishInfo.h b/src/producer/TopicPublishInfo.h index 0bb8c3cf7..af9c231a3 100644 --- a/src/producer/TopicPublishInfo.h +++ b/src/producer/TopicPublishInfo.h @@ -21,13 +21,14 @@ #include #include +#include "MQClientException.h" #include "MQMessageQueue.h" #include "TopicRouteData.h" namespace rocketmq { class TopicPublishInfo; -typedef std::shared_ptr TopicPublishInfoPtr; +typedef std::shared_ptr TopicPublishInfoPtr; class TopicPublishInfo { public: @@ -38,48 +39,52 @@ class TopicPublishInfo { virtual ~TopicPublishInfo() = default; - bool isOrderTopic() { return m_orderTopic; } + bool isOrderTopic() const { return m_orderTopic; } void setOrderTopic(bool orderTopic) { m_orderTopic = orderTopic; } - bool ok() { - std::lock_guard lock(m_queuelock); - return !m_messageQueueList.empty(); - } - - QueuesVec& getMessageQueueList() { return m_messageQueueList; } + bool ok() const { return !m_messageQueueList.empty(); } - std::mutex& getMessageQueueListMutex() { return m_queuelock; } + const QueuesVec& getMessageQueueList() const { return m_messageQueueList; } - std::atomic& getSendWhichQueue() { return m_sendWhichQueue; } + std::atomic& getSendWhichQueue() const { return m_sendWhichQueue; } bool isHaveTopicRouterInfo() { return m_haveTopicRouterInfo; } void setHaveTopicRouterInfo(bool haveTopicRouterInfo) { m_haveTopicRouterInfo = haveTopicRouterInfo; } - MQMessageQueue& selectOneMessageQueue(const std::string& lastBrokerName) { + const MQMessageQueue& selectOneMessageQueue(const std::string& lastBrokerName) const { if (!lastBrokerName.empty()) { - auto index = m_sendWhichQueue.fetch_add(1); - std::lock_guard lock(m_queuelock); - for (size_t i = 0; i < m_messageQueueList.size(); i++) { - auto pos = index++ % m_messageQueueList.size(); - auto& mq = m_messageQueueList[pos]; - if (mq.getBrokerName() != lastBrokerName) { - return mq; + auto mqSize = m_messageQueueList.size(); + if (mqSize <= 1) { + if (mqSize == 0) { + LOG_ERROR_NEW("[BUG] messageQueueList is empty"); + THROW_MQEXCEPTION(MQClientException, "messageQueueList is empty", -1); } + return m_messageQueueList[0]; + } else { + // NOTE: If it possible, mq in same broker is nonadjacent. + auto index = m_sendWhichQueue.fetch_add(1); + for (size_t i = 0; i < 2; i++) { + auto pos = index++ % m_messageQueueList.size(); + auto& mq = m_messageQueueList[pos]; + if (mq.getBrokerName() != lastBrokerName) { + return mq; + } + } + return m_messageQueueList[(index - 2) % m_messageQueueList.size()]; } } return selectOneMessageQueue(); } - MQMessageQueue& selectOneMessageQueue() { + const MQMessageQueue& selectOneMessageQueue() const { auto index = m_sendWhichQueue.fetch_add(1); - std::lock_guard lock(m_queuelock); auto pos = index % m_messageQueueList.size(); return m_messageQueueList[pos]; } - int getQueueIdByBroker(const std::string& brokerName) { + int getQueueIdByBroker(const std::string& brokerName) const { for (const auto& queueData : m_topicRouteData->getQueueDatas()) { if (queueData.brokerName == brokerName) { return queueData.writeQueueNums; @@ -95,10 +100,8 @@ class TopicPublishInfo { bool m_orderTopic; bool m_haveTopicRouterInfo; - QueuesVec m_messageQueueList; - std::mutex m_queuelock; - - std::atomic m_sendWhichQueue; + QueuesVec m_messageQueueList; // no change after build + mutable std::atomic m_sendWhichQueue; TopicRouteDataPtr m_topicRouteData; // no change after set }; diff --git a/src/producer/TransactionMQProducer.cpp b/src/producer/TransactionMQProducer.cpp index 405d86d33..b258dadd0 100644 --- a/src/producer/TransactionMQProducer.cpp +++ b/src/producer/TransactionMQProducer.cpp @@ -17,33 +17,44 @@ #include "TransactionMQProducer.h" #include "DefaultMQProducerImpl.h" +#include "TransactionMQProducerConfigImpl.h" namespace rocketmq { -TransactionMQProducerConfig::TransactionMQProducerConfig() : m_transactionListener(nullptr) {} - TransactionMQProducer::TransactionMQProducer(const std::string& groupname) : TransactionMQProducer(groupname, nullptr) {} -TransactionMQProducer::TransactionMQProducer(const std::string& groupname, std::shared_ptr rpcHook) - : DefaultMQProducer(groupname, rpcHook) {} +TransactionMQProducer::TransactionMQProducer(const std::string& groupname, RPCHookPtr rpcHook) + : DefaultMQProducer(groupname, rpcHook, std::make_shared()) {} TransactionMQProducer::~TransactionMQProducer() = default; +TransactionListener* TransactionMQProducer::getTransactionListener() const { + auto transactionProducerConfig = std::dynamic_pointer_cast(getRealConfig()); + if (transactionProducerConfig != nullptr) { + return transactionProducerConfig->getTransactionListener(); + } + return nullptr; +} + +void TransactionMQProducer::setTransactionListener(TransactionListener* transactionListener) { + auto transactionProducerConfig = std::dynamic_pointer_cast(getRealConfig()); + if (transactionProducerConfig != nullptr) { + transactionProducerConfig->setTransactionListener(transactionListener); + } +} + void TransactionMQProducer::start() { - dynamic_cast(m_producerDelegate.get())->initTransactionEnv(); + std::dynamic_pointer_cast(m_producerDelegate)->initTransactionEnv(); DefaultMQProducer::start(); } void TransactionMQProducer::shutdown() { DefaultMQProducer::shutdown(); - dynamic_cast(m_producerDelegate.get())->destroyTransactionEnv(); + std::dynamic_pointer_cast(m_producerDelegate)->destroyTransactionEnv(); } TransactionSendResult TransactionMQProducer::sendMessageInTransaction(MQMessagePtr msg, void* arg) { - if (nullptr == m_transactionListener) { - THROW_MQEXCEPTION(MQClientException, "TransactionListener is null", -1); - } return m_producerDelegate->sendMessageInTransaction(msg, arg); } diff --git a/src/producer/TransactionMQProducerConfigImpl.cpp b/src/producer/TransactionMQProducerConfigImpl.cpp new file mode 100644 index 000000000..d3a3dbdfa --- /dev/null +++ b/src/producer/TransactionMQProducerConfigImpl.cpp @@ -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 "TransactionMQProducerConfigImpl.h" + +namespace rocketmq { + +TransactionMQProducerConfigImpl::TransactionMQProducerConfigImpl() : m_transactionListener(nullptr) {} + +TransactionListener* TransactionMQProducerConfigImpl::getTransactionListener() const { + return m_transactionListener; +} + +void TransactionMQProducerConfigImpl::setTransactionListener(TransactionListener* transactionListener) { + m_transactionListener = transactionListener; +} + +} // namespace rocketmq diff --git a/src/producer/TransactionMQProducerConfigImpl.h b/src/producer/TransactionMQProducerConfigImpl.h new file mode 100644 index 000000000..c12205149 --- /dev/null +++ b/src/producer/TransactionMQProducerConfigImpl.h @@ -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 __TRANSACTION_MQ_PRODUCER_CONFIG_IMPL_H__ +#define __TRANSACTION_MQ_PRODUCER_CONFIG_IMPL_H__ + +#include "DefaultMQProducerConfigImpl.h" +#include "TransactionMQProducerConfig.h" + +namespace rocketmq { + +class TransactionMQProducerConfigImpl : virtual public TransactionMQProducerConfig, public DefaultMQProducerConfigImpl { + public: + TransactionMQProducerConfigImpl(); + virtual ~TransactionMQProducerConfigImpl() = default; + + public: // TransactionMQProducerConfig + TransactionListener* getTransactionListener() const override; + void setTransactionListener(TransactionListener* transactionListener) override; + + protected: + TransactionListener* m_transactionListener; +}; + +} // namespace rocketmq + +#endif // __TRANSACTION_MQ_PRODUCER_CONFIG_IMPL_H__ diff --git a/src/protocol/MQProtos.h b/src/protocol/MQProtos.h index a7a416ebf..29c6d792a 100644 --- a/src/protocol/MQProtos.h +++ b/src/protocol/MQProtos.h @@ -17,183 +17,7 @@ #ifndef __MQ_PROTOS_H__ #define __MQ_PROTOS_H__ -namespace rocketmq { - -enum MQRequestCode { - // send msg to Broker - SEND_MESSAGE = 10, - // subscribe msg from Broker - PULL_MESSAGE = 11, - // query msg from Broker - QUERY_MESSAGE = 12, - // query Broker Offset - QUERY_BROKER_OFFSET = 13, - // query Consumer Offset from broker - QUERY_CONSUMER_OFFSET = 14, - // update Consumer Offset to broker - UPDATE_CONSUMER_OFFSET = 15, - // create or update Topic to broker - UPDATE_AND_CREATE_TOPIC = 17, - // get all topic config info from broker - GET_ALL_TOPIC_CONFIG = 21, - // git all topic list from broker - GET_TOPIC_CONFIG_LIST = 22, - // get topic name list from broker - GET_TOPIC_NAME_LIST = 23, - UPDATE_BROKER_CONFIG = 25, - GET_BROKER_CONFIG = 26, - TRIGGER_DELETE_FILES = 27, - GET_BROKER_RUNTIME_INFO = 28, - SEARCH_OFFSET_BY_TIMESTAMP = 29, - GET_MAX_OFFSET = 30, - GET_MIN_OFFSET = 31, - GET_EARLIEST_MSG_STORETIME = 32, - VIEW_MESSAGE_BY_ID = 33, - // send heartbeat to broker, and register itself - HEART_BEAT = 34, - // unregister client to broker - UNREGISTER_CLIENT = 35, - // send back consume fail msg to broker - CONSUMER_SEND_MSG_BACK = 36, - // Commit Or Rollback transaction - END_TRANSACTION = 37, - // get consumer list by group from broker - GET_CONSUMER_LIST_BY_GROUP = 38, - - CHECK_TRANSACTION_STATE = 39, - // broker send notify to consumer when consumer lists changes - NOTIFY_CONSUMER_IDS_CHANGED = 40, - // lock mq before orderly consume - LOCK_BATCH_MQ = 41, - // unlock mq after orderly consume - UNLOCK_BATCH_MQ = 42, - GET_ALL_CONSUMER_OFFSET = 43, - GET_ALL_DELAY_OFFSET = 45, - PUT_KV_CONFIG = 100, - GET_KV_CONFIG = 101, - DELETE_KV_CONFIG = 102, - REGISTER_BROKER = 103, - UNREGISTER_BROKER = 104, - GET_ROUTEINTO_BY_TOPIC = 105, - GET_BROKER_CLUSTER_INFO = 106, - UPDATE_AND_CREATE_SUBSCRIPTIONGROUP = 200, - GET_ALL_SUBSCRIPTIONGROUP_CONFIG = 201, - GET_TOPIC_STATS_INFO = 202, - GET_CONSUMER_CONNECTION_LIST = 203, - GET_PRODUCER_CONNECTION_LIST = 204, - WIPE_WRITE_PERM_OF_BROKER = 205, - - GET_ALL_TOPIC_LIST_FROM_NAMESERVER = 206, - DELETE_SUBSCRIPTIONGROUP = 207, - GET_CONSUME_STATS = 208, - SUSPEND_CONSUMER = 209, - RESUME_CONSUMER = 210, - RESET_CONSUMER_OFFSET_IN_CONSUMER = 211, - RESET_CONSUMER_OFFSET_IN_BROKER = 212, - ADJUST_CONSUMER_THREAD_POOL = 213, - WHO_CONSUME_THE_MESSAGE = 214, - - DELETE_TOPIC_IN_BROKER = 215, - DELETE_TOPIC_IN_NAMESRV = 216, - - GET_KV_CONFIG_BY_VALUE = 217, - - DELETE_KV_CONFIG_BY_VALUE = 218, - - GET_KVLIST_BY_NAMESPACE = 219, - - RESET_CONSUMER_CLIENT_OFFSET = 220, - - GET_CONSUMER_STATUS_FROM_CLIENT = 221, - - INVOKE_BROKER_TO_RESET_OFFSET = 222, - - INVOKE_BROKER_TO_GET_CONSUMER_STATUS = 223, - - QUERY_TOPIC_CONSUME_BY_WHO = 300, - - GET_TOPICS_BY_CLUSTER = 224, - - REGISTER_FILTER_SERVER = 301, - - REGISTER_MESSAGE_FILTER_CLASS = 302, - - QUERY_CONSUME_TIME_SPAN = 303, - - GET_SYSTEM_TOPIC_LIST_FROM_NS = 304, - GET_SYSTEM_TOPIC_LIST_FROM_BROKER = 305, - - CLEAN_EXPIRED_CONSUMEQUEUE = 306, - - GET_CONSUMER_RUNNING_INFO = 307, - - QUERY_CORRECTION_OFFSET = 308, - - CONSUME_MESSAGE_DIRECTLY = 309, - - SEND_MESSAGE_V2 = 310, - - GET_UNIT_TOPIC_LIST = 311, - GET_HAS_UNIT_SUB_TOPIC_LIST = 312, - GET_HAS_UNIT_SUB_UNUNIT_TOPIC_LIST = 313, - - CLONE_GROUP_OFFSET = 314, - - VIEW_BROKER_STATS_DATA = 315, - - SEND_BATCH_MESSAGE = 320 -}; - -enum MQResponseCode { - // rcv success response from broker - SUCCESS_VALUE = 0, - // rcv exception from broker - SYSTEM_ERROR = 1, - // rcv symtem busy from broker - SYSTEM_BUSY = 2, - // broker don't support the request code - REQUEST_CODE_NOT_SUPPORTED = 3, - // broker flush disk timeout error - FLUSH_DISK_TIMEOUT = 10, - // broker sync double write, slave broker not available - SLAVE_NOT_AVAILABLE = 11, - // broker sync double write, slave broker flush msg timeout - FLUSH_SLAVE_TIMEOUT = 12, - // broker rcv illegal mesage - MESSAGE_ILLEGAL = 13, - // service not available due to broker or namesrv in shutdown status - SERVICE_NOT_AVAILABLE = 14, - // this version is not supported on broker or namesrv - VERSION_NOT_SUPPORTED = 15, - // broker or Namesrv has no permission to do this operation - NO_PERMISSION = 16, - // topic is not exist on broker - TOPIC_NOT_EXIST = 17, - // broker already created this topic - TOPIC_EXIST_ALREADY = 18, - // pulled msg was not found - PULL_NOT_FOUND = 19, - // retry later - PULL_RETRY_IMMEDIATELY = 20, - // pull msg with wrong offset - PULL_OFFSET_MOVED = 21, - // could not find the query msg - QUERY_NOT_FOUND = 22, - - SUBSCRIPTION_PARSE_FAILED = 23, - SUBSCRIPTION_NOT_EXIST = 24, - SUBSCRIPTION_NOT_LATEST = 25, - SUBSCRIPTION_GROUP_NOT_EXIST = 26, - - TRANSACTION_SHOULD_COMMIT = 200, - TRANSACTION_SHOULD_ROLLBACK = 201, - TRANSACTION_STATE_UNKNOW = 202, - TRANSACTION_STATE_GROUP_WRONG = 203, - - CONSUMER_NOT_ONLINE = 206, - CONSUME_MSG_TIMEOUT = 207 -}; - -} // namespace rocketmq +#include "RequestCode.h" +#include "ResponseCode.h" #endif // __MQ_PROTOS_H__ diff --git a/src/protocol/ProcessQueueInfo.h b/src/protocol/ProcessQueueInfo.h index f9ee5e81c..3d2ea6da0 100644 --- a/src/protocol/ProcessQueueInfo.h +++ b/src/protocol/ProcessQueueInfo.h @@ -70,7 +70,6 @@ class ProcessQueueInfo { outJson["droped"] = droped; outJson["lastPullTimestamp"] = UtilAll::to_string(lastPullTimestamp); outJson["lastConsumeTimestamp"] = UtilAll::to_string(lastConsumeTimestamp); - return outJson; } diff --git a/src/protocol/RemotingCommand.cpp b/src/protocol/RemotingCommand.cpp index 3bc9067f0..413edbc35 100644 --- a/src/protocol/RemotingCommand.cpp +++ b/src/protocol/RemotingCommand.cpp @@ -36,12 +36,15 @@ int32_t RemotingCommand::createNewRequestId() { } RemotingCommand::RemotingCommand(int32_t code, CommandCustomHeader* customHeader) + : RemotingCommand(code, "", customHeader) {} + +RemotingCommand::RemotingCommand(int32_t code, const std::string& remark, CommandCustomHeader* customHeader) : RemotingCommand(code, MQVersion::s_CurrentLanguage, MQVersion::s_CurrentVersion, createNewRequestId(), 0, - "", + remark, customHeader) {} RemotingCommand::RemotingCommand(int32_t code, @@ -73,7 +76,7 @@ RemotingCommand::RemotingCommand(RemotingCommand&& command) { RemotingCommand::~RemotingCommand() = default; -MemoryBlockPtr RemotingCommand::encode() { +MemoryBlockPtr RemotingCommand::encode() const { Json::Value root; root["code"] = m_code; root["language"] = m_language; @@ -94,37 +97,43 @@ MemoryBlockPtr RemotingCommand::encode() { std::string header = RemotingSerializable::toJson(root); - uint32 headerLen = header.size(); - uint32 packageLen = 4 + headerLen; + uint32_t headerLen = header.size(); + uint32_t packageLen = 4 + headerLen; if (m_body != nullptr) { packageLen += m_body->getSize(); } - uint32 messageHeader[2]; + uint32_t messageHeader[2]; messageHeader[0] = ByteOrder::swapIfLittleEndian(packageLen); messageHeader[1] = ByteOrder::swapIfLittleEndian(headerLen); - auto* package = new MemoryPool(4 + packageLen); + std::unique_ptr package(new MemoryPool(4 + packageLen)); package->copyFrom(messageHeader, 0, sizeof(messageHeader)); package->copyFrom(header.data(), sizeof(messageHeader), headerLen); if (m_body != nullptr && m_body->getSize() > 0) { package->copyFrom(m_body->getData(), sizeof(messageHeader) + headerLen, m_body->getSize()); } - return package; + return std::move(package); } -RemotingCommand* RemotingCommand::Decode(MemoryBlockPtr2& package) { - // decode package: 4 bytes(headerLength) + header + body +RemotingCommand* RemotingCommand::Decode(MemoryBlockPtr2 package, bool havePackageLen) { + // decode package: [4 bytes(packageLength) +] 4 bytes(headerLength) + header + body int packageLength = package->getSize(); + uint32_t netHeaderLen; + const char* data = package->getData(); - uint32 netHeaderLen; - package->copyTo(&netHeaderLen, 0, sizeof(netHeaderLen)); + if (havePackageLen) { + data += 4; + packageLength -= 4; + package->copyTo(&netHeaderLen, 4, sizeof(netHeaderLen)); + } else { + package->copyTo(&netHeaderLen, 0, sizeof(netHeaderLen)); + } int oriHeaderLen = ByteOrder::swapIfLittleEndian(netHeaderLen); int headerLength = oriHeaderLen & 0xFFFFFF; // decode header - const char* data = package->getData(); const char* begin = data + 4; const char* end = data + 4 + headerLength; @@ -161,7 +170,7 @@ RemotingCommand* RemotingCommand::Decode(MemoryBlockPtr2& package) { // decode body int bodyLength = packageLength - 4 - headerLength; if (bodyLength > 0) { - auto* body = new MemoryView(package, 4 + headerLength); + auto* body = new MemoryView(package, (havePackageLen ? 8 : 4) + headerLength); cmd->setBody(body); } @@ -231,7 +240,7 @@ CommandCustomHeader* RemotingCommand::readCustomHeader() const { return m_customHeader.get(); } -MemoryBlockPtr2 RemotingCommand::getBody() { +MemoryBlockPtr2 RemotingCommand::getBody() const { return m_body; } diff --git a/src/protocol/RemotingSerializable.cpp b/src/protocol/RemotingSerializable.cpp index eb828ce5b..96d04b514 100644 --- a/src/protocol/RemotingSerializable.cpp +++ b/src/protocol/RemotingSerializable.cpp @@ -81,6 +81,7 @@ Json::Value RemotingSerializable::fromJson(const char* begin, const char* end) { Json::Value root; std::string errs; std::unique_ptr reader(getPowerReaderBuilder().newCharReader()); + // TODO: object as key if (reader->parse(begin, end, &root, &errs)) { return root; } else { diff --git a/src/protocol/RequestCode.h b/src/protocol/RequestCode.h new file mode 100644 index 000000000..a2a7abc16 --- /dev/null +++ b/src/protocol/RequestCode.h @@ -0,0 +1,144 @@ +/* + * 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 __REQUEST_CODE_H__ +#define __REQUEST_CODE_H__ + +namespace rocketmq { + +enum MQRequestCode { + + /** + * client command + */ + + CHECK_TRANSACTION_STATE = 39, + // broker send notify to consumer when consumer lists changes + NOTIFY_CONSUMER_IDS_CHANGED = 40, + RESET_CONSUMER_CLIENT_OFFSET = 220, + GET_CONSUMER_STATUS_FROM_CLIENT = 221, + GET_CONSUMER_RUNNING_INFO = 307, + CONSUME_MESSAGE_DIRECTLY = 309, + PUSH_REPLY_MESSAGE_TO_CLIENT = 326, + + /** + * broker command + */ + + // send msg to Broker + SEND_MESSAGE = 10, + // subscribe msg from Broker + PULL_MESSAGE = 11, + // query msg from Broker + QUERY_MESSAGE = 12, + // query Broker Offset + QUERY_BROKER_OFFSET = 13, + // query Consumer Offset from broker + QUERY_CONSUMER_OFFSET = 14, + // update Consumer Offset to broker + UPDATE_CONSUMER_OFFSET = 15, + // create or update Topic to broker + UPDATE_AND_CREATE_TOPIC = 17, + // get all topic config info from broker + GET_ALL_TOPIC_CONFIG = 21, + // git all topic list from broker + GET_TOPIC_CONFIG_LIST = 22, + // get topic name list from broker + GET_TOPIC_NAME_LIST = 23, + UPDATE_BROKER_CONFIG = 25, + GET_BROKER_CONFIG = 26, + TRIGGER_DELETE_FILES = 27, + GET_BROKER_RUNTIME_INFO = 28, + SEARCH_OFFSET_BY_TIMESTAMP = 29, + GET_MAX_OFFSET = 30, + GET_MIN_OFFSET = 31, + GET_EARLIEST_MSG_STORETIME = 32, + VIEW_MESSAGE_BY_ID = 33, + // send heartbeat to broker, and register itself + HEART_BEAT = 34, + // unregister client to broker + UNREGISTER_CLIENT = 35, + // send back consume fail msg to broker + CONSUMER_SEND_MSG_BACK = 36, + // Commit Or Rollback transaction + END_TRANSACTION = 37, + // get consumer list by group from broker + GET_CONSUMER_LIST_BY_GROUP = 38, + // lock mq before orderly consume + LOCK_BATCH_MQ = 41, + // unlock mq after orderly consume + UNLOCK_BATCH_MQ = 42, + GET_ALL_CONSUMER_OFFSET = 43, + GET_ALL_DELAY_OFFSET = 45, + UPDATE_AND_CREATE_SUBSCRIPTIONGROUP = 200, + GET_ALL_SUBSCRIPTIONGROUP_CONFIG = 201, + GET_TOPIC_STATS_INFO = 202, + GET_CONSUMER_CONNECTION_LIST = 203, + GET_PRODUCER_CONNECTION_LIST = 204, + DELETE_SUBSCRIPTIONGROUP = 207, + GET_CONSUME_STATS = 208, + SUSPEND_CONSUMER = 209, + RESUME_CONSUMER = 210, + RESET_CONSUMER_OFFSET_IN_CONSUMER = 211, + RESET_CONSUMER_OFFSET_IN_BROKER = 212, + ADJUST_CONSUMER_THREAD_POOL = 213, + WHO_CONSUME_THE_MESSAGE = 214, + DELETE_TOPIC_IN_BROKER = 215, + INVOKE_BROKER_TO_RESET_OFFSET = 222, + INVOKE_BROKER_TO_GET_CONSUMER_STATUS = 223, + QUERY_TOPIC_CONSUME_BY_WHO = 300, + REGISTER_FILTER_SERVER = 301, + REGISTER_MESSAGE_FILTER_CLASS = 302, + QUERY_CONSUME_TIME_SPAN = 303, + GET_SYSTEM_TOPIC_LIST_FROM_BROKER = 305, + CLEAN_EXPIRED_CONSUMEQUEUE = 306, + QUERY_CORRECTION_OFFSET = 308, + SEND_MESSAGE_V2 = 310, + CLONE_GROUP_OFFSET = 314, + VIEW_BROKER_STATS_DATA = 315, + SEND_BATCH_MESSAGE = 320, + SEND_REPLY_MESSAGE = 324, + SEND_REPLY_MESSAGE_V2 = 325, + + /** + * namesrv command + */ + + PUT_KV_CONFIG = 100, + GET_KV_CONFIG = 101, + DELETE_KV_CONFIG = 102, + REGISTER_BROKER = 103, + UNREGISTER_BROKER = 104, + GET_ROUTEINTO_BY_TOPIC = 105, + GET_BROKER_CLUSTER_INFO = 106, + WIPE_WRITE_PERM_OF_BROKER = 205, + GET_ALL_TOPIC_LIST_FROM_NAMESERVER = 206, + DELETE_TOPIC_IN_NAMESRV = 216, + GET_KVLIST_BY_NAMESPACE = 219, + GET_TOPICS_BY_CLUSTER = 224, + GET_SYSTEM_TOPIC_LIST_FROM_NS = 304, + GET_UNIT_TOPIC_LIST = 311, + GET_HAS_UNIT_SUB_TOPIC_LIST = 312, + GET_HAS_UNIT_SUB_UNUNIT_TOPIC_LIST = 313, + UPDATE_NAMESRV_CONFIG = 318, + GET_NAMESRV_CONFIG = 319, + QUERY_DATA_VERSION = 322, + +}; + +} // namespace rocketmq + +#endif // __REQUEST_CODE_H__ diff --git a/src/protocol/ResponseCode.h b/src/protocol/ResponseCode.h new file mode 100644 index 000000000..16d2096ed --- /dev/null +++ b/src/protocol/ResponseCode.h @@ -0,0 +1,74 @@ +/* + * 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 __RESPOONSE_CODE_H__ +#define __RESPOONSE_CODE_H__ + +namespace rocketmq { + +enum MQResponseCode { + // rcv success response from broker + SUCCESS = 0, + // rcv exception from broker + SYSTEM_ERROR = 1, + // rcv symtem busy from broker + SYSTEM_BUSY = 2, + // broker don't support the request code + REQUEST_CODE_NOT_SUPPORTED = 3, + // broker flush disk timeout error + FLUSH_DISK_TIMEOUT = 10, + // broker sync double write, slave broker not available + SLAVE_NOT_AVAILABLE = 11, + // broker sync double write, slave broker flush msg timeout + FLUSH_SLAVE_TIMEOUT = 12, + // broker rcv illegal mesage + MESSAGE_ILLEGAL = 13, + // service not available due to broker or namesrv in shutdown status + SERVICE_NOT_AVAILABLE = 14, + // this version is not supported on broker or namesrv + VERSION_NOT_SUPPORTED = 15, + // broker or Namesrv has no permission to do this operation + NO_PERMISSION = 16, + // topic is not exist on broker + TOPIC_NOT_EXIST = 17, + // broker already created this topic + TOPIC_EXIST_ALREADY = 18, + // pulled msg was not found + PULL_NOT_FOUND = 19, + // retry later + PULL_RETRY_IMMEDIATELY = 20, + // pull msg with wrong offset + PULL_OFFSET_MOVED = 21, + // could not find the query msg + QUERY_NOT_FOUND = 22, + + SUBSCRIPTION_PARSE_FAILED = 23, + SUBSCRIPTION_NOT_EXIST = 24, + SUBSCRIPTION_NOT_LATEST = 25, + SUBSCRIPTION_GROUP_NOT_EXIST = 26, + + TRANSACTION_SHOULD_COMMIT = 200, + TRANSACTION_SHOULD_ROLLBACK = 201, + TRANSACTION_STATE_UNKNOW = 202, + TRANSACTION_STATE_GROUP_WRONG = 203, + + CONSUMER_NOT_ONLINE = 206, + CONSUME_MSG_TIMEOUT = 207 +}; + +} // namespace rocketmq + +#endif // __RESPOONSE_CODE_H__ diff --git a/src/protocol/TopicRouteData.h b/src/protocol/TopicRouteData.h index 9eb9e9207..61935881f 100644 --- a/src/protocol/TopicRouteData.h +++ b/src/protocol/TopicRouteData.h @@ -17,12 +17,12 @@ #ifndef __TOPIC_ROUTE_DATA_H__ #define __TOPIC_ROUTE_DATA_H__ +#include + #include #include #include -#include - #include "DataBlock.h" #include "Logging.h" #include "RemotingSerializable.h" @@ -42,6 +42,7 @@ struct QueueData { return brokerName == other.brokerName && readQueueNums == other.readQueueNums && writeQueueNums == other.writeQueueNums && perm == other.perm; } + bool operator!=(const QueueData& other) const { return !operator==(other); } }; struct BrokerData { @@ -53,6 +54,7 @@ struct BrokerData { bool operator==(const BrokerData& other) const { return brokerName == other.brokerName && brokerAddrs == other.brokerAddrs; } + bool operator!=(const BrokerData& other) const { return !operator==(other); } }; class TopicRouteData; @@ -104,20 +106,20 @@ class TopicRouteData { * @return Broker address. */ std::string selectBrokerAddr() { - int bdSize = m_brokerDatas.size(); + auto bdSize = m_brokerDatas.size(); if (bdSize > 0) { - int bdIndex = std::rand() % bdSize; - auto bd = m_brokerDatas[bdIndex]; - auto iter = bd.brokerAddrs.find(MASTER_ID); - if (iter == bd.brokerAddrs.end()) { - int baSize = bd.brokerAddrs.size(); - int baIndex = std::rand() % baSize; - iter = bd.brokerAddrs.begin(); + auto bdIndex = std::rand() % bdSize; + const auto& bd = m_brokerDatas[bdIndex]; + auto it = bd.brokerAddrs.find(MASTER_ID); + if (it == bd.brokerAddrs.end()) { + auto baSize = bd.brokerAddrs.size(); + auto baIndex = std::rand() % baSize; + it = bd.brokerAddrs.begin(); for (; baIndex > 0; baIndex--) { - iter++; + it++; } } - return iter->second; + return it->second; } return ""; } @@ -134,6 +136,7 @@ class TopicRouteData { return m_brokerDatas == other.m_brokerDatas && m_orderTopicConf == other.m_orderTopicConf && m_queueDatas == other.m_queueDatas; } + bool operator!=(const TopicRouteData& other) const { return !operator==(other); } private: std::string m_orderTopicConf; diff --git a/src/protocol/LockBatchBody.cpp b/src/protocol/body/LockBatchBody.cpp similarity index 100% rename from src/protocol/LockBatchBody.cpp rename to src/protocol/body/LockBatchBody.cpp diff --git a/src/protocol/LockBatchBody.h b/src/protocol/body/LockBatchBody.h similarity index 100% rename from src/protocol/LockBatchBody.h rename to src/protocol/body/LockBatchBody.h diff --git a/src/protocol/body/ResetOffsetBody.cpp b/src/protocol/body/ResetOffsetBody.cpp new file mode 100644 index 000000000..9caaf084f --- /dev/null +++ b/src/protocol/body/ResetOffsetBody.cpp @@ -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. + */ +#include "ResetOffsetBody.h" + +#include "RemotingSerializable.h" + +namespace rocketmq { + +ResetOffsetBody* ResetOffsetBody::Decode(MemoryBlock& mem) { + // FIXME: object as key + Json::Value root = RemotingSerializable::fromJson(mem); + Json::Value qds = root["offsetTable"]; + std::unique_ptr body(new ResetOffsetBody()); + for (unsigned int i = 0; i < qds.size(); i++) { + Json::Value qd = qds[i]; + MQMessageQueue mq(qd["brokerName"].asString(), qd["topic"].asString(), qd["queueId"].asInt()); + int64_t offset = qd["offset"].asInt64(); + body->setOffsetTable(mq, offset); + } + return body.release(); +} + +std::map ResetOffsetBody::getOffsetTable() { + return m_offsetTable; +} + +void ResetOffsetBody::setOffsetTable(const MQMessageQueue& mq, int64_t offset) { + m_offsetTable[mq] = offset; +} + +} // namespace rocketmq diff --git a/src/protocol/body/ResetOffsetBody.h b/src/protocol/body/ResetOffsetBody.h new file mode 100644 index 000000000..bc2c5f061 --- /dev/null +++ b/src/protocol/body/ResetOffsetBody.h @@ -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 __RESET_OFFSET_BODY__ +#define __RESET_OFFSET_BODY__ + +#include + +#include "DataBlock.h" +#include "MQMessageQueue.h" + +namespace rocketmq { + +class ResetOffsetBody { + public: + static ResetOffsetBody* Decode(MemoryBlock& mem); + + std::map getOffsetTable(); + void setOffsetTable(const MQMessageQueue& mq, int64_t offset); + + private: + std::map m_offsetTable; +}; + +} // namespace rocketmq + +#endif // __RESET_OFFSET_BODY__ diff --git a/src/protocol/CommandHeader.cpp b/src/protocol/header/CommandHeader.cpp similarity index 95% rename from src/protocol/CommandHeader.cpp rename to src/protocol/header/CommandHeader.cpp index 1a2694138..2bb5ceec5 100644 --- a/src/protocol/CommandHeader.cpp +++ b/src/protocol/header/CommandHeader.cpp @@ -318,7 +318,7 @@ SendMessageResponseHeader* SendMessageResponseHeader::Decode(std::mapqueueId = std::stoi(extFields.at("queueId")); header->queueOffset = std::stoll(extFields.at("queueOffset")); - auto it = extFields.find("transactionId"); + const auto& it = extFields.find("transactionId"); if (it != extFields.end()) { header->transactionId = it->second; } @@ -598,8 +598,8 @@ void UpdateConsumerOffsetRequestHeader::SetDeclaredFieldOfCommandHeader( std::map& requestMap) { requestMap.emplace("consumerGroup", consumerGroup); requestMap.emplace("topic", topic); - requestMap.emplace("queueId", std::to_string(queueId)); - requestMap.emplace("commitOffset", std::to_string(commitOffset)); + requestMap.emplace("queueId", UtilAll::to_string(queueId)); + requestMap.emplace("commitOffset", UtilAll::to_string(commitOffset)); } //###################################### @@ -607,34 +607,34 @@ void UpdateConsumerOffsetRequestHeader::SetDeclaredFieldOfCommandHeader( //###################################### void ConsumerSendMsgBackRequestHeader::Encode(Json::Value& extFields) { - extFields["offset"] = std::to_string(offset); + extFields["offset"] = UtilAll::to_string(offset); extFields["group"] = group; - extFields["delayLevel"] = std::to_string(delayLevel); + extFields["delayLevel"] = UtilAll::to_string(delayLevel); if (!originMsgId.empty()) { extFields["originMsgId"] = originMsgId; } if (!originTopic.empty()) { extFields["originTopic"] = originTopic; } - extFields["unitMode"] = std::to_string(unitMode); + extFields["unitMode"] = UtilAll::to_string(unitMode); if (maxReconsumeTimes != -1) { - extFields["maxReconsumeTimes"] = std::to_string(maxReconsumeTimes); + extFields["maxReconsumeTimes"] = UtilAll::to_string(maxReconsumeTimes); } } void ConsumerSendMsgBackRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { - requestMap.emplace("offset", std::to_string(offset)); + requestMap.emplace("offset", UtilAll::to_string(offset)); requestMap.emplace("group", group); - requestMap.emplace("delayLevel", std::to_string(delayLevel)); + requestMap.emplace("delayLevel", UtilAll::to_string(delayLevel)); if (!originMsgId.empty()) { requestMap.emplace("originMsgId", originMsgId); } if (!originTopic.empty()) { requestMap.emplace("originTopic", originTopic); } - requestMap.emplace("unitMode", std::to_string(unitMode)); + requestMap.emplace("unitMode", UtilAll::to_string(unitMode)); if (maxReconsumeTimes != -1) { - requestMap.emplace("maxReconsumeTimes", std::to_string(maxReconsumeTimes)); + requestMap.emplace("maxReconsumeTimes", UtilAll::to_string(maxReconsumeTimes)); } } @@ -665,8 +665,8 @@ ResetOffsetRequestHeader* ResetOffsetRequestHeader::Decode(std::mapgroup = extFields.at("group"); header->timestamp = std::stoll(extFields.at("timestamp")); header->isForce = UtilAll::stob(extFields.at("isForce")); - LOG_INFO("topic:%s, group:%s, timestamp:%lld, isForce:%d", header->topic.c_str(), header->group.c_str(), - header->timestamp, header->isForce); + LOG_INFO_NEW("topic:{}, group:{}, timestamp:{}, isForce:{}", header->topic, header->group, header->timestamp, + header->isForce); return header.release(); } @@ -686,11 +686,11 @@ void ResetOffsetRequestHeader::setForceFlag(const bool& tmp) { isForce = tmp; } -const std::string ResetOffsetRequestHeader::getTopic() const { +const std::string& ResetOffsetRequestHeader::getTopic() const { return topic; } -const std::string ResetOffsetRequestHeader::getGroup() const { +const std::string& ResetOffsetRequestHeader::getGroup() const { return group; } @@ -727,10 +727,10 @@ void GetConsumerRunningInfoRequestHeader::SetDeclaredFieldOfCommandHeader( std::map& requestMap) { requestMap.emplace("consumerGroup", consumerGroup); requestMap.emplace("clientId", clientId); - requestMap.emplace("jstackEnable", std::to_string(jstackEnable)); + requestMap.emplace("jstackEnable", UtilAll::to_string(jstackEnable)); } -const std::string GetConsumerRunningInfoRequestHeader::getConsumerGroup() const { +const std::string& GetConsumerRunningInfoRequestHeader::getConsumerGroup() const { return consumerGroup; } @@ -738,7 +738,7 @@ void GetConsumerRunningInfoRequestHeader::setConsumerGroup(const std::string& co this->consumerGroup = consumerGroup; } -const std::string GetConsumerRunningInfoRequestHeader::getClientId() const { +const std::string& GetConsumerRunningInfoRequestHeader::getClientId() const { return clientId; } @@ -765,7 +765,7 @@ NotifyConsumerIdsChangedRequestHeader* NotifyConsumerIdsChangedRequestHeader::De return header.release(); } -const std::string NotifyConsumerIdsChangedRequestHeader::getConsumerGroup() const { +const std::string& NotifyConsumerIdsChangedRequestHeader::getConsumerGroup() const { return consumerGroup; } diff --git a/src/protocol/CommandHeader.h b/src/protocol/header/CommandHeader.h similarity index 98% rename from src/protocol/CommandHeader.h rename to src/protocol/header/CommandHeader.h index a83fd1939..53b211464 100644 --- a/src/protocol/CommandHeader.h +++ b/src/protocol/header/CommandHeader.h @@ -408,10 +408,10 @@ class ResetOffsetRequestHeader : public CommandCustomHeader { static ResetOffsetRequestHeader* Decode(std::map& extFields); - const std::string getTopic() const; + const std::string& getTopic() const; void setTopic(const std::string& tmp); - const std::string getGroup() const; + const std::string& getGroup() const; void setGroup(const std::string& tmp); const int64_t getTimeStamp() const; @@ -435,10 +435,10 @@ class GetConsumerRunningInfoRequestHeader : public CommandCustomHeader { void Encode(Json::Value& extFields) override; void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; - const std::string getConsumerGroup() const; + const std::string& getConsumerGroup() const; void setConsumerGroup(const std::string& consumerGroup); - const std::string getClientId() const; + const std::string& getClientId() const; void setClientId(const std::string& clientId); const bool isJstackEnable() const; @@ -454,7 +454,7 @@ class NotifyConsumerIdsChangedRequestHeader : public CommandCustomHeader { public: static NotifyConsumerIdsChangedRequestHeader* Decode(std::map& extFields); - const std::string getConsumerGroup() const; + const std::string& getConsumerGroup() const; void setConsumerGroup(const std::string& tmp); private: diff --git a/src/protocol/header/ReplyMessageRequestHeader.cpp b/src/protocol/header/ReplyMessageRequestHeader.cpp new file mode 100644 index 000000000..7fd362526 --- /dev/null +++ b/src/protocol/header/ReplyMessageRequestHeader.cpp @@ -0,0 +1,175 @@ +/* + * 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 "ReplyMessageRequestHeader.h" + +#include + +#include "UtilAll.h" + +namespace rocketmq { + +ReplyMessageRequestHeader* ReplyMessageRequestHeader::Decode(std::map& extFields) { + std::unique_ptr header(new ReplyMessageRequestHeader()); + + header->producerGroup = extFields.at("producerGroup"); + header->topic = extFields.at("topic"); + header->defaultTopic = extFields.at("defaultTopic"); + header->defaultTopicQueueNums = std::stoi(extFields.at("defaultTopicQueueNums")); + header->queueId = std::stoi(extFields.at("queueId")); + header->sysFlag = std::stoi(extFields.at("sysFlag")); + header->bornTimestamp = std::stoll(extFields.at("bornTimestamp")); + header->flag = std::stoi(extFields.at("flag")); + + auto it = extFields.find("properties"); + if (it != extFields.end()) { + header->properties = it->second; + } + + it = extFields.find("reconsumeTimes"); + if (it != extFields.end()) { + header->reconsumeTimes = std::stoi(it->second); + } else { + header->reconsumeTimes = 0; + } + + it = extFields.find("unitMode"); + if (it != extFields.end()) { + header->unitMode = UtilAll::stob(it->second); + } else { + header->unitMode = false; + } + + header->bornHost = extFields.at("bornHost"); + header->storeHost = extFields.at("storeHost"); + header->storeTimestamp = std::stoll(extFields.at("storeTimestamp")); + + return header.release(); +} + +const std::string& ReplyMessageRequestHeader::getProducerGroup() const { + return this->producerGroup; +} + +void ReplyMessageRequestHeader::setProducerGroup(const std::string& producerGroup) { + this->producerGroup = producerGroup; +} + +const std::string& ReplyMessageRequestHeader::getTopic() const { + return this->topic; +} + +void ReplyMessageRequestHeader::setTopic(const std::string& topic) { + this->topic = topic; +} + +const std::string& ReplyMessageRequestHeader::getDefaultTopic() const { + return this->defaultTopic; +} + +void ReplyMessageRequestHeader::setDefaultTopic(const std::string& defaultTopic) { + this->defaultTopic = defaultTopic; +} + +int32_t ReplyMessageRequestHeader::getDefaultTopicQueueNums() const { + return this->defaultTopicQueueNums; +} + +void ReplyMessageRequestHeader::setDefaultTopicQueueNums(int32_t defaultTopicQueueNums) { + this->defaultTopicQueueNums = defaultTopicQueueNums; +} + +int32_t ReplyMessageRequestHeader::getQueueId() const { + return this->queueId; +} + +void ReplyMessageRequestHeader::setQueueId(int32_t queueId) { + this->queueId = queueId; +} + +int32_t ReplyMessageRequestHeader::getSysFlag() const { + return this->sysFlag; +} + +void ReplyMessageRequestHeader::setSysFlag(int32_t sysFlag) { + this->sysFlag = sysFlag; +} + +int64_t ReplyMessageRequestHeader::getBornTimestamp() const { + return this->bornTimestamp; +} + +void ReplyMessageRequestHeader::setBornTimestamp(int64_t bornTimestamp) { + this->bornTimestamp = bornTimestamp; +} + +int32_t ReplyMessageRequestHeader::getFlag() const { + return this->flag; +} + +void ReplyMessageRequestHeader::setFlag(int32_t flag) { + this->flag = flag; +} + +const std::string& ReplyMessageRequestHeader::getProperties() const { + return this->properties; +} + +void ReplyMessageRequestHeader::setProperties(const std::string& properties) { + this->properties = properties; +} + +int32_t ReplyMessageRequestHeader::getReconsumeTimes() const { + return this->reconsumeTimes; +} + +void ReplyMessageRequestHeader::setReconsumeTimes(int32_t reconsumeTimes) { + this->reconsumeTimes = reconsumeTimes; +} + +bool ReplyMessageRequestHeader::getUnitMode() const { + return this->unitMode; +} + +void ReplyMessageRequestHeader::setUnitMode(bool unitMode) { + this->unitMode = unitMode; +} + +const std::string& ReplyMessageRequestHeader::getBornHost() const { + return this->bornHost; +} + +void ReplyMessageRequestHeader::setBornHost(const std::string& bornHost) { + this->bornHost = bornHost; +} + +const std::string& ReplyMessageRequestHeader::getStoreHost() const { + return this->storeHost; +} + +void ReplyMessageRequestHeader::setStoreHost(const std::string& storeHost) { + this->storeHost = storeHost; +} + +int64_t ReplyMessageRequestHeader::getStoreTimestamp() const { + return this->storeTimestamp; +} + +void ReplyMessageRequestHeader::setStoreTimestamp(int64_t storeTimestamp) { + this->storeTimestamp = storeTimestamp; +} + +} // namespace rocketmq diff --git a/src/protocol/header/ReplyMessageRequestHeader.h b/src/protocol/header/ReplyMessageRequestHeader.h new file mode 100644 index 000000000..5fd341e5e --- /dev/null +++ b/src/protocol/header/ReplyMessageRequestHeader.h @@ -0,0 +1,92 @@ +/* + * 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 __REPLY_MESSAGE_REQUEST_HEADER_H__ +#define __REPLY_MESSAGE_REQUEST_HEADER_H__ + +#include + +#include "CommandCustomHeader.h" + +namespace rocketmq { + +class ReplyMessageRequestHeader : public CommandCustomHeader { + public: + static ReplyMessageRequestHeader* Decode(std::map& extFields); + + const std::string& getProducerGroup() const; + void setProducerGroup(const std::string& producerGroup); + + const std::string& getTopic() const; + void setTopic(const std::string& topic); + + const std::string& getDefaultTopic() const; + void setDefaultTopic(const std::string& defaultTopic); + + int32_t getDefaultTopicQueueNums() const; + void setDefaultTopicQueueNums(int32_t defaultTopicQueueNums); + + int32_t getQueueId() const; + void setQueueId(int32_t queueId); + + int32_t getSysFlag() const; + void setSysFlag(int32_t sysFlag); + + int64_t getBornTimestamp() const; + void setBornTimestamp(int64_t bornTimestamp); + + int32_t getFlag() const; + void setFlag(int32_t flag); + + const std::string& getProperties() const; + void setProperties(const std::string& properties); + + int32_t getReconsumeTimes() const; + void setReconsumeTimes(int32_t reconsumeTimes); + + bool getUnitMode() const; + void setUnitMode(bool unitMode); + + const std::string& getBornHost() const; + void setBornHost(const std::string& bornHost); + + const std::string& getStoreHost() const; + void setStoreHost(const std::string& storeHost); + + int64_t getStoreTimestamp() const; + void setStoreTimestamp(int64_t stroeTimestamp); + + private: + std::string producerGroup; + std::string topic; + std::string defaultTopic; + int32_t defaultTopicQueueNums; + int32_t queueId; + int32_t sysFlag; + int64_t bornTimestamp; + int32_t flag; + std::string properties; // nullable + int32_t reconsumeTimes; // nullable + bool unitMode; // nullable + + std::string bornHost; + std::string storeHost; + int64_t storeTimestamp; +}; + +} // namespace rocketmq + +#endif // __REPLY_MESSAGE_REQUEST_HEADER_H__ diff --git a/src/transport/EventLoop.cpp b/src/transport/EventLoop.cpp index 23ace973d..b1ccde7fc 100644 --- a/src/transport/EventLoop.cpp +++ b/src/transport/EventLoop.cpp @@ -18,15 +18,8 @@ #include -#ifndef WIN32 -#include -#else -#include -#endif - #include "Logging.h" #include "SocketUtil.h" -#include "UtilAll.h" namespace rocketmq { @@ -52,7 +45,7 @@ EventLoop::EventLoop(const struct event_config* config, bool run_immediately) if (m_eventBase == nullptr) { // FIXME: failure... - LOG_ERROR("Failed to create event base!"); + LOG_ERROR_NEW("[CRITICAL] Failed to create event base!"); exit(-1); } @@ -68,8 +61,6 @@ EventLoop::EventLoop(const struct event_config* config, bool run_immediately) EventLoop::~EventLoop() { stop(); - freeBufferEvent(); - if (m_eventBase != nullptr) { event_base_free(m_eventBase); m_eventBase = nullptr; @@ -92,36 +83,14 @@ void EventLoop::stop() { void EventLoop::runLoop() { while (_is_running) { - freeBufferEvent(); - int ret = event_base_dispatch(m_eventBase); if (ret == 1) { // no event std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } - - freeBufferEvent(); -} - -#if ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP -void EventLoop::freeBufferEvent() { - while (true) { - auto event = _free_queue.pop_front(); - if (event == nullptr) { - break; - } - bufferevent_free(*event); - } } -void EventLoop::freeBufferEvent(struct bufferevent* event) { - _free_queue.push_back(event); -} -#else -void EventLoop::freeBufferEvent() {} -#endif // ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP - #define OPT_UNLOCK_CALLBACKS (BEV_OPT_DEFER_CALLBACKS | BEV_OPT_UNLOCK_CALLBACKS) BufferEvent* EventLoop::createBufferEvent(socket_t fd, int options) { @@ -143,30 +112,23 @@ BufferEvent::BufferEvent(struct bufferevent* event, bool unlockCallbacks, EventL m_unlockCallbacks(unlockCallbacks), m_readCallback(nullptr), m_writeCallback(nullptr), - m_eventCallback(nullptr), - m_callbackTransport() { -#ifdef ROCKETMQ_BUFFEREVENT_PROXY_ALL_CALLBACK + m_eventCallback(nullptr) { if (m_bufferEvent != nullptr) { - bufferevent_setcb(m_bufferEvent, read_callback, write_callback, event_callback, this); + bufferevent_incref(m_bufferEvent); } -#endif // ROCKETMQ_BUFFEREVENT_PROXY_ALL_CALLBACK } BufferEvent::~BufferEvent() { if (m_bufferEvent != nullptr) { -#if ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP - m_eventLoop->freeBufferEvent(m_bufferEvent); -#else - bufferevent_free(m_bufferEvent); -#endif // ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP - m_bufferEvent = nullptr; + bufferevent_decref(m_bufferEvent); } } -void BufferEvent::setCallback(BufferEventDataCallback readCallback, - BufferEventDataCallback writeCallback, - BufferEventEventCallback eventCallback, - std::shared_ptr transport) { +void BufferEvent::setCallback(DataCallback readCallback, DataCallback writeCallback, EventCallback eventCallback) { + if (m_bufferEvent == nullptr) { + return; + } + // use lock in bufferevent bufferevent_lock(m_bufferEvent); @@ -174,15 +136,12 @@ void BufferEvent::setCallback(BufferEventDataCallback readCallback, m_readCallback = readCallback; m_writeCallback = writeCallback; m_eventCallback = eventCallback; - m_callbackTransport = transport; -#ifndef ROCKETMQ_BUFFEREVENT_PROXY_ALL_CALLBACK bufferevent_data_cb readcb = readCallback != nullptr ? read_callback : nullptr; bufferevent_data_cb writecb = writeCallback != nullptr ? write_callback : nullptr; bufferevent_event_cb eventcb = eventCallback != nullptr ? event_callback : nullptr; bufferevent_setcb(m_bufferEvent, readcb, writecb, eventcb, this); -#endif // ROCKETMQ_BUFFEREVENT_PROXY_ALL_CALLBACK bufferevent_unlock(m_bufferEvent); } @@ -194,15 +153,14 @@ void BufferEvent::read_callback(struct bufferevent* bev, void* ctx) { bufferevent_lock(event->m_bufferEvent); } - BufferEventDataCallback callback = event->m_readCallback; - std::shared_ptr transport = event->m_callbackTransport.lock(); + auto callback = event->m_readCallback; if (event->m_unlockCallbacks) { bufferevent_unlock(event->m_bufferEvent); } if (callback != nullptr) { - callback(event, transport.get()); + callback(*event); } } @@ -213,67 +171,49 @@ void BufferEvent::write_callback(struct bufferevent* bev, void* ctx) { bufferevent_lock(event->m_bufferEvent); } - BufferEventDataCallback callback = event->m_writeCallback; - std::shared_ptr transport = event->m_callbackTransport.lock(); + auto callback = event->m_writeCallback; if (event->m_unlockCallbacks) { bufferevent_unlock(event->m_bufferEvent); } if (callback != nullptr) { - callback(event, transport.get()); + callback(*event); } } -static std::string buildPeerAddrPort(socket_t fd) { - sockaddr_in addr; - socklen_t len = sizeof(addr); - - getpeername(fd, (struct sockaddr*)&addr, &len); - - std::string addrPort = socketAddress2IPPort((struct sockaddr*)&addr); - LOG_DEBUG("socket: %d, addr: %s", fd, addrPort); - - return addrPort; -} - -int BufferEvent::connect(const struct sockaddr* addr, int socklen) { - m_peerAddrPort = socketAddress2IPPort(addr); - return bufferevent_socket_connect(m_bufferEvent, (struct sockaddr*)addr, socklen); -} - -int BufferEvent::close() { - bufferevent_lock(m_bufferEvent); - auto fd = bufferevent_getfd(m_bufferEvent); - int ret = -1; - if (fd >= 0) { - ret = evutil_closesocket(fd); - } - bufferevent_unlock(m_bufferEvent); - return ret; -} - void BufferEvent::event_callback(struct bufferevent* bev, short what, void* ctx) { auto event = static_cast(ctx); - // if (what & BEV_EVENT_CONNECTED) { - // socket_t fd = event->getfd(); - // event->m_peerAddrPort = buildPeerAddrPort(fd); - // } - if (event->m_unlockCallbacks) { bufferevent_lock(event->m_bufferEvent); } - BufferEventEventCallback callback = event->m_eventCallback; - std::shared_ptr transport = event->m_callbackTransport.lock(); + auto callback = event->m_eventCallback; if (event->m_unlockCallbacks) { bufferevent_unlock(event->m_bufferEvent); } if (callback != nullptr) { - callback(event, what, transport.get()); + callback(*event, what); + } +} + +int BufferEvent::connect(const std::string& addr) { + if (m_bufferEvent == nullptr) { + LOG_WARN_NEW("have not bufferevent object to connect {}", addr); + return -1; + } + + auto* sa = string2SocketAddress(addr); + m_peerAddrPort = socketAddress2String(sa); // resolve domain + return bufferevent_socket_connect(m_bufferEvent, sa, sockaddr_size(sa)); +} + +void BufferEvent::close() { + if (m_bufferEvent != nullptr) { + bufferevent_free(m_bufferEvent); } } diff --git a/src/transport/EventLoop.h b/src/transport/EventLoop.h index c6a2924de..69ca0a010 100644 --- a/src/transport/EventLoop.h +++ b/src/transport/EventLoop.h @@ -21,16 +21,9 @@ #include #include +#include #include -#ifndef ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP -#define ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP 1 -#endif // ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP - -#if ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP -#include "concurrent/concurrent_queue.hpp" -#endif // ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOPƒ - #include "concurrent/thread.hpp" #include "noncopyable.h" @@ -57,30 +50,21 @@ class EventLoop : public noncopyable { private: void runLoop(); - void freeBufferEvent(); - -#if ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP - void freeBufferEvent(struct bufferevent* event); - friend BufferEvent; -#endif // ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP private: struct event_base* m_eventBase; thread m_loopThread; bool _is_running; // aotmic is unnecessary - -#if ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP - concurrent_queue _free_queue; -#endif // ROCKETMQ_BUFFEREVENT_FREE_IN_EVENTLOOP }; class TcpTransport; -using BufferEventDataCallback = void (*)(BufferEvent* event, TcpTransport* transport); -using BufferEventEventCallback = void (*)(BufferEvent* event, short what, TcpTransport* transport); - class BufferEvent : public noncopyable { + public: + typedef std::function DataCallback; + typedef std::function EventCallback; + private: BufferEvent(struct bufferevent* event, bool unlockCallbacks, EventLoop* loop); friend EventLoop; @@ -88,10 +72,7 @@ class BufferEvent : public noncopyable { public: virtual ~BufferEvent(); - void setCallback(BufferEventDataCallback readCallback, - BufferEventDataCallback writeCallback, - BufferEventEventCallback eventCallback, - std::shared_ptr transport); + void setCallback(DataCallback readCallback, DataCallback writeCallback, EventCallback eventCallback); void setWatermark(short events, size_t lowmark, size_t highmark) { bufferevent_setwatermark(m_bufferEvent, events, lowmark, highmark); @@ -100,8 +81,8 @@ class BufferEvent : public noncopyable { int enable(short event) { return bufferevent_enable(m_bufferEvent, event); } int disable(short event) { return bufferevent_disable(m_bufferEvent, event); } - int connect(const struct sockaddr* addr, int socklen); - int close(); + int connect(const std::string& addr); + void close(); int write(const void* data, size_t size) { return bufferevent_write(m_bufferEvent, data, size); } @@ -125,10 +106,9 @@ class BufferEvent : public noncopyable { struct bufferevent* m_bufferEvent; const bool m_unlockCallbacks; - BufferEventDataCallback m_readCallback; - BufferEventDataCallback m_writeCallback; - BufferEventEventCallback m_eventCallback; - std::weak_ptr m_callbackTransport; // avoid reference cycle + DataCallback m_readCallback; + DataCallback m_writeCallback; + EventCallback m_eventCallback; // cached properties std::string m_peerAddrPort; diff --git a/src/transport/RequestProcessor.h b/src/transport/RequestProcessor.h index 68e76f346..167bd78be 100644 --- a/src/transport/RequestProcessor.h +++ b/src/transport/RequestProcessor.h @@ -18,6 +18,7 @@ #define __REQUEST_PROCESSOR_H__ #include "RemotingCommand.h" +#include "TcpTransport.h" namespace rocketmq { @@ -25,7 +26,7 @@ class RequestProcessor { public: virtual ~RequestProcessor() = default; - virtual RemotingCommand* processRequest(const std::string& addr, RemotingCommand* request) = 0; + virtual RemotingCommand* processRequest(TcpTransportPtr channel, RemotingCommand* request) = 0; }; } // namespace rocketmq diff --git a/src/transport/ResponseFuture.cpp b/src/transport/ResponseFuture.cpp index 2bd723b44..c3ce78ad4 100755 --- a/src/transport/ResponseFuture.cpp +++ b/src/transport/ResponseFuture.cpp @@ -59,8 +59,8 @@ void ResponseFuture::executeInvokeCallback() noexcept { std::unique_ptr ResponseFuture::waitResponse(int timeoutMillis) { if (m_countDownLatch != nullptr) { - if (timeoutMillis <= 0) { - timeoutMillis = m_timeoutMillis; + if (timeoutMillis < 0) { + timeoutMillis = 0; } m_countDownLatch->wait(timeoutMillis, time_unit::milliseconds); } diff --git a/src/transport/ResponseFuture.h b/src/transport/ResponseFuture.h index cf16d89ae..8e8674dec 100755 --- a/src/transport/ResponseFuture.h +++ b/src/transport/ResponseFuture.h @@ -17,13 +17,15 @@ #ifndef __RESPONSE_FUTURE_H__ #define __RESPONSE_FUTURE_H__ -#include "concurrent/latch.hpp" - #include "InvokeCallback.h" #include "RemotingCommand.h" +#include "concurrent/latch.hpp" namespace rocketmq { +class ResponseFuture; +typedef std::shared_ptr ResponseFuturePtr; + class ResponseFuture { public: ResponseFuture(int requestCode, int opaque, int64_t timeoutMillis, InvokeCallback* invokeCallback = nullptr); @@ -37,7 +39,7 @@ class ResponseFuture { void executeInvokeCallback() noexcept; // for sync request - std::unique_ptr waitResponse(int timeoutMillis = 0); + std::unique_ptr waitResponse(int timeoutMillis); void putResponse(std::unique_ptr responseCommand); // for async request diff --git a/src/transport/SocketUtil.cpp b/src/transport/SocketUtil.cpp index 58dc24bc7..e114128b6 100644 --- a/src/transport/SocketUtil.cpp +++ b/src/transport/SocketUtil.cpp @@ -16,129 +16,105 @@ */ #include "SocketUtil.h" +#include + #include #include #include -#include - #ifndef WIN32 -#include #include #include #endif #include "ByteOrder.h" #include "MQClientException.h" +#include "UtilAll.h" namespace rocketmq { -struct sockaddr IPPort2socketAddress(int host, int port) { +union sockaddr_union { struct sockaddr_in sin; - sin.sin_family = AF_INET; - sin.sin_port = htons((uint16_t)port); - sin.sin_addr.s_addr = htonl(host); - return *(struct sockaddr*)&sin; -} + struct sockaddr_in6 sin6; +}; -std::string socketAddress2IPPort(const struct sockaddr* addr) { - if (NULL == addr) { - return std::string(); - } +thread_local static sockaddr_union sin_buf; - if (addr->sa_family == AF_INET) { - struct sockaddr_in* sin = (struct sockaddr_in*)addr; - std::ostringstream ipport; - ipport << socketAddress2String(addr) << ":" << ntohs(sin->sin_port); - return ipport.str(); - } else if (addr->sa_family == AF_INET6) { - // struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr; - throw std::runtime_error("don't support ipv6."); - } else { - throw std::runtime_error("don't support non-inet Address families."); - } +struct sockaddr* ipPort2SocketAddress(uint32_t host, uint16_t port) { + struct sockaddr_in* sin = &sin_buf.sin; + sin->sin_family = AF_INET; + sin->sin_port = htons(port); + sin->sin_addr.s_addr = htonl(host); + return (struct sockaddr*)sin; } -void socketAddress2IPPort(const struct sockaddr* addr, int& host, int& port) { - if (addr->sa_family == AF_INET) { - struct sockaddr_in* sin = (struct sockaddr_in*)addr; - host = ntohl(sin->sin_addr.s_addr); - port = ntohs(sin->sin_port); - } else if (addr->sa_family == AF_INET6) { - // struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr; - throw std::runtime_error("don't support ipv6."); - } else { - throw std::runtime_error("don't support non-inet Address families."); +struct sockaddr* string2SocketAddress(const std::string& addr) { + std::string::size_type start_pos = addr[0] == '/' ? 1 : 0; + auto colon_pos = addr.find_last_of(":"); + std::string host = addr.substr(start_pos, colon_pos - start_pos); + std::string port = addr.substr(colon_pos + 1, addr.length() - colon_pos); + auto* sa = lookupNameServers(host); + if (sa != nullptr) { + if (sa->sa_family == AF_INET) { + auto* sin = (struct sockaddr_in*)sa; + sin->sin_port = htons((uint16_t)std::stoi(port)); + } else { + auto* sin6 = (struct sockaddr_in6*)sa; + sin6->sin6_port = htons((uint16_t)std::stoi(port)); + } } + return sa; } /** * converts an address from network format to presentation format (a.b.c.d) */ std::string socketAddress2String(const struct sockaddr* addr) { - if (NULL == addr) { - return std::string(); + if (nullptr == addr) { + return "127.0.0.1"; } char buf[128]; - const char* address = NULL; + std::string address; + uint16_t port = 0; if (addr->sa_family == AF_INET) { - struct sockaddr_in* sin = (struct sockaddr_in*)addr; - address = evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf)); - } else if (addr->sa_family == AF_INET6) { - struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr; - address = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf)); - } - - if (address != NULL) { - return address; - } - - return std::string(); -} - -/** - * get the hostname of address - */ -std::string getHostName(const struct sockaddr* addr) { - if (NULL == addr) { - return std::string(); - } - - struct hostent* host = NULL; - if (addr->sa_family == AF_INET) { - struct sockaddr_in* sin = (struct sockaddr_in*)addr; - host = ::gethostbyaddr((char*)&sin->sin_addr, sizeof(sin->sin_addr), AF_INET); + auto* sin = (struct sockaddr_in*)addr; + if (nullptr != evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf))) { + address = buf; + } + port = ntohs(sin->sin_port); } else if (addr->sa_family == AF_INET6) { - struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr; - host = ::gethostbyaddr((char*)&sin6->sin6_addr, sizeof(sin6->sin6_addr), AF_INET6); + auto* sin6 = (struct sockaddr_in6*)addr; + if (nullptr != evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf))) { + address = buf; + } + port = ntohs(sin6->sin6_port); + } else { + throw std::runtime_error("don't support non-inet Address families."); } - if (host != NULL) { - char** alias = host->h_aliases; - if (*alias != NULL) { - return *alias; + if (!address.empty() && port != 0) { + if (addr->sa_family == AF_INET6) { + address = "[" + address + "]"; } + address += ":" + UtilAll::to_string(port); } - return socketAddress2String(addr); + return address; } -std::string lookupNameServers(const std::string& hostname) { +struct sockaddr* lookupNameServers(const std::string& hostname) { if (hostname.empty()) { - return "127.0.0.1"; + return nullptr; } - std::string ip; - struct evutil_addrinfo hints; struct evutil_addrinfo* answer = NULL; /* Build the hints to tell getaddrinfo how to act. */ memset(&hints, 0, sizeof(hints)); - // hints.ai_family = AF_UNSPEC; /* v4 or v6 is fine. */ - hints.ai_family = AF_INET; /* v4 only. */ + hints.ai_family = AF_UNSPEC; /* v4 or v6 is fine. */ hints.ai_socktype = SOCK_STREAM; /* We want stream socket*/ hints.ai_protocol = IPPROTO_TCP; /* We want a TCP socket */ hints.ai_flags = EVUTIL_AI_ADDRCONFIG; /* Only return addresses we can use. */ @@ -150,16 +126,34 @@ std::string lookupNameServers(const std::string& hostname) { THROW_MQEXCEPTION(UnknownHostException, info, -1); } - for (struct evutil_addrinfo* addressInfo = answer; addressInfo != NULL; addressInfo = addressInfo->ai_next) { - ip = socketAddress2String(addressInfo->ai_addr); - if (!ip.empty()) { - break; + struct sockaddr* sin = nullptr; + + for (struct evutil_addrinfo* ai = answer; ai != NULL; ai = ai->ai_next) { + auto* ai_addr = ai->ai_addr; + if (ai_addr->sa_family != AF_INET && ai_addr->sa_family != AF_INET6) { + continue; } + sin = (struct sockaddr*)&sin_buf; + memcpy(sin, ai_addr, sockaddr_size(ai_addr)); + break; } evutil_freeaddrinfo(answer); - return ip; + return sin; +} + +struct sockaddr* copySocketAddress(struct sockaddr* dst, const struct sockaddr* src) { + if (src != nullptr) { + if (dst == nullptr || dst->sa_family != src->sa_family) { + dst = (struct sockaddr*)realloc(dst, sizeof(union sockaddr_union)); + } + memcpy(dst, src, sockaddr_size(src)); + } else { + free(dst); + dst = nullptr; + } + return dst; } uint64_t h2nll(uint64_t v) { diff --git a/src/transport/SocketUtil.h b/src/transport/SocketUtil.h index 310ee8b79..e6a421bab 100644 --- a/src/transport/SocketUtil.h +++ b/src/transport/SocketUtil.h @@ -21,6 +21,7 @@ #include #ifndef WIN32 +#include #include #else #include @@ -29,16 +30,18 @@ namespace rocketmq { -struct sockaddr IPPort2socketAddress(int host, int port); +static inline size_t sockaddr_size(const struct sockaddr* sa) { + return sa->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); +} -std::string socketAddress2IPPort(const struct sockaddr* addr); -void socketAddress2IPPort(const struct sockaddr*, int& host, int& port); +struct sockaddr* ipPort2SocketAddress(uint32_t host, uint16_t port); +struct sockaddr* string2SocketAddress(const std::string& addr); std::string socketAddress2String(const struct sockaddr* addr); -std::string getHostName(const struct sockaddr* addr); +struct sockaddr* lookupNameServers(const std::string& hostname); -std::string lookupNameServers(const std::string& hostname); +struct sockaddr* copySocketAddress(struct sockaddr* dst, const struct sockaddr* src); uint64_t h2nll(uint64_t v); uint64_t n2hll(uint64_t v); diff --git a/src/transport/TcpRemotingClient.cpp b/src/transport/TcpRemotingClient.cpp index 6887678cf..948eb0eb7 100644 --- a/src/transport/TcpRemotingClient.cpp +++ b/src/transport/TcpRemotingClient.cpp @@ -24,6 +24,68 @@ namespace rocketmq { +class ResponseFutureInfo : public TcpTransportInfo { + public: + using FutureMap = std::map; + + public: + ~ResponseFutureInfo() { + // FIXME: Can optimize? + activeAllResponses(); + } + + void putResponseFuture(int opaque, ResponseFuturePtr future) { + std::lock_guard lock(m_futureTableMutex); + const auto it = m_futureTable.find(opaque); + if (it != m_futureTable.end()) { + LOG_WARN_NEW("[BUG] response futurn with opaque:{} is exist.", opaque); + } + m_futureTable[opaque] = future; + } + + ResponseFuturePtr popResponseFuture(int opaque) { + std::lock_guard lock(m_futureTableMutex); + const auto& it = m_futureTable.find(opaque); + if (it != m_futureTable.end()) { + auto future = it->second; + m_futureTable.erase(it); + return future; + } + return nullptr; + } + + void scanResponseTable(uint64_t now, std::vector& futureList) { + std::lock_guard lock(m_futureTableMutex); + for (auto it = m_futureTable.begin(); it != m_futureTable.end();) { + auto& future = it->second; // NOTE: future is a reference + if (future->getBeginTimestamp() + future->getTimeoutMillis() + 1000 <= now) { + LOG_WARN_NEW("remove timeout request, code:{}, opaque:{}", future->getRequestCode(), future->getOpaque()); + futureList.push_back(future); + it = m_futureTable.erase(it); + } else { + ++it; + } + } + } + + void activeAllResponses() { + std::lock_guard lock(m_futureTableMutex); + for (const auto& it : m_futureTable) { + auto& future = it.second; + if (future->hasInvokeCallback()) { + future->executeInvokeCallback(); // callback async request + } else { + future->putResponse(nullptr); // wake up sync request + } + } + m_futureTable.clear(); + } + + private: + FutureMap m_futureTable; // opaque -> future + std::mutex m_futureTableMutex; +}; + TcpRemotingClient::TcpRemotingClient(int workerThreadNum, uint64_t tcpConnectTimeout, uint64_t tcpTransportTryLockTimeout) @@ -34,14 +96,16 @@ TcpRemotingClient::TcpRemotingClient(int workerThreadNum, m_handleExecutor("MessageHandleExecutor", workerThreadNum, false), m_timeoutExecutor("TimeoutScanExecutor", false) {} -TcpRemotingClient::~TcpRemotingClient() = default; +TcpRemotingClient::~TcpRemotingClient() { + LOG_DEBUG_NEW("TcpRemotingClient is destructed."); +} void TcpRemotingClient::start() { m_dispatchExecutor.startup(); m_handleExecutor.startup(); - LOG_INFO("tcpConnectTimeout:%ju, tcpTransportTryLockTimeout:%ju, pullThreadNum:%d", m_tcpConnectTimeout, - m_tcpTransportTryLockTimeout, m_handleExecutor.num_threads()); + LOG_INFO_NEW("tcpConnectTimeout:{}, tcpTransportTryLockTimeout:{}, pullThreadNum:{}", m_tcpConnectTimeout, + m_tcpTransportTryLockTimeout, m_handleExecutor.num_threads()); m_timeoutExecutor.startup(); @@ -67,20 +131,10 @@ void TcpRemotingClient::shutdown() { m_dispatchExecutor.shutdown(); - { - std::lock_guard lock(m_futureTableMutex); - for (const auto& future : m_futureTable) { - if (future.second != nullptr) { - future.second->executeInvokeCallback(); - } - } - m_futureTable.clear(); - } - LOG_INFO_NEW("TcpRemotingClient::shutdown End, m_transportTable:{}", m_transportTable.size()); } -void TcpRemotingClient::registerRPCHook(std::shared_ptr rpcHook) { +void TcpRemotingClient::registerRPCHook(RPCHookPtr rpcHook) { if (rpcHook != nullptr) { for (auto& hook : m_rpcHooks) { if (hook == rpcHook) { @@ -137,23 +191,20 @@ void TcpRemotingClient::scanResponseTablePeriodically() { } void TcpRemotingClient::scanResponseTable() { - std::vector> rfList; - + std::vector channelList; { - std::lock_guard lock(m_futureTableMutex); - auto now = UtilAll::currentTimeMillis(); - for (auto it = m_futureTable.begin(); it != m_futureTable.end();) { - auto& rep = it->second; // NOTE: rep is a reference - if (rep->getBeginTimestamp() + rep->getTimeoutMillis() + 1000 <= now) { - LOG_WARN_NEW("remove timeout request, code:{}, opaque:{}", rep->getRequestCode(), rep->getOpaque()); - rfList.push_back(rep); - it = m_futureTable.erase(it); - } else { - ++it; - } + std::lock_guard lock(m_transportTableMutex); + for (const auto& trans : m_transportTable) { + channelList.push_back(trans.second); } } + auto now = UtilAll::currentTimeMillis(); + + std::vector rfList; + for (auto channel : channelList) { + static_cast(channel->getInfo())->scanResponseTable(now, rfList); + } for (auto rf : rfList) { if (rf->hasInvokeCallback()) { m_handleExecutor.submit(std::bind(&ResponseFuture::executeInvokeCallback, rf)); @@ -165,7 +216,7 @@ std::unique_ptr TcpRemotingClient::invokeSync(const std::string RemotingCommand& request, int timeoutMillis) throw(RemotingException) { auto beginStartTime = UtilAll::currentTimeMillis(); - TcpTransportPtr channel = GetTransport(addr, true); + auto channel = GetTransport(addr); if (channel != nullptr) { try { doBeforeRpcHooks(addr, request, true); @@ -202,29 +253,25 @@ std::unique_ptr TcpRemotingClient::invokeSyncImpl( int code = request.getCode(); int opaque = request.getOpaque(); - std::shared_ptr responseFuture(new ResponseFuture(code, opaque, timeoutMillis)); - addResponseFuture(opaque, responseFuture); + auto responseFuture = std::make_shared(code, opaque, timeoutMillis); + putResponseFuture(channel, opaque, responseFuture); if (SendCommand(channel, request)) { responseFuture->setSendRequestOK(true); } else { responseFuture->setSendRequestOK(false); - - findAndDeleteResponseFuture(opaque); - responseFuture->putResponse(nullptr); - + popResponseFuture(channel, opaque); // clean future + // wake up potential waitResponse() is unnecessary, so not call putResponse() LOG_WARN_NEW("send a request command to channel <{}> failed.", channel->getPeerAddrAndPort()); + THROW_MQEXCEPTION(RemotingSendRequestException, "send request to <" + channel->getPeerAddrAndPort() + "> failed", + -1); } - std::unique_ptr response(responseFuture->waitResponse()); - if (nullptr == response) { - if (responseFuture->isSendRequestOK()) { - THROW_MQEXCEPTION(RemotingTimeoutException, - "wait response on the addr <" + channel->getPeerAddrAndPort() + "> timeout", -1); - } else { - THROW_MQEXCEPTION(RemotingSendRequestException, "send request to <" + channel->getPeerAddrAndPort() + "> failed", - -1); - } + std::unique_ptr response(responseFuture->waitResponse(timeoutMillis)); + if (nullptr == response) { // timeout + popResponseFuture(channel, opaque); // clean future + THROW_MQEXCEPTION(RemotingTimeoutException, + "wait response on the addr <" + channel->getPeerAddrAndPort() + "> timeout", -1); } return response; @@ -235,7 +282,7 @@ void TcpRemotingClient::invokeAsync(const std::string& addr, InvokeCallback* invokeCallback, int64_t timeoutMillis) throw(RemotingException) { auto beginStartTime = UtilAll::currentTimeMillis(); - TcpTransportPtr channel = GetTransport(addr, true); + auto channel = GetTransport(addr); if (channel != nullptr) { try { doBeforeRpcHooks(addr, request, true); @@ -262,18 +309,17 @@ void TcpRemotingClient::invokeAsyncImpl(TcpTransportPtr channel, int opaque = request.getOpaque(); // delete in callback - std::shared_ptr responseFuture(new ResponseFuture(code, opaque, timeoutMillis, invokeCallback)); - addResponseFuture(opaque, responseFuture); + auto responseFuture = std::make_shared(code, opaque, timeoutMillis, invokeCallback); + putResponseFuture(channel, opaque, responseFuture); try { if (SendCommand(channel, request)) { responseFuture->setSendRequestOK(true); } else { // requestFail - responseFuture = findAndDeleteResponseFuture(opaque); + responseFuture = popResponseFuture(channel, opaque); if (responseFuture != nullptr) { responseFuture->setSendRequestOK(false); - responseFuture->putResponse(nullptr); if (responseFuture->hasInvokeCallback()) { m_handleExecutor.submit(std::bind(&ResponseFuture::executeInvokeCallback, responseFuture)); } @@ -289,7 +335,7 @@ void TcpRemotingClient::invokeAsyncImpl(TcpTransportPtr channel, } void TcpRemotingClient::invokeOneway(const std::string& addr, RemotingCommand& request) throw(RemotingException) { - TcpTransportPtr channel = GetTransport(addr, true); + auto channel = GetTransport(addr); if (channel != nullptr) { try { doBeforeRpcHooks(addr, request, true); @@ -337,65 +383,70 @@ void TcpRemotingClient::doAfterRpcHooks(const std::string& addr, } } -TcpTransportPtr TcpRemotingClient::GetTransport(const std::string& addr, bool needResponse) { +TcpTransportPtr TcpRemotingClient::GetTransport(const std::string& addr) { if (addr.empty()) { - LOG_DEBUG_NEW("GetTransport of NameServer"); - return CreateNameServerTransport(needResponse); + LOG_DEBUG_NEW("Get namesrv transport"); + return CreateNameServerTransport(); } - return CreateTransport(addr, needResponse); + return CreateTransport(addr); } -TcpTransportPtr TcpRemotingClient::CreateTransport(const std::string& addr, bool needResponse) { +TcpTransportPtr TcpRemotingClient::CreateTransport(const std::string& addr) { TcpTransportPtr channel; { - // try get m_tcpLock util m_tcpTransportTryLockTimeout to avoid blocking long time, + // try get m_transportTableMutex until m_tcpTransportTryLockTimeout to avoid blocking long time, // if could not get m_transportTableMutex, return NULL if (!UtilAll::try_lock_for(m_transportTableMutex, 1000 * m_tcpTransportTryLockTimeout)) { LOG_ERROR_NEW("GetTransport of:{} get timed_mutex timeout", addr); - return TcpTransportPtr(); + return nullptr; } std::lock_guard lock(m_transportTableMutex, std::adopt_lock); // check for reuse - auto iter = m_transportTable.find(addr); - if (iter != m_transportTable.end()) { - channel = iter->second; - if (channel != nullptr) { - TcpConnectStatus connectStatus = channel->getTcpConnectStatus(); - switch (connectStatus) { - // case TCP_CONNECT_STATUS_CREATED: - case TCP_CONNECT_STATUS_CONNECTED: - return channel; - case TCP_CONNECT_STATUS_CONNECTING: - // wait server answer, return dummy - return TcpTransportPtr(); - case TCP_CONNECT_STATUS_FAILED: - LOG_ERROR_NEW("tcpTransport with server disconnected, erase server:{}", addr); - channel->disconnect(addr); // avoid coredump when connection with broker was broken - m_transportTable.erase(addr); - break; - default: // TCP_CONNECT_STATUS_CLOSED - LOG_ERROR_NEW("go to CLOSED state, erase:{} from transportTable, and reconnect it", addr); - m_transportTable.erase(addr); - break; - } - } + const auto& it = m_transportTable.find(addr); + if (it != m_transportTable.end()) { + channel = it->second; } - // choose callback - TcpTransportReadCallback callback = needResponse ? &TcpRemotingClient::MessageReceived : nullptr; - - // create new transport, then connect server - channel = TcpTransport::CreateTransport(this, callback); - TcpConnectStatus connectStatus = channel->connect(addr, 0); // use non-block - if (connectStatus != TCP_CONNECT_STATUS_CONNECTING) { - LOG_WARN_NEW("can not connect to:{}", addr); - channel->disconnect(addr); - return TcpTransportPtr(); + if (channel != nullptr) { + TcpConnectStatus connectStatus = channel->getTcpConnectStatus(); + switch (connectStatus) { + // case TCP_CONNECT_STATUS_CREATED: + case TCP_CONNECT_STATUS_CONNECTED: + return channel; + case TCP_CONNECT_STATUS_CONNECTING: + // wait server answer + break; + case TCP_CONNECT_STATUS_FAILED: + LOG_ERROR_NEW("tcpTransport with server disconnected, erase server:{}", addr); + channel->disconnect(addr); + m_transportTable.erase(it); + break; + default: // TCP_CONNECT_STATUS_CLOSED + LOG_ERROR_NEW("go to CLOSED state, erase:{} from transportTable, and reconnect it", addr); + m_transportTable.erase(it); + break; + } } else { - // even if connecting failed finally, this server transport will be erased by next CreateTransport - m_transportTable[addr] = channel; + // callback + TcpTransport::ReadCallback readCallback = + std::bind(&TcpRemotingClient::messageReceived, this, std::placeholders::_1, std::placeholders::_2); + TcpTransport::CloseCallback closeCallback = + std::bind(&TcpRemotingClient::channelClosed, this, std::placeholders::_1); + + // create new transport, then connect server + std::unique_ptr responseFutureInfo(new ResponseFutureInfo()); + channel = TcpTransport::CreateTransport(readCallback, closeCallback, std::move(responseFutureInfo)); + TcpConnectStatus connectStatus = channel->connect(addr, 0); // use non-block + if (connectStatus != TCP_CONNECT_STATUS_CONNECTING) { + LOG_WARN_NEW("can not connect to:{}", addr); + channel->disconnect(addr); + return nullptr; + } else { + // even if connecting failed finally, this server transport will be erased by next CreateTransport + m_transportTable[addr] = channel; + } } } @@ -403,28 +454,28 @@ TcpTransportPtr TcpRemotingClient::CreateTransport(const std::string& addr, bool TcpConnectStatus connectStatus = channel->waitTcpConnectEvent(static_cast(m_tcpConnectTimeout)); if (connectStatus != TCP_CONNECT_STATUS_CONNECTED) { LOG_WARN_NEW("can not connect to server:{}", addr); - channel->disconnect(addr); - return TcpTransportPtr(); + // channel->disconnect(addr); + return nullptr; } else { LOG_INFO_NEW("connect server with addr:{} success", addr); return channel; } } -TcpTransportPtr TcpRemotingClient::CreateNameServerTransport(bool needResponse) { - // m_namesrvLock was added to avoid operation of nameServer was blocked by +TcpTransportPtr TcpRemotingClient::CreateNameServerTransport() { + // m_namesrvLock was added to avoid operation of NameServer was blocked by // m_tcpLock, it was used by single Thread mostly, so no performance impact // try get m_tcpLock until m_tcpTransportTryLockTimeout to avoid blocking long // time, if could not get m_namesrvlock, return NULL - LOG_DEBUG_NEW("--CreateNameserverTransport--"); + LOG_DEBUG_NEW("create namesrv transport"); if (!UtilAll::try_lock_for(m_namesrvLock, 1000 * m_tcpTransportTryLockTimeout)) { LOG_ERROR_NEW("CreateNameserverTransport get timed_mutex timeout"); - return TcpTransportPtr(); + return nullptr; } std::lock_guard lock(m_namesrvLock, std::adopt_lock); if (!m_namesrvAddrChoosed.empty()) { - TcpTransportPtr channel = CreateTransport(m_namesrvAddrChoosed, true); + auto channel = CreateTransport(m_namesrvAddrChoosed); if (channel != nullptr) { return channel; } else { @@ -433,17 +484,17 @@ TcpTransportPtr TcpRemotingClient::CreateNameServerTransport(bool needResponse) } for (unsigned i = 0; i < m_namesrvAddrList.size(); i++) { - unsigned int index = m_namesrvIndex++ % m_namesrvAddrList.size(); + auto index = m_namesrvIndex++ % m_namesrvAddrList.size(); LOG_INFO_NEW("namesrvIndex is:{}, index:{}, namesrvaddrlist size:{}", m_namesrvIndex, index, m_namesrvAddrList.size()); - TcpTransportPtr channel = CreateTransport(m_namesrvAddrList[index], true); + auto channel = CreateTransport(m_namesrvAddrList[index]); if (channel != nullptr) { m_namesrvAddrChoosed = m_namesrvAddrList[index]; return channel; } } - return TcpTransportPtr(); + return nullptr; } bool TcpRemotingClient::CloseTransport(const std::string& addr, TcpTransportPtr channel) { @@ -457,11 +508,12 @@ bool TcpRemotingClient::CloseTransport(const std::string& addr, TcpTransportPtr } std::lock_guard lock(m_transportTableMutex, std::adopt_lock); - LOG_ERROR_NEW("CloseTransport of:{}", addr); + LOG_INFO_NEW("CloseTransport of:{}", addr); bool removeItemFromTable = true; - if (m_transportTable.find(addr) != m_transportTable.end()) { - if (m_transportTable[addr]->getStartTime() != channel->getStartTime()) { + const auto& it = m_transportTable.find(addr); + if (it != m_transportTable.end()) { + if (it->second->getStartTime() != channel->getStartTime()) { LOG_INFO_NEW("tcpTransport with addr:{} has been closed before, and has been created again, nothing to do", addr); removeItemFromTable = false; } @@ -503,23 +555,21 @@ bool TcpRemotingClient::CloseNameServerTransport(TcpTransportPtr channel) { } bool TcpRemotingClient::SendCommand(TcpTransportPtr channel, RemotingCommand& msg) { - MemoryBlockPtr3 package(msg.encode()); + MemoryBlockPtr package(msg.encode()); return channel->sendMessage(package->getData(), package->getSize()); } -void TcpRemotingClient::MessageReceived(void* context, MemoryBlockPtr3& mem, const std::string& addr) { - auto* client = reinterpret_cast(context); - if (client != nullptr) { - client->messageReceived(mem, addr); - } +void TcpRemotingClient::channelClosed(TcpTransportPtr channel) { + LOG_DEBUG_NEW("channel of {} is closed.", channel->getPeerAddrAndPort()); + m_handleExecutor.submit([channel] { static_cast(channel->getInfo())->activeAllResponses(); }); } -void TcpRemotingClient::messageReceived(MemoryBlockPtr3& mem, const std::string& addr) { +void TcpRemotingClient::messageReceived(MemoryBlockPtr mem, TcpTransportPtr channel) { m_dispatchExecutor.submit( - std::bind(&TcpRemotingClient::processMessageReceived, this, MemoryBlockPtr2(std::move(mem)), addr)); + std::bind(&TcpRemotingClient::processMessageReceived, this, MemoryBlockPtr2(std::move(mem)), channel)); } -void TcpRemotingClient::processMessageReceived(MemoryBlockPtr2& mem, const std::string& addr) { +void TcpRemotingClient::processMessageReceived(MemoryBlockPtr2 mem, TcpTransportPtr channel) { std::unique_ptr cmd; try { cmd.reset(RemotingCommand::Decode(mem)); @@ -529,17 +579,17 @@ void TcpRemotingClient::processMessageReceived(MemoryBlockPtr2& mem, const std:: } if (cmd->isResponseType()) { - processResponseCommand(std::move(cmd)); + processResponseCommand(std::move(cmd), channel); } else { class task_adaptor { public: - task_adaptor(TcpRemotingClient* client, std::unique_ptr cmd, const std::string& addr) - : client_(client), cmd_(cmd.release()), addr_(addr) {} - task_adaptor(const task_adaptor& other) : client_(other.client_), cmd_(other.cmd_), addr_(other.addr_) { + task_adaptor(TcpRemotingClient* client, std::unique_ptr cmd, TcpTransportPtr channel) + : client_(client), cmd_(cmd.release()), channel_(channel) {} + task_adaptor(const task_adaptor& other) : client_(other.client_), cmd_(other.cmd_), channel_(other.channel_) { // force move const_cast(&other)->cmd_ = nullptr; } - task_adaptor(task_adaptor&& other) : client_(other.client_), cmd_(other.cmd_), addr_(other.addr_) { + task_adaptor(task_adaptor&& other) : client_(other.client_), cmd_(other.cmd_), channel_(other.channel_) { other.cmd_ = nullptr; } ~task_adaptor() { delete cmd_; } @@ -547,25 +597,27 @@ void TcpRemotingClient::processMessageReceived(MemoryBlockPtr2& mem, const std:: void operator()() { std::unique_ptr requestCommand(cmd_); cmd_ = nullptr; - client_->processRequestCommand(std::move(requestCommand), addr_); + client_->processRequestCommand(std::move(requestCommand), channel_); } private: TcpRemotingClient* client_; RemotingCommand* cmd_; - std::string addr_; + TcpTransportPtr channel_; }; - m_handleExecutor.submit(task_adaptor(this, std::move(cmd), addr)); + m_handleExecutor.submit(task_adaptor(this, std::move(cmd), channel)); } } -void TcpRemotingClient::processResponseCommand(std::unique_ptr responseCommand) { +void TcpRemotingClient::processResponseCommand(std::unique_ptr responseCommand, + TcpTransportPtr channel) { int opaque = responseCommand->getOpaque(); - std::shared_ptr responseFuture = findAndDeleteResponseFuture(opaque); + auto responseFuture = popResponseFuture(channel, opaque); if (responseFuture != nullptr) { int code = responseFuture->getRequestCode(); - LOG_DEBUG_NEW("processResponseCommand, opaque:{}, code:{}", opaque, code); + LOG_DEBUG_NEW("processResponseCommand, opaque:{}, request code:{}, server:{}", opaque, code, + channel->getPeerAddrAndPort()); if (responseFuture->hasInvokeCallback()) { responseFuture->setResponseCommand(std::move(responseCommand)); @@ -575,77 +627,63 @@ void TcpRemotingClient::processResponseCommand(std::unique_ptr responseFuture->putResponse(std::move(responseCommand)); } } else { - LOG_DEBUG_NEW("responseFuture was deleted by timeout of opaque:{}", opaque); + LOG_DEBUG_NEW("responseFuture was deleted by timeout of opaque:{}, server:{}", opaque, + channel->getPeerAddrAndPort()); } } void TcpRemotingClient::processRequestCommand(std::unique_ptr requestCommand, - const std::string& addr) { + TcpTransportPtr channel) { + std::unique_ptr response; + int requestCode = requestCommand->getCode(); - auto iter = m_processorTable.find(requestCode); - if (iter != m_processorTable.end()) { + const auto& it = m_processorTable.find(requestCode); + if (it != m_processorTable.end()) { try { - auto& processor = iter->second; - - doBeforeRpcHooks(addr, *requestCommand, false); - std::unique_ptr response(processor->processRequest(addr, requestCommand.get())); - doAfterRpcHooks(addr, *requestCommand, response.get(), true); - - if (!requestCommand->isOnewayRPC()) { - if (response != nullptr) { - response->setOpaque(requestCommand->getOpaque()); - response->markResponseType(); - - try { - TcpTransportPtr channel = GetTransport(addr, true); - if (channel != nullptr) { - if (!SendCommand(channel, *response)) { - LOG_WARN_NEW("send a response command to channel <{}> failed.", channel->getPeerAddrAndPort()); - } - } - } catch (std::exception& e) { - LOG_ERROR_NEW("process request over, but response failed. {}", e.what()); - } - } else { - } - } + auto* processor = it->second; + + doBeforeRpcHooks(channel->getPeerAddrAndPort(), *requestCommand, false); + response.reset(processor->processRequest(channel, requestCommand.get())); + doAfterRpcHooks(channel->getPeerAddrAndPort(), *response, response.get(), true); } catch (std::exception& e) { LOG_ERROR_NEW("process request exception. {}", e.what()); - if (!requestCommand->isOnewayRPC()) { - // TODO: send SYSTEM_ERROR response - } + // send SYSTEM_ERROR response + response.reset(new RemotingCommand(SYSTEM_ERROR, e.what())); } } else { + // send REQUEST_CODE_NOT_SUPPORTED response std::string error = "request type " + UtilAll::to_string(requestCommand->getCode()) + " not supported"; + response.reset(new RemotingCommand(REQUEST_CODE_NOT_SUPPORTED, error)); - // TODO: send REQUEST_CODE_NOT_SUPPORTED response + LOG_ERROR_NEW("{}: {}", channel->getPeerAddrAndPort(), error); + } - LOG_ERROR_NEW("{} {}", addr, error); + if (!requestCommand->isOnewayRPC() && response != nullptr) { + response->setOpaque(requestCommand->getOpaque()); + response->markResponseType(); + try { + if (!SendCommand(channel, *response)) { + LOG_WARN_NEW("send a response command to channel <{}> failed.", channel->getPeerAddrAndPort()); + } + } catch (const std::exception& e) { + LOG_ERROR_NEW("process request over, but response failed. {}", e.what()); + } } } -void TcpRemotingClient::addResponseFuture(int opaque, std::shared_ptr pFuture) { - std::lock_guard lock(m_futureTableMutex); - m_futureTable[opaque] = pFuture; +void TcpRemotingClient::putResponseFuture(TcpTransportPtr channel, int opaque, ResponseFuturePtr future) { + return static_cast(channel->getInfo())->putResponseFuture(opaque, future); } -// Note: after call this function, shared_ptr of m_futureTable[opaque] will +// NOTE: after call this function, shared_ptr of m_futureTable[opaque] will // be erased, so caller must ensure the life cycle of returned shared_ptr; -std::shared_ptr TcpRemotingClient::findAndDeleteResponseFuture(int opaque) { - std::lock_guard lock(m_futureTableMutex); - std::shared_ptr pResponseFuture; - if (m_futureTable.find(opaque) != m_futureTable.end()) { - pResponseFuture = m_futureTable[opaque]; - m_futureTable.erase(opaque); - } - return pResponseFuture; +ResponseFuturePtr TcpRemotingClient::popResponseFuture(TcpTransportPtr channel, int opaque) { + return static_cast(channel->getInfo())->popResponseFuture(opaque); } void TcpRemotingClient::registerProcessor(MQRequestCode requestCode, RequestProcessor* requestProcessor) { - if (m_processorTable.find(requestCode) != m_processorTable.end()) { - m_processorTable.erase(requestCode); - } + // replace m_processorTable[requestCode] = requestProcessor; } diff --git a/src/transport/TcpRemotingClient.h b/src/transport/TcpRemotingClient.h index 055b27923..e06f7ab76 100755 --- a/src/transport/TcpRemotingClient.h +++ b/src/transport/TcpRemotingClient.h @@ -23,16 +23,14 @@ #include #include -#include "concurrent/executor.hpp" - #include "MQClientException.h" #include "MQProtos.h" #include "RPCHook.h" #include "RemotingCommand.h" #include "RequestProcessor.h" #include "ResponseFuture.h" -#include "SocketUtil.h" #include "TcpTransport.h" +#include "concurrent/executor.hpp" namespace rocketmq { @@ -44,7 +42,7 @@ class TcpRemotingClient { void start(); void shutdown(); - void registerRPCHook(std::shared_ptr rpcHook); + void registerRPCHook(RPCHookPtr rpcHook); void updateNameServerAddressList(const std::string& addrs); @@ -61,24 +59,25 @@ class TcpRemotingClient { void registerProcessor(MQRequestCode requestCode, RequestProcessor* requestProcessor); - std::vector getNameServerAddressList() { return m_namesrvAddrList; } + std::vector getNameServerAddressList() const { return m_namesrvAddrList; } private: static bool SendCommand(TcpTransportPtr channel, RemotingCommand& msg); - static void MessageReceived(void* context, MemoryBlockPtr3& mem, const std::string& addr); - void messageReceived(MemoryBlockPtr3& mem, const std::string& addr); - void processMessageReceived(MemoryBlockPtr2& mem, const std::string& addr); - void processRequestCommand(std::unique_ptr cmd, const std::string& addr); - void processResponseCommand(std::unique_ptr cmd); + void channelClosed(TcpTransportPtr channel); + + void messageReceived(MemoryBlockPtr mem, TcpTransportPtr channel); + void processMessageReceived(MemoryBlockPtr2 mem, TcpTransportPtr channel); + void processRequestCommand(std::unique_ptr cmd, TcpTransportPtr channel); + void processResponseCommand(std::unique_ptr cmd, TcpTransportPtr channel); // timeout daemon void scanResponseTablePeriodically(); void scanResponseTable(); - TcpTransportPtr GetTransport(const std::string& addr, bool needResponse); - TcpTransportPtr CreateTransport(const std::string& addr, bool needResponse); - TcpTransportPtr CreateNameServerTransport(bool needResponse); + TcpTransportPtr GetTransport(const std::string& addr); + TcpTransportPtr CreateTransport(const std::string& addr); + TcpTransportPtr CreateNameServerTransport(); bool CloseTransport(const std::string& addr, TcpTransportPtr channel); bool CloseNameServerTransport(TcpTransportPtr channel); @@ -98,24 +97,20 @@ class TcpRemotingClient { void doAfterRpcHooks(const std::string& addr, RemotingCommand& request, RemotingCommand* response, bool toSent); // future management - void addResponseFuture(int opaque, std::shared_ptr pFuture); - std::shared_ptr findAndDeleteResponseFuture(int opaque); + void putResponseFuture(TcpTransportPtr channel, int opaque, ResponseFuturePtr future); + ResponseFuturePtr popResponseFuture(TcpTransportPtr channel, int opaque); private: using ProcessorMap = std::map; using TransportMap = std::map>; - using FutureMap = std::map>; ProcessorMap m_processorTable; // code -> processor TransportMap m_transportTable; // addr -> transport std::timed_mutex m_transportTableMutex; - FutureMap m_futureTable; // opaque -> future - std::mutex m_futureTableMutex; - // FIXME: not strict thread-safe in abnormal scence - std::vector> m_rpcHooks; // for Acl / ONS + std::vector m_rpcHooks; // for Acl / ONS uint64_t m_tcpConnectTimeout; // ms uint64_t m_tcpTransportTryLockTimeout; // s @@ -124,7 +119,7 @@ class TcpRemotingClient { std::timed_mutex m_namesrvLock; std::vector m_namesrvAddrList; std::string m_namesrvAddrChoosed; - unsigned int m_namesrvIndex; + size_t m_namesrvIndex; thread_pool_executor m_dispatchExecutor; thread_pool_executor m_handleExecutor; diff --git a/src/transport/TcpTransport.cpp b/src/transport/TcpTransport.cpp index ddaf75edd..770bb436b 100644 --- a/src/transport/TcpTransport.cpp +++ b/src/transport/TcpTransport.cpp @@ -31,29 +31,32 @@ namespace rocketmq { -TcpTransport::TcpTransport(TcpRemotingClient* client, TcpTransportReadCallback callback) +TcpTransport::TcpTransport(ReadCallback readCallback, + CloseCallback closeCallback, + std::unique_ptr info) : m_event(nullptr), m_tcpConnectStatus(TCP_CONNECT_STATUS_CREATED), m_statusMutex(), m_statusEvent(), - m_readCallback(callback), - m_tcpRemotingClient(client) { + m_readCallback(readCallback), + m_closeCallback(closeCallback), + m_info(std::move(info)) { m_startTime = UtilAll::currentTimeMillis(); } TcpTransport::~TcpTransport() { - closeBufferEvent(); - m_readCallback = nullptr; + closeBufferEvent(true); } -TcpConnectStatus TcpTransport::closeBufferEvent() { +TcpConnectStatus TcpTransport::closeBufferEvent(bool isDeleted) { // closeBufferEvent is idempotent. if (setTcpConnectEvent(TCP_CONNECT_STATUS_CLOSED) != TCP_CONNECT_STATUS_CLOSED) { if (m_event != nullptr) { - m_event->disable(EV_READ | EV_WRITE); // this is need for avoid block on event_base_dispatch. - // close the socket!!! m_event->close(); } + if (!isDeleted && m_closeCallback != nullptr) { + m_closeCallback(shared_from_this()); + } } return TCP_CONNECT_STATUS_CLOSED; } @@ -92,16 +95,6 @@ bool TcpTransport::setTcpConnectEventIf(TcpConnectStatus& expectedStatus, TcpCon return isSuccessed; } -u_long TcpTransport::resolveInetAddr(std::string& hostname) { - // TODO: support ipv6 - u_long addr = inet_addr(hostname.c_str()); - if (INADDR_NONE == addr) { - auto ip = lookupNameServers(hostname); - addr = inet_addr(ip.c_str()); - } - return addr; -} - void TcpTransport::disconnect(const std::string& addr) { // disconnect is idempotent. LOG_INFO_NEW("disconnect:{} start. event:{}", addr, (void*)m_event.get()); @@ -109,45 +102,41 @@ void TcpTransport::disconnect(const std::string& addr) { LOG_INFO_NEW("disconnect:{} completely", addr); } -TcpConnectStatus TcpTransport::connect(const std::string& strServerURL, int timeoutMillis) { - std::string hostname; - short port; - - LOG_INFO_NEW("connect to [{}].", strServerURL); - if (!UtilAll::SplitURL(strServerURL, hostname, port)) { - LOG_ERROR_NEW("connect to [{}] failed, Invalid url.", strServerURL); - return closeBufferEvent(); - } +TcpConnectStatus TcpTransport::connect(const std::string& addr, int timeoutMillis) { + LOG_INFO_NEW("connect to {}.", addr); TcpConnectStatus curStatus = TCP_CONNECT_STATUS_CREATED; if (setTcpConnectEventIf(curStatus, TCP_CONNECT_STATUS_CONNECTING)) { - // TODO: support ipv6 - struct sockaddr_in sin; - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - try { - sin.sin_addr.s_addr = resolveInetAddr(hostname); - } catch (UnknownHostException& e) { - // throw exception if dns failed. - LOG_WARN_NEW("{}", e.what()); - return closeBufferEvent(); - } - sin.sin_port = htons(port); - // create BufferEvent - m_event.reset( - EventLoop::GetDefaultEventLoop()->createBufferEvent(-1, /* BEV_OPT_CLOSE_ON_FREE | */ BEV_OPT_THREADSAFE)); + m_event.reset(EventLoop::GetDefaultEventLoop()->createBufferEvent(-1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE)); if (nullptr == m_event) { LOG_ERROR_NEW("create BufferEvent failed"); return closeBufferEvent(); } // then, configure BufferEvent - m_event->setCallback(ReadCallback, nullptr, EventCallback, shared_from_this()); + auto weak_this = std::weak_ptr(shared_from_this()); + auto readCallback = [=](BufferEvent& event) { + auto channel = weak_this.lock(); + if (channel != nullptr) { + channel->dataArrived(event); + } else { + LOG_WARN_NEW("[BUG] TcpTransport object is released."); + } + }; + auto eventCallback = [=](BufferEvent& event, short what) { + auto channel = weak_this.lock(); + if (channel != nullptr) { + channel->eventOccurred(event, what); + } else { + LOG_WARN_NEW("[BUG] TcpTransport object is released."); + } + }; + m_event->setCallback(readCallback, nullptr, eventCallback); m_event->setWatermark(EV_READ, 4, 0); m_event->enable(EV_READ | EV_WRITE); - if (m_event->connect((struct sockaddr*)&sin, sizeof(sin)) < 0) { + if (m_event->connect(addr) < 0) { LOG_WARN_NEW("connect to fd:{} failed", m_event->getfd()); return closeBufferEvent(); } @@ -156,29 +145,28 @@ TcpConnectStatus TcpTransport::connect(const std::string& strServerURL, int time } if (timeoutMillis <= 0) { - LOG_INFO_NEW("try to connect to fd:{}, addr:{}", m_event->getfd(), hostname); + LOG_INFO_NEW("try to connect to fd:{}, addr:{}", m_event->getfd(), addr); return TCP_CONNECT_STATUS_CONNECTING; } TcpConnectStatus connectStatus = waitTcpConnectEvent(timeoutMillis); if (connectStatus != TCP_CONNECT_STATUS_CONNECTED) { - LOG_WARN_NEW("can not connect to server:{}", strServerURL); + LOG_WARN_NEW("can not connect to server:{}", addr); return closeBufferEvent(); } return TCP_CONNECT_STATUS_CONNECTED; } -void TcpTransport::EventCallback(BufferEvent* event, short what, TcpTransport* transport) { - socket_t fd = event->getfd(); - LOG_INFO("eventcb: received event:%x on fd:%d", what, fd); - if (what & BEV_EVENT_CONNECTED) { - LOG_INFO("eventcb: connect to fd:%d successfully", fd); +void TcpTransport::eventOccurred(BufferEvent& event, short what) { + socket_t fd = event.getfd(); + LOG_INFO_NEW("eventcb: received event:0x{:X} on fd:{}", what, fd); - int val; + if (what & BEV_EVENT_CONNECTED) { + LOG_INFO_NEW("eventcb: connect to fd:{} successfully", fd); // disable Nagle - val = 1; + int val = 1; if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val)) < 0) { LOG_WARN_NEW("eventcb: disable Nagle failed. fd:{}", fd); } @@ -190,24 +178,25 @@ void TcpTransport::EventCallback(BufferEvent* event, short what, TcpTransport* t } TcpConnectStatus curStatus = TCP_CONNECT_STATUS_CONNECTING; - transport->setTcpConnectEventIf(curStatus, TCP_CONNECT_STATUS_CONNECTED); + setTcpConnectEventIf(curStatus, TCP_CONNECT_STATUS_CONNECTED); } else if (what & (BEV_EVENT_ERROR | BEV_EVENT_EOF)) { - LOG_INFO("eventcb: received error event cb:%x on fd:%d", what, fd); + LOG_ERROR_NEW("eventcb: received error event:0x{:X} on fd:{}", what, fd); + closeBufferEvent(); // if error, stop callback. - TcpConnectStatus curStatus = transport->getTcpConnectStatus(); - while (curStatus != TCP_CONNECT_STATUS_CLOSED && curStatus != TCP_CONNECT_STATUS_FAILED) { - if (transport->setTcpConnectEventIf(curStatus, TCP_CONNECT_STATUS_FAILED)) { - event->setCallback(nullptr, nullptr, nullptr, nullptr); - break; - } - curStatus = transport->getTcpConnectStatus(); - } + // TcpConnectStatus curStatus = getTcpConnectStatus(); + // while (curStatus != TCP_CONNECT_STATUS_CLOSED && curStatus != TCP_CONNECT_STATUS_FAILED) { + // if (setTcpConnectEventIf(curStatus, TCP_CONNECT_STATUS_FAILED)) { + // event.setCallback(nullptr, nullptr, nullptr); + // break; + // } + // curStatus = getTcpConnectStatus(); + // } } else { - LOG_ERROR("eventcb: received error event:%d on fd:%d", what, fd); + LOG_ERROR_NEW("eventcb: received error event:0x{:X} on fd:{}", what, fd); } } -void TcpTransport::ReadCallback(BufferEvent* event, TcpTransport* transport) { +void TcpTransport::dataArrived(BufferEvent& event) { /* This callback is invoked when there is data to read on bev. */ // protocol:
@@ -218,7 +207,7 @@ void TcpTransport::ReadCallback(BufferEvent* event, TcpTransport* transport) { // 3, use json to serialization data // 4, application could self-defined binary data - struct evbuffer* input = event->getInput(); + struct evbuffer* input = event.getInput(); while (1) { // glance at first 4 byte to get package length struct evbuffer_iovec v[4]; @@ -243,26 +232,26 @@ void TcpTransport::ReadCallback(BufferEvent* event, TcpTransport* transport) { uint32_t msgLen = ByteOrder::swapIfLittleEndian(packageLength); // same as ntohl() size_t recvLen = evbuffer_get_length(input); if (recvLen >= msgLen + 4) { - LOG_DEBUG_NEW("had received all data. msgLen:{}, from:{}, recvLen:{}", msgLen, event->getfd(), recvLen); + LOG_DEBUG_NEW("had received all data. msgLen:{}, from:{}, recvLen:{}", msgLen, event.getfd(), recvLen); } else { - LOG_DEBUG_NEW("didn't received whole. msgLen:{}, from:{}, recvLen:{}", msgLen, event->getfd(), recvLen); + LOG_DEBUG_NEW("didn't received whole. msgLen:{}, from:{}, recvLen:{}", msgLen, event.getfd(), recvLen); return; // consider large data which was not received completely by now } if (msgLen > 0) { - MemoryBlockPtr3 msg(new MemoryPool(msgLen, true)); + MemoryBlockPtr msg(new MemoryPool(msgLen, true)); - event->read(&packageLength, 4); // skip length field - event->read(msg->getData(), msgLen); + event.read(&packageLength, 4); // skip length field + event.read(msg->getData(), msgLen); - transport->messageReceived(msg, event->getPeerAddrPort()); + messageReceived(std::move(msg)); } } } -void TcpTransport::messageReceived(MemoryBlockPtr3& mem, const std::string& addr) { +void TcpTransport::messageReceived(MemoryBlockPtr mem) { if (m_readCallback != nullptr) { - m_readCallback(m_tcpRemotingClient, mem, addr); + m_readCallback(std::move(mem), shared_from_this()); } } diff --git a/src/transport/TcpTransport.h b/src/transport/TcpTransport.h index 7b9a44d7d..5a1ccb7ff 100755 --- a/src/transport/TcpTransport.h +++ b/src/transport/TcpTransport.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __TCPTRANSPORT_H__ -#define __TCPTRANSPORT_H__ +#ifndef __TCP_TRANSPORT_H__ +#define __TCP_TRANSPORT_H__ #include #include @@ -34,18 +34,25 @@ typedef enum TcpConnectStatus { TCP_CONNECT_STATUS_CLOSED = 4 } TcpConnectStatus; -using TcpTransportReadCallback = void (*)(void* context, MemoryBlockPtr3&, const std::string&); - -class TcpRemotingClient; class TcpTransport; - typedef std::shared_ptr TcpTransportPtr; +class TcpTransportInfo { + public: + virtual ~TcpTransportInfo() = default; +}; + class TcpTransport : public noncopyable, public std::enable_shared_from_this { public: - static TcpTransportPtr CreateTransport(TcpRemotingClient* client, TcpTransportReadCallback handle = nullptr) { + typedef std::function ReadCallback; + typedef std::function CloseCallback; + + public: + static TcpTransportPtr CreateTransport(ReadCallback readCallback, + CloseCallback closeCallback, + std::unique_ptr info) { // transport must be managed by smart pointer - return TcpTransportPtr(new TcpTransport(client, handle)); + return TcpTransportPtr(new TcpTransport(readCallback, closeCallback, std::move(info))); } virtual ~TcpTransport(); @@ -59,38 +66,40 @@ class TcpTransport : public noncopyable, public std::enable_shared_from_this info); - // buffer - static void ReadCallback(BufferEvent* event, TcpTransport* transport); - static void EventCallback(BufferEvent* event, short what, TcpTransport* transport); + // BufferEvent callback + void dataArrived(BufferEvent& event); + void eventOccurred(BufferEvent& event, short what); - void messageReceived(MemoryBlockPtr3& mem, const std::string& addr); + void messageReceived(MemoryBlockPtr mem); - TcpConnectStatus closeBufferEvent(); // not thread-safe + TcpConnectStatus closeBufferEvent(bool isDeleted = false); TcpConnectStatus setTcpConnectEvent(TcpConnectStatus connectStatus); bool setTcpConnectEventIf(TcpConnectStatus& expectStatus, TcpConnectStatus connectStatus); - // convert host to binary - u_long resolveInetAddr(std::string& hostname); - private: uint64_t m_startTime; - std::shared_ptr m_event; // NOTE: use m_event in callback is unsafe. + std::unique_ptr m_event; // NOTE: use m_event in callback is unsafe. std::atomic m_tcpConnectStatus; std::mutex m_statusMutex; std::condition_variable m_statusEvent; - // read data callback - TcpTransportReadCallback m_readCallback; - TcpRemotingClient* m_tcpRemotingClient; + // callback + ReadCallback m_readCallback; + CloseCallback m_closeCallback; + + // info + std::unique_ptr m_info; }; } // namespace rocketmq -#endif +#endif // __TCP_TRANSPORT__ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 73a00d007..41cff8245 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -15,79 +15,78 @@ project(test) -SET(SUB_DIRS) -file(GLOB children ${CMAKE_SOURCE_DIR}/src/*) -FOREACH(child ${children}) - IF(IS_DIRECTORY ${child}) - LIST(APPEND SUB_DIRS ${child}) - ENDIF() -ENDFOREACH() -LIST(APPEND SUB_DIRS ${CMAKE_SOURCE_DIR}/src) -include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories(${SUB_DIRS}) - -set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/test/bin) +set(CMAKE_BUILD_TYPE "Debug") -include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories(${Boost_INCLUDE_DIRS}) +set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) -set(Gtest_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/bin/include/gtest) -set(Gmock_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/bin/include/gmock) +set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${CMAKE_SOURCE_DIR}/bin/lib64/cmake;${CMAKE_SOURCE_DIR}/bin/lib/cmake") -include_directories(${Gtest_INCLUDE_DIR}) -include_directories(${Gtest_INCLUDE_DIR}/internal) -include_directories(${Gmock_INCLUDE_DIR}) -include_directories(${Gmock_INCLUDE_DIR}/internal) +# Find dependencies +if (CMAKE_VERSION VERSION_LESS "3.0") + find_package(GTest 1.10.0 REQUIRED CONFIG) +else () + include_directories("${CMAKE_SOURCE_DIR}/bin/include") -set(Gtest_LIBRARY_DIRS ${CMAKE_SOURCE_DIR}/bin/lib) -set(Gtest_LIBRARIES ${Gtest_LIBRARY_DIRS}/libgtest_main.a;${Gtest_LIBRARY_DIRS}/libgtest.a) -set(Gmock_LIBRARIES ${Gtest_LIBRARY_DIRS}/libgmock_main.a;${Gtest_LIBRARY_DIRS}/libgmock.a) -message(status "** Gmock_LIBRARIES: ${Gmock_LIBRARIES}") + if (EXISTS "${CMAKE_SOURCE_DIR}/bin/lib64/libgtest.a") + set(Gtest_LIBRARY_DIR "${CMAKE_SOURCE_DIR}/bin/lib64") + else () + set(Gtest_LIBRARY_DIR "${CMAKE_SOURCE_DIR}/bin/lib") + endif () + link_libraries("${Gtest_LIBRARY_DIR}/libgtest.a" "${Gtest_LIBRARY_DIR}/libgtest_main.a" + "${Gtest_LIBRARY_DIR}/libgmock.a" "${Gtest_LIBRARY_DIR}/libgmock_main.a") +endif () -link_directories(${Boost_LIBRARY_DIRS}) -link_directories(${LIBEVENT_LIBRARY}) -link_directories(${JSONCPP_LIBRARY}) +if (NOT (CMAKE_VERSION VERSION_LESS "3.9")) + cmake_policy(SET CMP0054 NEW) + cmake_policy(SET CMP0057 NEW) + include(GoogleTest) +endif () -set(ROCKETMQ_LIBRARIES ${CMAKE_SOURCE_DIR}/bin/librocketmq.a) -message(status "ROCKETMQ_LIBRARIES ${ROCKETMQ_LIBRARIES}") +function(config_test file) + get_filename_component(basename ${file} NAME_WE) -set(CMAKE_BUILD_TYPE "Debug") + add_executable(${basename} ${file}) -function(compile files) - foreach(file ${files}) - get_filename_component(basename ${file} NAME_WE) - add_executable(${basename} ${file}) - if(MSVC) - if(CMAKE_CONFIGURATION_TYPES STREQUAL "Release") - set_target_properties( ${basename} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT" ) - else() - set_target_properties( ${basename} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMTD" ) - endif() + if(MSVC) + if(CMAKE_CONFIGURATION_TYPES STREQUAL "Release") + set_target_properties(${basename} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT") + else() + set_target_properties(${basename} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMTD") endif() + endif() - if (MSVC) - if (BUILD_ROCKETMQ_SHARED) - target_link_libraries (${basename} rocketmq_shared ${deplibs} - ${Boost_LIBRARIES} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES} ${x`}) - else() - target_link_libraries (${basename} rocketmq_static ${deplibs} - ${Boost_LIBRARIES} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES} ${Gtest_LIBRARIES}) - endif() - else() - target_link_libraries (${basename} rocketmq_shared ${deplibs}) - target_link_libraries (${basename} rocketmq_shared ${Gtest_LIBRARIES}) - target_link_libraries (${basename} rocketmq_shared ${Gmock_LIBRARIES}) - endif() - endforeach() + if (CMAKE_VERSION VERSION_LESS "3.0") + if (BUILD_ROCKETMQ_SHARED) + target_link_libraries(${basename} rocketmq_shared + GTest::gtest GTest::gtest_main GTest::gmock GTest::gmock_main) + else (BUILD_ROCKETMQ_SHARED) + target_link_libraries(${basename} rocketmq_static + GTest::gtest GTest::gtest_main GTest::gmock GTest::gmock_main) + endif (BUILD_ROCKETMQ_SHARED) + else () + if (BUILD_ROCKETMQ_SHARED) + target_link_libraries(${basename} rocketmq_shared) + else (BUILD_ROCKETMQ_SHARED) + target_link_libraries(${basename} rocketmq_static) + endif (BUILD_ROCKETMQ_SHARED) + endif () + + if (NOT (CMAKE_VERSION VERSION_LESS "3.10")) + gtest_discover_tests(${basename}) + elseif (NOT (CMAKE_VERSION VERSION_LESS "3.9")) + gtest_add_tests(TARGET ${basename}) + endif () endfunction() -file(GLOB files "src/*.c*") -compile("${files}") +function(config_all_test dir) + file(GLOB files "${dir}/*") + foreach (file ${files}) + if (IS_DIRECTORY ${file}) + config_all_test(${file}) + elseif (${file} MATCHES "^.+\\.(c|cpp)$") + config_test(${file}) + endif () + endforeach () +endfunction() -file(GLOB files "src/*") -foreach(file ${files}) - if(IS_DIRECTORY ${file}) - file(GLOB filess "${file}/*.c*") - compile("${filess}") - endif() -endforeach() +config_all_test(${PROJECT_SOURCE_DIR}/src) diff --git a/test/src/BatchMessageTest.cpp b/test/src/BatchMessageTest.cpp deleted file mode 100644 index 789e09bfe..000000000 --- a/test/src/BatchMessageTest.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 "gtest/gtest.h" -#include "gmock/gmock.h" -#include -#include -#include -#include "BatchMessage.h" -#include "MQMessage.h" -#include - -using namespace std; -using namespace rocketmq; -using ::testing::InitGoogleTest; -using ::testing::InitGoogleMock; -using testing::Return; - -TEST(BatchMessageEncodeTest, encodeMQMessage) { - MQMessage msg1("topic", "*", "test"); - // const map& properties = msg1.getProperties(); - // for (auto& pair : properties) { - // std::cout << pair.first << " : " << pair.second << std::endl; - //} - - EXPECT_EQ(msg1.getProperties().size(), 2); - EXPECT_EQ(msg1.getBody().size(), 4); - // 20 + bodyLen + 2 + propertiesLength; - string encodeMessage = BatchMessage::encode(msg1); - EXPECT_EQ(encodeMessage.size(), 43); - - msg1.setProperty(MQMessage::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX, "1"); - encodeMessage = BatchMessage::encode(msg1); - EXPECT_EQ(encodeMessage.size(), 54); -} - -TEST(BatchMessageEncodeTest, encodeMQMessages) { - std::vector msgs; - MQMessage msg1("topic", "*", "test1"); - // const map& properties = msg1.getProperties(); - // for (auto& pair : properties) { - // std::cout << pair.first << " : " << pair.second << std::endl; - //} - msgs.push_back(msg1); - // 20 + bodyLen + 2 + propertiesLength; - string encodeMessage = BatchMessage::encode(msgs); - EXPECT_EQ(encodeMessage.size(), 86); - MQMessage msg2("topic", "*", "test2"); - MQMessage msg3("topic", "*", "test3"); - msgs.push_back(msg2); - msgs.push_back(msg3); - encodeMessage = BatchMessage::encode(msgs); - EXPECT_EQ(encodeMessage.size(), 258); // 86*3 -} - -int main(int argc, char* argv[]) { - InitGoogleMock(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/src/common/BigEndianTest.cpp b/test/src/common/BigEndianTest.cpp new file mode 100644 index 000000000..b329988fd --- /dev/null +++ b/test/src/common/BigEndianTest.cpp @@ -0,0 +1,85 @@ +/* + * 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 +#include + +#include + +#include "big_endian.h" + +using testing::InitGoogleMock; +using testing::InitGoogleTest; +using testing::Return; + +using rocketmq::BigEndianReader; +using rocketmq::BigEndianWriter; + +TEST(BigEndianTest, BigEndianObject) { + char buf[32]; + + BigEndianWriter writer(buf, 32); + BigEndianReader reader(buf, 32); + + uint64_t uint64[1]; + EXPECT_TRUE(writer.WriteU64((uint64_t)0x1234567890ABCDEF)); + EXPECT_EQ(*(uint64_t*)reader.ptr(), 0xEFCDAB9078563412); + EXPECT_TRUE(reader.ReadU64(uint64)); + EXPECT_EQ(*uint64, 0x1234567890ABCDEF); + + uint32_t uint32[1]; + EXPECT_TRUE(writer.WriteU32((uint32_t)0x12345678)); + EXPECT_EQ(*(uint32_t*)reader.ptr(), 0x78563412); + EXPECT_TRUE(reader.ReadU32(uint32)); + EXPECT_EQ(*uint32, 0x12345678); + + uint16_t uint16[1]; + EXPECT_TRUE(writer.WriteU16((uint16_t)0x1234)); + EXPECT_EQ(*(uint16_t*)reader.ptr(), 0x3412); + EXPECT_TRUE(reader.ReadU16(uint16)); + EXPECT_EQ(*uint16, 0x1234); + + uint8_t uint8[1]; + EXPECT_TRUE(writer.WriteU8((uint8_t)0x12)); + EXPECT_EQ(*(uint8_t*)reader.ptr(), 0x12); + EXPECT_TRUE(reader.ReadU8(uint8)); + EXPECT_EQ(*uint8, 0x12); + + char str[] = "RocketMQ"; + char str2[sizeof(str)]; + EXPECT_TRUE(writer.WriteBytes(str, sizeof(str) - 1)); + EXPECT_TRUE(strncmp(reader.ptr(), str, sizeof(str) - 1) == 0); + EXPECT_TRUE(reader.ReadBytes(str2, sizeof(str) - 1)); + EXPECT_TRUE(strncmp(str2, str, sizeof(str) - 1) == 0); +} + +TEST(BigEndianTest, BigEndian) { + char buf[8]; + + rocketmq::WriteBigEndian(buf, (uint8_t)0x12); + EXPECT_EQ(*(uint8_t*)buf, 0x12); + + uint8_t out[1]; + rocketmq::ReadBigEndian(buf, out); + EXPECT_EQ(*out, 0x12); +} + +int main(int argc, char* argv[]) { + InitGoogleMock(&argc, argv); + testing::GTEST_FLAG(throw_on_failure) = true; + testing::GTEST_FLAG(filter) = "BigEndianTest.*"; + return RUN_ALL_TESTS(); +} diff --git a/test/src/common/ClientRPCHookTest.cpp b/test/src/common/ClientRPCHookTest.cpp index 6fd48b631..0d22c9361 100644 --- a/test/src/common/ClientRPCHookTest.cpp +++ b/test/src/common/ClientRPCHookTest.cpp @@ -14,25 +14,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include +#include #include "ClientRPCHook.h" -#include "CommandHeader.h" #include "RemotingCommand.h" #include "SessionCredentials.h" +#include "protocol/RequestCode.h" +#include "protocol/header/CommandHeader.h" -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; +using rocketmq::ClientRPCHook; +using rocketmq::MQRequestCode; using rocketmq::RemotingCommand; using rocketmq::SendMessageRequestHeader; using rocketmq::SessionCredentials; -using rocketmq::ClientRPCHook; - -TEST(clientRPCHook, doBeforeRequest) { +TEST(ClientRPCHookTest, BeforeRequest) { SessionCredentials sessionCredentials; sessionCredentials.setAccessKey("accessKey"); sessionCredentials.setSecretKey("secretKey"); @@ -40,21 +41,23 @@ TEST(clientRPCHook, doBeforeRequest) { ClientRPCHook clientRPCHook(sessionCredentials); - RemotingCommand remotingCommand; - clientRPCHook.doBeforeRequest("127.0.0.1:9876", remotingCommand); + // TODO: + + RemotingCommand requestCommand; + clientRPCHook.doBeforeRequest("127.0.0.1:9876", requestCommand, true); SendMessageRequestHeader* sendMessageRequestHeader = new SendMessageRequestHeader(); - RemotingCommand headeRremotingCommand(17, sendMessageRequestHeader); - clientRPCHook.doBeforeRequest("127.0.0.1:9876", headeRremotingCommand); + RemotingCommand sendRequestCommand(MQRequestCode::UPDATE_AND_CREATE_TOPIC, sendMessageRequestHeader); + clientRPCHook.doBeforeRequest("127.0.0.1:9876", sendRequestCommand, true); - headeRremotingCommand.setMsgBody("1231231"); - clientRPCHook.doBeforeRequest("127.0.0.1:9876", headeRremotingCommand); + sendRequestCommand.setBody("1231231"); + clientRPCHook.doBeforeRequest("127.0.0.1:9876", sendRequestCommand, true); } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "clientRPCHook.doBeforeRequest"; + testing::GTEST_FLAG(filter) = "ClientRPCHookTest.*"; int itestts = RUN_ALL_TESTS(); return itestts; } diff --git a/test/src/common/MemoryBlockTest.cpp b/test/src/common/MemoryBlockTest.cpp index bfd7b92f6..fc8d0ec9a 100644 --- a/test/src/common/MemoryBlockTest.cpp +++ b/test/src/common/MemoryBlockTest.cpp @@ -14,161 +14,137 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include - -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include +#include -#include "dataBlock.h" +#include -using std::string; +#include "DataBlock.h" -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::MemoryBlock; +using rocketmq::MemoryPool; -TEST(memoryBlock, init) { +TEST(MemoryBlockTest, Init) { MemoryBlock memoryBlock; EXPECT_EQ(memoryBlock.getSize(), 0); EXPECT_TRUE(memoryBlock.getData() == nullptr); - MemoryBlock twoMemoryBlock(-1, true); + MemoryPool twoMemoryBlock(0, true); EXPECT_EQ(twoMemoryBlock.getSize(), 0); EXPECT_TRUE(twoMemoryBlock.getData() == nullptr); - MemoryBlock threeMemoryBlock(10, true); + MemoryPool threeMemoryBlock(10, true); EXPECT_EQ(threeMemoryBlock.getSize(), 10); EXPECT_TRUE(threeMemoryBlock.getData() != nullptr); - MemoryBlock frouMemoryBlock(12, false); + MemoryPool frouMemoryBlock(12, false); EXPECT_EQ(frouMemoryBlock.getSize(), 12); EXPECT_TRUE(frouMemoryBlock.getData() != nullptr); - char* buf = (char*)malloc(sizeof(char) * 9); - strcpy(buf, "RocketMQ"); - MemoryBlock fiveMemoryBlock(buf, -1); - EXPECT_EQ(fiveMemoryBlock.getSize(), -1); + char buf[] = "RocketMQ"; + MemoryPool fiveMemoryBlock(buf, 0); + EXPECT_EQ(fiveMemoryBlock.getSize(), 0); EXPECT_TRUE(fiveMemoryBlock.getData() == nullptr); - char* bufNull = NULL; - MemoryBlock sixMemoryBlock(bufNull, 16); + MemoryPool sixMemoryBlock(nullptr, 16); EXPECT_EQ(sixMemoryBlock.getSize(), 16); EXPECT_TRUE(sixMemoryBlock.getData() != nullptr); - MemoryBlock sevenMemoryBlock(buf, 20); - EXPECT_EQ(sevenMemoryBlock.getSize(), 20); - sevenMemoryBlock.getData(); - EXPECT_EQ(string(sevenMemoryBlock.getData()), string(buf)); + MemoryPool sevenMemoryBlock(buf, sizeof(buf) - 1); + EXPECT_EQ(sevenMemoryBlock.getSize(), sizeof(buf) - 1); + EXPECT_EQ((std::string)sevenMemoryBlock, buf); - MemoryBlock nineMemoryBlock(sevenMemoryBlock); + MemoryPool nineMemoryBlock(sevenMemoryBlock); EXPECT_EQ(nineMemoryBlock.getSize(), sevenMemoryBlock.getSize()); - EXPECT_EQ(string(nineMemoryBlock.getData()), string(sevenMemoryBlock.getData())); + EXPECT_EQ(nineMemoryBlock, sevenMemoryBlock); - MemoryBlock eightMemoryBlock(fiveMemoryBlock); + MemoryPool eightMemoryBlock(fiveMemoryBlock); EXPECT_EQ(eightMemoryBlock.getSize(), fiveMemoryBlock.getSize()); EXPECT_TRUE(eightMemoryBlock.getData() == nullptr); - - free(buf); } -TEST(memoryBlock, operators) { - MemoryBlock memoryBlock(12, false); - - MemoryBlock operaterMemoryBlock = memoryBlock; +TEST(MemoryBlockTest, Operators) { + MemoryPool memoryBlock(8, false); + MemoryPool operaterMemoryBlock = memoryBlock; EXPECT_TRUE(operaterMemoryBlock == memoryBlock); - char* buf = (char*)malloc(sizeof(char) * 16); - memset(buf, 0, 16); - strcpy(buf, "RocketMQ"); - MemoryBlock twoMemoryBlock(buf, 12); + char buf[] = "RocketMQ"; + MemoryPool twoMemoryBlock(buf, sizeof(buf) - 1); EXPECT_FALSE(memoryBlock == twoMemoryBlock); - MemoryBlock threeMemoryBlock(buf, 16); + MemoryPool threeMemoryBlock(buf, 7); EXPECT_FALSE(memoryBlock == threeMemoryBlock); EXPECT_TRUE(twoMemoryBlock != threeMemoryBlock); threeMemoryBlock.fillWith(49); - EXPECT_EQ(string(threeMemoryBlock.getData(), 16), "1111111111111111"); + EXPECT_EQ((std::string)threeMemoryBlock, "1111111"); threeMemoryBlock.reset(); EXPECT_EQ(threeMemoryBlock.getSize(), 0); EXPECT_TRUE(threeMemoryBlock.getData() == nullptr); - threeMemoryBlock.setSize(16, 0); + threeMemoryBlock.setSize(16, false); EXPECT_EQ(threeMemoryBlock.getSize(), 16); - // EXPECT_EQ(threeMemoryBlock.getData() , buf); - threeMemoryBlock.setSize(0, 0); + threeMemoryBlock.setSize(0, false); EXPECT_EQ(threeMemoryBlock.getSize(), 0); EXPECT_TRUE(threeMemoryBlock.getData() == nullptr); - MemoryBlock appendMemoryBlock; + MemoryPool appendMemoryBlock; EXPECT_EQ(appendMemoryBlock.getSize(), 0); EXPECT_TRUE(appendMemoryBlock.getData() == nullptr); - appendMemoryBlock.append(buf, -1); + appendMemoryBlock.append(buf, 0); EXPECT_EQ(appendMemoryBlock.getSize(), 0); EXPECT_TRUE(appendMemoryBlock.getData() == nullptr); - appendMemoryBlock.append(buf, 8); + appendMemoryBlock.append(buf, sizeof(buf) - 1); EXPECT_EQ(appendMemoryBlock.getSize(), 8); - MemoryBlock replaceWithMemoryBlock; - replaceWithMemoryBlock.append(buf, 8); + MemoryPool replaceWithMemoryBlock; + replaceWithMemoryBlock.append(buf, sizeof(buf) - 1); - char* aliyunBuf = (char*)malloc(sizeof(char) * 8); - memset(aliyunBuf, 0, 8); - strcpy(aliyunBuf, "aliyun"); + char aliyunBuf[] = "aliyun"; replaceWithMemoryBlock.replaceWith(aliyunBuf, 0); EXPECT_EQ(replaceWithMemoryBlock.getSize(), 8); - EXPECT_EQ(string(replaceWithMemoryBlock.getData(), 8), "RocketMQ"); + EXPECT_EQ((std::string)replaceWithMemoryBlock, "RocketMQ"); - replaceWithMemoryBlock.replaceWith(aliyunBuf, 6); + replaceWithMemoryBlock.replaceWith(aliyunBuf, sizeof(aliyunBuf) - 1); EXPECT_EQ(replaceWithMemoryBlock.getSize(), 6); - EXPECT_EQ(string(replaceWithMemoryBlock.getData(), strlen(aliyunBuf)), "aliyun"); - - MemoryBlock insertMemoryBlock; - insertMemoryBlock.append(buf, 8); - insertMemoryBlock.insert(aliyunBuf, -1, -1); - EXPECT_EQ(string(insertMemoryBlock.getData(), 8), "RocketMQ"); - - /* MemoryBlock fourInsertMemoryBlock; - fourInsertMemoryBlock.append(buf , 8); - // 6+ (-1) - fourInsertMemoryBlock.insert(aliyunBuf , 8 , -1); - string fourStr( fourInsertMemoryBlock.getData()); - EXPECT_TRUE( fourStr == "liyun");*/ - - MemoryBlock twoInsertMemoryBlock; - twoInsertMemoryBlock.append(buf, 8); - twoInsertMemoryBlock.insert(aliyunBuf, strlen(aliyunBuf), 0); - EXPECT_EQ(string(twoInsertMemoryBlock.getData(), 8 + strlen(aliyunBuf)), "aliyunRocketMQ"); - - MemoryBlock threeInsertMemoryBlock; - threeInsertMemoryBlock.append(buf, 8); - threeInsertMemoryBlock.insert(aliyunBuf, 6, 100); - EXPECT_EQ(string(threeInsertMemoryBlock.getData(), 8 + strlen(aliyunBuf)), "RocketMQaliyun"); - - MemoryBlock removeSectionMemoryBlock(buf, 8); - removeSectionMemoryBlock.removeSection(8, -1); - EXPECT_EQ(string(removeSectionMemoryBlock.getData(), 8), "RocketMQ"); - - MemoryBlock twoRemoveSectionMemoryBlock(buf, 8); - twoRemoveSectionMemoryBlock.removeSection(1, 4); - string str(twoRemoveSectionMemoryBlock.getData(), 4); - EXPECT_TRUE(str == "RtMQ"); + EXPECT_EQ((std::string)replaceWithMemoryBlock, "aliyun"); - free(buf); - free(aliyunBuf); + MemoryPool insertMemoryBlock; + insertMemoryBlock.append(buf, sizeof(buf) - 1); + insertMemoryBlock.insert(aliyunBuf, 0, 0); + EXPECT_EQ((std::string)insertMemoryBlock, "RocketMQ"); + + MemoryPool twoInsertMemoryBlock; + twoInsertMemoryBlock.append(buf, sizeof(buf) - 1); + twoInsertMemoryBlock.insert(aliyunBuf, sizeof(aliyunBuf) - 1, 0); + EXPECT_EQ((std::string)twoInsertMemoryBlock, "aliyunRocketMQ"); + + MemoryPool threeInsertMemoryBlock; + threeInsertMemoryBlock.append(buf, sizeof(buf) - 1); + threeInsertMemoryBlock.insert(aliyunBuf, sizeof(aliyunBuf) - 1, 100); + EXPECT_EQ((std::string)threeInsertMemoryBlock, "RocketMQaliyun"); + + MemoryPool removeSectionMemoryBlock(buf, sizeof(buf) - 1); + removeSectionMemoryBlock.removeSection(8, 0); + EXPECT_EQ((std::string)removeSectionMemoryBlock, "RocketMQ"); + + MemoryPool twoRemoveSectionMemoryBlock(buf, sizeof(buf) - 1); + twoRemoveSectionMemoryBlock.removeSection(1, 4); + EXPECT_EQ((std::string)twoRemoveSectionMemoryBlock, "RtMQ"); } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "memoryBlock.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "MemoryBlockTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/common/MemoryOutputStreamTest.cpp b/test/src/common/MemoryOutputStreamTest.cpp index 05af181e0..80218cffe 100644 --- a/test/src/common/MemoryOutputStreamTest.cpp +++ b/test/src/common/MemoryOutputStreamTest.cpp @@ -14,26 +14,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "string.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include +#include +#include "DataBlock.h" #include "MemoryInputStream.h" #include "MemoryOutputStream.h" -#include "dataBlock.h" - -using std::string; -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::MemoryBlock; using rocketmq::MemoryInputStream; using rocketmq::MemoryOutputStream; +using rocketmq::MemoryPool; -TEST(memoryOutputStream, init) { +TEST(MemoryOutputStreamTest, Init) { MemoryOutputStream memoryOutput; EXPECT_EQ(memoryOutput.getMemoryBlock().getSize(), 0); EXPECT_TRUE(memoryOutput.getData() != nullptr); @@ -44,7 +41,7 @@ TEST(memoryOutputStream, init) { MemoryOutputStream twoMemoryOutput(512); EXPECT_EQ(memoryOutput.getMemoryBlock().getSize(), 0); - MemoryBlock memoryBlock(12, false); + MemoryPool memoryBlock(12, false); MemoryOutputStream threeMemoryOutput(memoryBlock, false); EXPECT_EQ(threeMemoryOutput.getPosition(), 0); EXPECT_EQ(threeMemoryOutput.getDataSize(), 0); @@ -53,76 +50,67 @@ TEST(memoryOutputStream, init) { EXPECT_EQ(frouMemoryOutput.getPosition(), memoryBlock.getSize()); EXPECT_EQ(frouMemoryOutput.getDataSize(), memoryBlock.getSize()); - char* buf = (char*)malloc(sizeof(char) * 9); - strcpy(buf, "RocketMQ"); - MemoryOutputStream fiveMemoryOutputStream(buf, 8); + char buf[] = "RocketMQ"; + MemoryOutputStream fiveMemoryOutputStream(buf, sizeof(buf)); EXPECT_EQ(fiveMemoryOutputStream.getData(), buf); fiveMemoryOutputStream.reset(); EXPECT_EQ(memoryOutput.getPosition(), 0); EXPECT_EQ(memoryOutput.getDataSize(), 0); - free(buf); } -TEST(memoryOutputStream, flush) { - char* buf = (char*)malloc(sizeof(char) * 9); - strcpy(buf, "RocketMQ"); +TEST(MemoryOutputStreamTest, Flush) { + char buf[] = "RocketMQ"; MemoryOutputStream memoryOutput; - memoryOutput.write(buf, 9); + memoryOutput.write(buf, sizeof(buf) - 1); memoryOutput.flush(); EXPECT_FALSE(memoryOutput.getData() == buf); - free(buf); } -TEST(memoryOutputStream, preallocate) { +TEST(MemoryOutputStreamTest, Preallocate) { MemoryOutputStream memoryOutput; + + // TODO: memoryOutput.preallocate(250); memoryOutput.preallocate(256); } -TEST(memoryOutputStream, getMemoryBlock) { - char* buf = (char*)malloc(sizeof(char) * 9); - strcpy(buf, "RocketMQ"); +TEST(MemoryOutputStreamTest, GetMemoryBlock) { + char buf[] = "RocketMQ"; MemoryOutputStream memoryOutput; - memoryOutput.write(buf, 9); - MemoryBlock memoryBlock = memoryOutput.getMemoryBlock(); + memoryOutput.write(buf, sizeof(buf) - 1); + MemoryPool memoryBlock = memoryOutput.getMemoryBlock(); EXPECT_EQ(memoryBlock.getSize(), memoryOutput.getDataSize()); - free(buf); } -TEST(memoryOutputStream, prepareToWriteAndGetData) { - char* buf = (char*)malloc(sizeof(char) * 9); - strcpy(buf, "RocketMQ"); - MemoryOutputStream memoryOutput(buf, 9); +TEST(MemoryOutputStreamTest, PrepareToWriteAndGetData) { + char buf[] = "RocketMQ"; + MemoryOutputStream memoryOutput(buf, sizeof(buf)); EXPECT_EQ(memoryOutput.getData(), buf); // prepareToWrite // EXPECT_TRUE(memoryOutput.writeIntBigEndian(123)); EXPECT_TRUE(memoryOutput.writeByte('r')); - const char* data = static_cast(memoryOutput.getData()); - EXPECT_EQ(string(data), "rocketMQ"); + EXPECT_STREQ(static_cast(memoryOutput.getData()), "rocketMQ"); MemoryOutputStream blockMmoryOutput(8); - char* memoryData = (char*)blockMmoryOutput.getData(); - + auto* memoryData = static_cast(blockMmoryOutput.getData()); EXPECT_EQ(memoryData[blockMmoryOutput.getDataSize()], 0); blockMmoryOutput.write(buf, 8); blockMmoryOutput.write(buf, 8); - data = static_cast(blockMmoryOutput.getData()); - EXPECT_EQ(string(data), "rocketMQrocketMQ"); - free(buf); + auto* data = static_cast(blockMmoryOutput.getData()); + EXPECT_STREQ(data, "rocketMQrocketMQ"); } -TEST(memoryOutputStream, position) { - char* buf = (char*)malloc(sizeof(char) * 9); - strcpy(buf, "RocketMQ"); +TEST(MemoryOutputStreamTest, Position) { + char buf[] = "RocketMQ"; MemoryOutputStream memoryOutput; EXPECT_EQ(memoryOutput.getPosition(), 0); - memoryOutput.write(buf, 8); + memoryOutput.write(buf, sizeof(buf) - 1); EXPECT_EQ(memoryOutput.getPosition(), 8); EXPECT_FALSE(memoryOutput.setPosition(9)); @@ -135,10 +123,9 @@ TEST(memoryOutputStream, position) { EXPECT_TRUE(memoryOutput.setPosition(7)); EXPECT_EQ(memoryOutput.getPosition(), 7); - free(buf); } -TEST(memoryOutputStream, write) { +TEST(MemoryOutputStreamTest, Write) { MemoryOutputStream memoryOutput; MemoryInputStream memoryInput(memoryOutput.getData(), 256, false); @@ -166,43 +153,31 @@ TEST(memoryOutputStream, write) { EXPECT_TRUE(memoryOutput.writeFloatBigEndian(12.1)); float f = 12.1; EXPECT_EQ(memoryInput.readFloatBigEndian(), f); - - // EXPECT_TRUE(memoryOutput.writeRepeatedByte(8 , 8)); } -TEST(memoryInputStream, info) { - char* buf = (char*)malloc(sizeof(char) * 9); - strcpy(buf, "RocketMQ"); - - MemoryInputStream memoryInput(buf, 8, false); - - char* memoryData = (char*)memoryInput.getData(); - EXPECT_EQ(memoryData, buf); +TEST(MemoryInputStreamTest, Info) { + char buf[] = "RocketMQ"; + MemoryInputStream memoryInput(buf, sizeof(buf) - 1, false); + EXPECT_EQ(memoryInput.getData(), buf); EXPECT_EQ(memoryInput.getTotalLength(), 8); - MemoryInputStream twoMemoryInput(buf, 8, true); + MemoryInputStream twoMemoryInput(buf, sizeof(buf) - 1, true); EXPECT_NE(twoMemoryInput.getData(), buf); - memoryData = (char*)twoMemoryInput.getData(); - EXPECT_NE(&memoryData, &buf); - - MemoryBlock memoryBlock(buf, 8); + MemoryBlock memoryBlock(buf, sizeof(buf) - 1); MemoryInputStream threeMemoryInput(memoryBlock, false); - memoryData = (char*)threeMemoryInput.getData(); - EXPECT_EQ(memoryData, threeMemoryInput.getData()); + EXPECT_EQ(threeMemoryInput.getData(), memoryBlock.getData()); EXPECT_EQ(threeMemoryInput.getTotalLength(), 8); MemoryInputStream frouMemoryInput(memoryBlock, true); EXPECT_NE(frouMemoryInput.getData(), memoryBlock.getData()); - free(buf); } -TEST(memoryInputStream, position) { - char* buf = (char*)malloc(sizeof(char) * 9); - strcpy(buf, "RocketMQ"); +TEST(MemoryInputStreamTest, Position) { + char buf[] = "RocketMQ"; - MemoryInputStream memoryInput(buf, 8, false); + MemoryInputStream memoryInput(buf, sizeof(buf) - 1, false); EXPECT_EQ(memoryInput.getPosition(), 0); EXPECT_FALSE(memoryInput.isExhausted()); @@ -212,13 +187,11 @@ TEST(memoryInputStream, position) { memoryInput.setPosition(-1); EXPECT_EQ(memoryInput.getPosition(), 0); - free(buf); } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; testing::GTEST_FLAG(filter) = "*.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + return RUN_ALL_TESTS(); } diff --git a/test/src/common/NamesrvConfigTest.cpp b/test/src/common/NamesrvConfigTest.cpp index e4e1206ae..da2bed182 100644 --- a/test/src/common/NamesrvConfigTest.cpp +++ b/test/src/common/NamesrvConfigTest.cpp @@ -15,25 +15,23 @@ * limitations under the License. */ -#include +#include +#include -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include #include "NamesrvConfig.h" -using std::string; - -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::NamesrvConfig; -TEST(namesrvConfig, init) { +TEST(NamesrvConfigTest, Init) { NamesrvConfig namesrvConfig; - const string home = "/home/rocketmq"; + const std::string home = "/home/rocketmq"; namesrvConfig.setRocketmqHome(home); EXPECT_EQ(namesrvConfig.getRocketmqHome(), "/home/rocketmq"); @@ -44,7 +42,6 @@ TEST(namesrvConfig, init) { int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "namesrvConfig.init"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "NamesrvConfigTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/common/PermNametTest.cpp b/test/src/common/PermNameTest.cpp similarity index 84% rename from test/src/common/PermNametTest.cpp rename to test/src/common/PermNameTest.cpp index 3296b84d7..2e3268bde 100644 --- a/test/src/common/PermNametTest.cpp +++ b/test/src/common/PermNameTest.cpp @@ -14,18 +14,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include +#include #include "PermName.h" -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::PermName; -TEST(permName, perm2String) { +TEST(PermNameTest, Perm2String) { EXPECT_EQ(PermName::perm2String(0), "---"); EXPECT_EQ(PermName::perm2String(1), "--X"); EXPECT_EQ(PermName::perm2String(2), "-W"); @@ -40,7 +40,6 @@ TEST(permName, perm2String) { int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "permName.perm2String"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "PermNameTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/common/PullSysFlagTest.cpp b/test/src/common/PullSysFlagTest.cpp index 7b7c9db95..e5f2485eb 100644 --- a/test/src/common/PullSysFlagTest.cpp +++ b/test/src/common/PullSysFlagTest.cpp @@ -14,18 +14,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include +#include #include "PullSysFlag.h" -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::PullSysFlag; -TEST(pullSysFlag, flag) { +TEST(PullSysFlagTest, Flag) { EXPECT_EQ(PullSysFlag::buildSysFlag(false, false, false, false), 0); EXPECT_EQ(PullSysFlag::buildSysFlag(true, false, false, false), 1); @@ -89,7 +89,6 @@ TEST(pullSysFlag, flag) { int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "pullSysFlag.flag"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "PullSysFlagTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/common/TopicConfigTest.cpp b/test/src/common/TopicConfigTest.cpp index 8c163942c..a9748a243 100644 --- a/test/src/common/TopicConfigTest.cpp +++ b/test/src/common/TopicConfigTest.cpp @@ -14,35 +14,32 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "string.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include +#include #include "PermName.h" #include "TopicConfig.h" #include "TopicFilterType.h" -using std::string; - -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::PermName; using rocketmq::TopicConfig; using rocketmq::TopicFilterType; -TEST(topicConfig, encodeAndDecode) { +TEST(TopicConfigTest, EncodeAndDecode) { TopicConfig topicConfig("testTopic", 4, 4, PermName::PERM_READ); - string str = topicConfig.encode(); + std::string str = topicConfig.encode(); + EXPECT_EQ(str, "testTopic 4 4 4 0"); TopicConfig topicDecodeConfig; topicDecodeConfig.decode(str); EXPECT_EQ(str, topicDecodeConfig.encode()); } -TEST(topicConfig, info) { +TEST(TopicConfigTest, GetterAndSetter) { TopicConfig topicConfig; topicConfig.setTopicName("testTopic"); @@ -61,7 +58,7 @@ TEST(topicConfig, info) { EXPECT_EQ(topicConfig.getTopicFilterType(), TopicFilterType::MULTI_TAG); } -TEST(topicConfig, init) { +TEST(TopicConfigTest, Init) { TopicConfig topicConfig; EXPECT_TRUE(topicConfig.getTopicName() == ""); EXPECT_EQ(topicConfig.getReadQueueNums(), TopicConfig::DefaultReadQueueNums); @@ -87,7 +84,6 @@ TEST(topicConfig, init) { int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "topicConfig.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "TopicConfigTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/common/ValidatorsTest.cpp b/test/src/common/ValidatorsTest.cpp index 23594cdd3..b56088915 100644 --- a/test/src/common/ValidatorsTest.cpp +++ b/test/src/common/ValidatorsTest.cpp @@ -14,69 +14,62 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "string.h" +#include +#include -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include #include "MQClientException.h" #include "MQMessage.h" #include "Validators.h" -using std::string; - -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::MQClientException; using rocketmq::MQMessage; using rocketmq::Validators; -TEST(validators, regularExpressionMatcher) { - EXPECT_FALSE(Validators::regularExpressionMatcher(string(), string())); - - EXPECT_TRUE(Validators::regularExpressionMatcher(string("123456"), string())); - - EXPECT_TRUE(Validators::regularExpressionMatcher(string("123456"), string("123"))); +TEST(ValidatorsTest, RegularExpressionMatcher) { + EXPECT_FALSE(Validators::regularExpressionMatcher("", "")); + EXPECT_TRUE(Validators::regularExpressionMatcher("123456", "")); + EXPECT_FALSE(Validators::regularExpressionMatcher("123%456", Validators::validPatternStr)); + EXPECT_TRUE(Validators::regularExpressionMatcher("123456", Validators::validPatternStr)); } -TEST(validators, getGroupWithRegularExpression) { - EXPECT_EQ(Validators::getGroupWithRegularExpression(string(), string()), ""); +TEST(ValidatorsTest, GetGroupWithRegularExpression) { + EXPECT_EQ(Validators::getGroupWithRegularExpression("", ""), ""); } -TEST(validators, checkTopic) { - EXPECT_THROW(Validators::checkTopic(string()), MQClientException); - string exceptionTopic = "1234567890"; +TEST(ValidatorsTest, CheckTopic) { + EXPECT_THROW(Validators::checkTopic(""), MQClientException); + std::string exceptionTopic = "1234567890"; for (int i = 0; i < 25; i++) { exceptionTopic.append("1234567890"); } EXPECT_THROW(Validators::checkTopic(exceptionTopic), MQClientException); - EXPECT_THROW(Validators::checkTopic("TBW102"), MQClientException); } -TEST(validators, checkGroup) { - EXPECT_THROW(Validators::checkGroup(string()), MQClientException); - string exceptionTopic = "1234567890"; +TEST(ValidatorsTest, CheckGroup) { + EXPECT_THROW(Validators::checkGroup(""), MQClientException); + std::string exceptionTopic = "1234567890"; for (int i = 0; i < 25; i++) { exceptionTopic.append("1234567890"); } EXPECT_THROW(Validators::checkGroup(exceptionTopic), MQClientException); } -TEST(validators, checkMessage) { - MQMessage message("testTopic", string()); - - EXPECT_THROW(Validators::checkMessage(MQMessage("testTopic", string()), 1), MQClientException); - - EXPECT_THROW(Validators::checkMessage(MQMessage("testTopic", string("123")), 2), MQClientException); +TEST(ValidatorsTest, CheckMessage) { + MQMessage message("testTopic", ""); + EXPECT_THROW(Validators::checkMessage(MQMessage("testTopic", ""), 1), MQClientException); + EXPECT_THROW(Validators::checkMessage(MQMessage("testTopic", "123"), 2), MQClientException); } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "validators.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "ValidatorsTest.Skipped"; + return RUN_ALL_TESTS(); } diff --git a/test/src/common/VirtualEnvUtilTest.cpp b/test/src/common/VirtualEnvUtilTest.cpp index f02889cf7..1d2b92383 100644 --- a/test/src/common/VirtualEnvUtilTest.cpp +++ b/test/src/common/VirtualEnvUtilTest.cpp @@ -14,38 +14,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "string.h" +#include +#include -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include #include "VirtualEnvUtil.h" -using std::string; - -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::VirtualEnvUtil; -VirtualEnvUtil virtualEnvUtil; - -TEST(virtualEnvUtil, buildWithProjectGroup) { - string origin = "origin"; - string projectGroup; - EXPECT_EQ(virtualEnvUtil.buildWithProjectGroup(origin, string()), origin); - - EXPECT_EQ(virtualEnvUtil.buildWithProjectGroup(origin, string("123")), origin); +TEST(VirtualEnvUtilTest, BuildWithProjectGroup) { + EXPECT_EQ(VirtualEnvUtil::buildWithProjectGroup("origin", ""), "origin"); + EXPECT_EQ(VirtualEnvUtil::buildWithProjectGroup("origin", "123"), "origin%PROJECT_123%"); } -TEST(virtualEnvUtil, clearProjectGroup) {} +TEST(VirtualEnvUtilTest, ClearProjectGroup) {} int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); - testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "messageExt.init"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "VirtualEnvUtilTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/common/big_endianTest.cpp b/test/src/common/big_endianTest.cpp deleted file mode 100644 index 5469dedb1..000000000 --- a/test/src/common/big_endianTest.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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 - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "big_endian.h" - -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; -using testing::Return; - -using rocketmq::BigEndianReader; -using rocketmq::BigEndianWriter; - -TEST(big_endian, bigEndianObject) { - char* buf = (char*)malloc(sizeof(char) * 32); - - BigEndianWriter writer(buf, 32); - BigEndianReader reader(buf, 32); - - uint8_t* unit8 = (uint8_t*)malloc(sizeof(uint8_t)); - EXPECT_TRUE(writer.WriteU8((uint8_t)12)); - EXPECT_TRUE(reader.ReadU8(unit8)); - EXPECT_EQ(*unit8, 12); - free(unit8); - - uint16_t* unit16 = (uint16_t*)malloc(sizeof(uint16_t)); - EXPECT_TRUE(writer.WriteU16((uint16_t)1200)); - EXPECT_TRUE(reader.ReadU16(unit16)); - EXPECT_EQ(*unit16, 1200); - free(unit16); - - uint32_t* unit32 = (uint32_t*)malloc(sizeof(uint32_t)); - - EXPECT_TRUE(writer.WriteU32((uint32_t)120000)); - EXPECT_TRUE(reader.ReadU32(unit32)); - EXPECT_EQ(*unit32, 120000); - free(unit32); - - uint64_t* unit64 = (uint64_t*)malloc(sizeof(uint64_t)); - - EXPECT_TRUE(writer.WriteU64((uint64_t)120000)); - EXPECT_TRUE(reader.ReadU64(unit64)); - EXPECT_EQ(*unit64, 120000); - free(unit64); - - char* newBuf = (char*)malloc(sizeof(char) * 8); - char* writeBuf = (char*)malloc(sizeof(char) * 8); - strcpy(writeBuf, "RocketMQ"); - EXPECT_TRUE(writer.WriteBytes(writeBuf, (size_t)8)); - EXPECT_TRUE(reader.ReadBytes(newBuf, (size_t)8)); - EXPECT_EQ(*writeBuf, *newBuf); - - free(newBuf); - free(writeBuf); -} - -TEST(big_endian, bigEndian) { - char writeBuf[8]; - - /*TODO - char *newBuf = (char *) malloc(sizeof(char) * 8); - strcpy(newBuf, "RocketMQ"); - - char readBuf[8]; - rocketmq::WriteBigEndian(writeBuf, newBuf); - rocketmq::ReadBigEndian(writeBuf, readBuf); - EXPECT_EQ(writeBuf, readBuf); - */ - - rocketmq::WriteBigEndian(writeBuf, (uint8_t)12); - uint8_t* out = (uint8_t*)malloc(sizeof(uint8_t)); - rocketmq::ReadBigEndian(writeBuf, out); - EXPECT_EQ(*out, 12); - free(out); -} - -int main(int argc, char* argv[]) { - InitGoogleMock(&argc, argv); - testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "big_endian.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; -} diff --git a/test/src/extern/CMessageExtTest.cpp b/test/src/extern/CMessageExtTest.cpp index 8752d5ce4..442ae5768 100644 --- a/test/src/extern/CMessageExtTest.cpp +++ b/test/src/extern/CMessageExtTest.cpp @@ -15,20 +15,20 @@ * limitations under the License. */ -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include +#include -#include "CCommon.h" -#include "CMessageExt.h" #include "MQMessageExt.h" +#include "c/CCommon.h" +#include "c/CMessageExt.h" -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::MQMessageExt; -TEST(cmessageExt, info) { +TEST(CMessageExtTest, CheckProperties) { MQMessageExt* mqMessageExt = new MQMessageExt(); CMessageExt* messageExt = (CMessageExt*)mqMessageExt; @@ -44,8 +44,8 @@ TEST(cmessageExt, info) { mqMessageExt->setBody("testBody"); EXPECT_EQ(GetMessageBody(messageExt), mqMessageExt->getBody()); - mqMessageExt->setProperty("testKey", "testValues"); - EXPECT_EQ(GetMessageProperty(messageExt, "testKey"), mqMessageExt->getProperty("testKey")); + mqMessageExt->putProperty("testProperty", "testValue"); + EXPECT_EQ(GetMessageProperty(messageExt, "testProperty"), mqMessageExt->getProperty("testProperty")); mqMessageExt->setMsgId("msgId123456"); EXPECT_EQ(GetMessageId(messageExt), mqMessageExt->getMsgId()); @@ -80,7 +80,7 @@ TEST(cmessageExt, info) { delete mqMessageExt; } -TEST(cmessageExt, null) { +TEST(CMessageExtTest, CheckNull) { EXPECT_TRUE(GetMessageTopic(NULL) == NULL); EXPECT_TRUE(GetMessageTags(NULL) == NULL); EXPECT_TRUE(GetMessageKeys(NULL) == NULL); @@ -100,7 +100,7 @@ TEST(cmessageExt, null) { int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); - testing::GTEST_FLAG(filter) = "cmessageExt.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(throw_on_failure) = true; + testing::GTEST_FLAG(filter) = "CMessageExtTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/extern/CMessageTest.cpp b/test/src/extern/CMessageTest.cpp index f6da8fa84..446c3d88b 100644 --- a/test/src/extern/CMessageTest.cpp +++ b/test/src/extern/CMessageTest.cpp @@ -14,20 +14,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include +#include -#include "CCommon.h" -#include "CMessage.h" #include "MQMessage.h" +#include "c/CCommon.h" +#include "c/CMessage.h" -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::MQMessage; -TEST(cmessages, info) { +TEST(CMessagesTest, CheckProperties) { CMessage* message = CreateMessage(NULL); MQMessage* mqMessage = (MQMessage*)message; EXPECT_EQ(mqMessage->getTopic(), ""); @@ -47,22 +47,22 @@ TEST(cmessages, info) { SetByteMessageBody(message, "testBody", 5); EXPECT_EQ(mqMessage->getBody(), "testB"); - SetMessageProperty(message, "testKey", "testValue"); - EXPECT_EQ(mqMessage->getProperty("testKey"), "testValue"); + SetMessageProperty(message, "testProperty", "testValue"); + EXPECT_EQ(mqMessage->getProperty("testProperty"), "testValue"); SetDelayTimeLevel(message, 1); EXPECT_EQ(mqMessage->getDelayTimeLevel(), 1); EXPECT_EQ(DestroyMessage(message), OK); - CMessage* twomessage = CreateMessage("testTwoTopic"); - MQMessage* twoMqMessage = (MQMessage*)twomessage; - EXPECT_EQ(twoMqMessage->getTopic(), "testTwoTopic"); + message = CreateMessage("testTopic"); + mqMessage = (MQMessage*)message; + EXPECT_EQ(mqMessage->getTopic(), "testTopic"); - EXPECT_EQ(DestroyMessage(twomessage), OK); + EXPECT_EQ(DestroyMessage(message), OK); } -TEST(cmessages, null) { +TEST(CMessagesTest, CheckNull) { EXPECT_EQ(SetMessageTopic(NULL, NULL), NULL_POINTER); EXPECT_EQ(SetMessageTags(NULL, NULL), NULL_POINTER); EXPECT_EQ(SetMessageKeys(NULL, NULL), NULL_POINTER); @@ -74,8 +74,6 @@ TEST(cmessages, null) { int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); - - testing::GTEST_FLAG(filter) = "cmessages.null"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "CMessagesTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/extern/CProducerTest.cpp b/test/src/extern/CProducerTest.cpp index 1491e5156..5c97043eb 100644 --- a/test/src/extern/CProducerTest.cpp +++ b/test/src/extern/CProducerTest.cpp @@ -14,33 +14,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "string.h" +#include +#include -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "CMessage.h" -#include "CProducer.h" -#include "CSendResult.h" - -#include "AsyncCallback.h" #include "DefaultMQProducer.h" #include "MQMessage.h" #include "MQMessageQueue.h" #include "MQSelector.h" #include "SendResult.h" #include "SessionCredentials.h" +#include "c/CMessage.h" +#include "c/CProducer.h" +#include "c/CSendResult.h" -using std::string; - -using ::testing::_; -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::_; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Mock; using testing::Return; using rocketmq::DefaultMQProducer; -using rocketmq::elogLevel; using rocketmq::MessageQueueSelector; using rocketmq::MQMessage; using rocketmq::MQMessageQueue; @@ -51,31 +44,31 @@ using rocketmq::SessionCredentials; class MockDefaultMQProducer : public DefaultMQProducer { public: - MockDefaultMQProducer(const string& groupname) : DefaultMQProducer(groupname) {} - MOCK_METHOD0(start, void()); - MOCK_METHOD0(shutdown, void()); - MOCK_METHOD2(setLogFileSizeAndNum, void(int, long)); - MOCK_METHOD1(SetProducerLogLevel, void(elogLevel)); - MOCK_METHOD2(send, SendResult(MQMessage&, bool)); - MOCK_METHOD3(send, void(MQMessage&, SendCallback*, bool)); - MOCK_METHOD2(sendOneway, void(MQMessage&, bool)); - MOCK_METHOD5(send, SendResult(MQMessage&, MessageQueueSelector*, void*, int, bool)); + MockDefaultMQProducer(const std::string& groupname) : DefaultMQProducer(groupname) {} + + MOCK_METHOD(void, start, (), (override)); + MOCK_METHOD(void, shutdown, (), (override)); + + MOCK_METHOD(SendResult, send, (MQMessage*), (override)); + MOCK_METHOD(void, send, (MQMessage*, SendCallback*), (noexcept, override)); + MOCK_METHOD(SendResult, send, (MQMessage*, MessageQueueSelector*, void*, long), (override)); + MOCK_METHOD(void, sendOneway, (MQMessage*), (override)); }; void CSendSuccessCallbackFunc(CSendResult result) {} -void cSendExceptionCallbackFunc(CMQException e) {} +void CSendExceptionCallbackFunc(CMQException e) {} -TEST(cProducer, SendMessageAsync) { +TEST(CProducerTest, SendMessageAsync) { MockDefaultMQProducer* mockProducer = new MockDefaultMQProducer("testGroup"); CProducer* cProducer = (CProducer*)mockProducer; - CMessage* msg = (CMessage*)new MQMessage(); + CMessage* msg = CreateMessage(""); EXPECT_EQ(SendMessageAsync(NULL, NULL, NULL, NULL), NULL_POINTER); EXPECT_EQ(SendMessageAsync(cProducer, NULL, NULL, NULL), NULL_POINTER); EXPECT_EQ(SendMessageAsync(cProducer, msg, CSendSuccessCallbackFunc, NULL), NULL_POINTER); EXPECT_CALL(*mockProducer, send(_, _)).Times(1); - EXPECT_EQ(SendMessageAsync(cProducer, msg, CSendSuccessCallbackFunc, cSendExceptionCallbackFunc), OK); + EXPECT_EQ(SendMessageAsync(cProducer, msg, CSendSuccessCallbackFunc, CSendExceptionCallbackFunc), OK); Mock::AllowLeak(mockProducer); DestroyMessage(msg); } @@ -84,7 +77,7 @@ int QueueSelectorCallbackFunc(int size, CMessage* msg, void* arg) { return 0; } -TEST(cProducer, sendMessageOrderly) { +TEST(CProducerTest, SendMessageOrderly) { MockDefaultMQProducer* mockProducer = new MockDefaultMQProducer("testGroup"); CProducer* cProducer = (CProducer*)mockProducer; CMessage* msg = (CMessage*)new MQMessage(); @@ -96,7 +89,7 @@ TEST(cProducer, sendMessageOrderly) { EXPECT_EQ(SendMessageOrderly(cProducer, msg, QueueSelectorCallbackFunc, NULL, 1, NULL), NULL_POINTER); EXPECT_EQ(SendMessageOrderly(cProducer, msg, QueueSelectorCallbackFunc, msg, 1, NULL), NULL_POINTER); - EXPECT_CALL(*mockProducer, send(_, _, _, _, _)) + EXPECT_CALL(*mockProducer, send(_, _, _, _)) .WillOnce(Return(SendResult(SendStatus::SEND_OK, "3", "offset1", messageQueue, 14))); // EXPECT_EQ(SendMessageOrderly(cProducer, msg, callback, msg, 1, result), OK); Mock::AllowLeak(mockProducer); @@ -104,7 +97,7 @@ TEST(cProducer, sendMessageOrderly) { // free(result); } -TEST(cProducer, sendOneway) { +TEST(CProducerTest, SendOneway) { MockDefaultMQProducer* mockProducer = new MockDefaultMQProducer("testGroup"); CProducer* cProducer = (CProducer*)mockProducer; CMessage* msg = (CMessage*)new MQMessage(); @@ -112,13 +105,15 @@ TEST(cProducer, sendOneway) { EXPECT_EQ(SendMessageOneway(NULL, NULL), NULL_POINTER); EXPECT_EQ(SendMessageOneway(cProducer, NULL), NULL_POINTER); - EXPECT_CALL(*mockProducer, sendOneway(_, _)).Times(1); + EXPECT_CALL(*mockProducer, sendOneway(_)).Times(1); EXPECT_EQ(SendMessageOneway(cProducer, msg), OK); + Mock::AllowLeak(mockProducer); + DestroyMessage(msg); } -TEST(cProducer, sendMessageSync) { +TEST(CProducerTest, SendMessageSync) { MockDefaultMQProducer* mockProducer = new MockDefaultMQProducer("testGroup"); CProducer* cProducer = (CProducer*)mockProducer; @@ -133,7 +128,7 @@ TEST(cProducer, sendMessageSync) { result = (CSendResult*)malloc(sizeof(CSendResult)); - EXPECT_CALL(*mockProducer, send(_, _)) + EXPECT_CALL(*mockProducer, send(_)) .Times(5) .WillOnce(Return(SendResult(SendStatus::SEND_FLUSH_DISK_TIMEOUT, "1", "offset1", messageQueue, 14))) .WillOnce(Return(SendResult(SendStatus::SEND_FLUSH_SLAVE_TIMEOUT, "2", "offset1", messageQueue, 14))) @@ -155,12 +150,14 @@ TEST(cProducer, sendMessageSync) { EXPECT_EQ(SendMessageSync(cProducer, msg, result), OK); EXPECT_EQ(result->sendStatus, E_SEND_OK); + Mock::AllowLeak(mockProducer); + DestroyMessage(msg); free(result); } -TEST(cProducer, infoMock) { +TEST(CProducerTest, InfoMock) { MockDefaultMQProducer* mockProducer = new MockDefaultMQProducer("testGroup"); CProducer* cProducer = (CProducer*)mockProducer; @@ -170,15 +167,10 @@ TEST(cProducer, infoMock) { EXPECT_CALL(*mockProducer, shutdown()).Times(1); EXPECT_EQ(ShutdownProducer(cProducer), OK); - EXPECT_CALL(*mockProducer, setLogFileSizeAndNum(_, _)).Times(1); - EXPECT_EQ(SetProducerLogFileNumAndSize(cProducer, 1, 1), OK); - - EXPECT_CALL(*mockProducer, SetProducerLogLevel(_)).Times(1); - EXPECT_EQ(SetProducerLogLevel(cProducer, E_LOG_LEVEL_FATAL), OK); Mock::AllowLeak(mockProducer); } -TEST(cProducer, info) { +TEST(CProducerTest, Info) { CProducer* cProducer = CreateProducer("groupTest"); DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)cProducer; EXPECT_TRUE(cProducer != NULL); @@ -204,12 +196,13 @@ TEST(cProducer, info) { EXPECT_EQ(SetProducerSessionCredentials(NULL, NULL, NULL, NULL), NULL_POINTER); EXPECT_EQ(SetProducerSessionCredentials(cProducer, "accessKey", "secretKey", "channel"), OK); - SessionCredentials sessionCredentials = defaultMQProducer->getSessionCredentials(); - EXPECT_EQ(sessionCredentials.getAccessKey(), "accessKey"); + // SessionCredentials sessionCredentials = defaultMQProducer->getSessionCredentials(); + // EXPECT_EQ(sessionCredentials.getAccessKey(), "accessKey"); + Mock::AllowLeak(defaultMQProducer); } -TEST(cProducer, null) { +TEST(CProducerTest, CheckNull) { EXPECT_TRUE(CreateProducer(NULL) == NULL); EXPECT_EQ(StartProducer(NULL), NULL_POINTER); EXPECT_EQ(ShutdownProducer(NULL), NULL_POINTER); @@ -228,7 +221,6 @@ TEST(cProducer, null) { int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "cProducer.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "CProducerTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/extern/CPullConsumerTest.cpp b/test/src/extern/CPullConsumerTest.cpp index b55b99e05..a356a5774 100644 --- a/test/src/extern/CPullConsumerTest.cpp +++ b/test/src/extern/CPullConsumerTest.cpp @@ -14,35 +14,30 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include +#include #include #include -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "CCommon.h" -#include "CPullConsumer.h" - #include "DefaultMQPullConsumer.h" -#include "MQClient.h" +#include "MQClientInstance.h" #include "MQMessageExt.h" #include "MQMessageQueue.h" #include "PullResult.h" #include "SessionCredentials.h" +#include "c/CCommon.h" +#include "c/CPullConsumer.h" -using std::string; -using std::vector; - -using ::testing::_; +using testing::_; using testing::Expectation; -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; +using testing::Mock; using testing::Return; using testing::SetArgReferee; using rocketmq::DefaultMQPullConsumer; -using rocketmq::elogLevel; using rocketmq::MessageModel; using rocketmq::MQMessageExt; using rocketmq::MQMessageQueue; @@ -52,41 +47,34 @@ using rocketmq::SessionCredentials; class MockDefaultMQPullConsumer : public DefaultMQPullConsumer { public: - MockDefaultMQPullConsumer(const string& groupname) : DefaultMQPullConsumer(groupname) {} - MOCK_METHOD0(start, void()); - MOCK_METHOD0(shutdown, void()); - MOCK_METHOD2(setLogFileSizeAndNum, void(int, long)); - MOCK_METHOD1(setLogLevel, void(elogLevel)); - MOCK_METHOD2(fetchSubscribeMessageQueues, void(const string&, vector&)); - MOCK_METHOD4(pull, PullResult(const MQMessageQueue&, const string&, int64, int)); + MockDefaultMQPullConsumer(const std::string& groupname) : DefaultMQPullConsumer(groupname) {} + + MOCK_METHOD(void, start, (), (override)); + MOCK_METHOD(void, shutdown, (), (override)); + MOCK_METHOD(void, fetchSubscribeMessageQueues, (const std::string&, std::vector&), (override)); + MOCK_METHOD(PullResult, pull, (const MQMessageQueue&, const std::string&, int64_t, int), (override)); }; -TEST(cpullConsumer, pull) { +TEST(CPullConsumerTest, Pull) { MockDefaultMQPullConsumer* mqPullConsumer = new MockDefaultMQPullConsumer("groudId"); - CPullConsumer* pullConsumer = (CPullConsumer*)mqPullConsumer; + CPullConsumer* pullConsumer = reinterpret_cast(static_cast(mqPullConsumer)); - CMessageQueue* cMessageQueue; - cMessageQueue = (CMessageQueue*)malloc(sizeof(CMessageQueue)); + CMessageQueue* cMessageQueue = (CMessageQueue*)malloc(sizeof(CMessageQueue)); strncpy(cMessageQueue->topic, "testTopic", 8); strncpy(cMessageQueue->brokerName, "testBroker", 9); cMessageQueue->queueId = 1; PullResult timeOutPullResult(PullStatus::BROKER_TIMEOUT, 1, 2, 3); - PullResult noNewMsgPullResult(PullStatus::NO_NEW_MSG, 1, 2, 3); - PullResult noMatchedMsgPullResult(PullStatus::NO_MATCHED_MSG, 1, 2, 3); - PullResult offsetIllegalPullResult(PullStatus::OFFSET_ILLEGAL, 1, 2, 3); - PullResult defaultPullResult((PullStatus)-1, 1, 2, 3); - vector src; + std::vector> src; for (int i = 0; i < 5; i++) { - MQMessageExt ext; + auto ext = std::make_shared(); src.push_back(ext); } - PullResult foundPullResult(PullStatus::FOUND, 1, 2, 3, src); EXPECT_CALL(*mqPullConsumer, pull(_, _, _, _)) @@ -121,7 +109,7 @@ TEST(cpullConsumer, pull) { delete mqPullConsumer; } -TEST(cpullConsumer, infoMock) { +TEST(CPullConsumerTest, InfoMock) { MockDefaultMQPullConsumer* mqPullConsumer = new MockDefaultMQPullConsumer("groudId"); CPullConsumer* pullConsumer = (CPullConsumer*)mqPullConsumer; @@ -152,7 +140,7 @@ TEST(cpullConsumer, infoMock) { delete mqPullConsumer; } -TEST(cpullConsumer, init) { +TEST(CPullConsumerTest, Init) { CPullConsumer* pullConsumer = CreatePullConsumer("testGroupId"); DefaultMQPullConsumer* defaultMQPullConsumer = (DefaultMQPullConsumer*)pullConsumer; EXPECT_FALSE(pullConsumer == NULL); @@ -164,8 +152,8 @@ TEST(cpullConsumer, init) { EXPECT_EQ(defaultMQPullConsumer->getNamesrvAddr(), "127.0.0.1:10091"); EXPECT_EQ(SetPullConsumerSessionCredentials(pullConsumer, "accessKey", "secretKey", "channel"), OK); - SessionCredentials sessionCredentials = defaultMQPullConsumer->getSessionCredentials(); - EXPECT_EQ(sessionCredentials.getAccessKey(), "accessKey"); + // SessionCredentials sessionCredentials = defaultMQPullConsumer->getSessionCredentials(); + // EXPECT_EQ(sessionCredentials.getAccessKey(), "accessKey"); EXPECT_EQ(SetPullConsumerLogPath(pullConsumer, NULL), OK); @@ -173,7 +161,7 @@ TEST(cpullConsumer, init) { EXPECT_EQ(SetPullConsumerLogLevel(pullConsumer, E_LOG_LEVEL_DEBUG), OK); } -TEST(cpullConsumer, null) { +TEST(CPullConsumerTest, CheckNull) { CPullConsumer* pullConsumer = CreatePullConsumer("testGroupId"); DefaultMQPullConsumer* defaultMQPullConsumer = (DefaultMQPullConsumer*)pullConsumer; EXPECT_FALSE(pullConsumer == NULL); @@ -185,8 +173,8 @@ TEST(cpullConsumer, null) { EXPECT_EQ(defaultMQPullConsumer->getNamesrvAddr(), "127.0.0.1:10091"); EXPECT_EQ(SetPullConsumerSessionCredentials(pullConsumer, "accessKey", "secretKey", "channel"), OK); - SessionCredentials sessionCredentials = defaultMQPullConsumer->getSessionCredentials(); - EXPECT_EQ(sessionCredentials.getAccessKey(), "accessKey"); + // SessionCredentials sessionCredentials = defaultMQPullConsumer->getSessionCredentials(); + // EXPECT_EQ(sessionCredentials.getAccessKey(), "accessKey"); EXPECT_EQ(SetPullConsumerLogPath(pullConsumer, NULL), OK); // EXPECT_EQ(SetPullConsumerLogFileNumAndSize(pullConsumer,NULL,NULL),NULL_POINTER); @@ -199,7 +187,6 @@ TEST(cpullConsumer, null) { int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "cpullConsumer.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "CPullConsumerTest.Skipped"; + return RUN_ALL_TESTS(); } diff --git a/test/src/extern/CPushConsumerTest.cpp b/test/src/extern/CPushConsumerTest.cpp index 498f46f6d..e41d7f81c 100644 --- a/test/src/extern/CPushConsumerTest.cpp +++ b/test/src/extern/CPushConsumerTest.cpp @@ -15,45 +15,37 @@ * limitations under the License. */ -#include "string.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "CPushConsumer.h" +#include +#include #include "ConsumeType.h" #include "DefaultMQPushConsumer.h" #include "MQMessageListener.h" #include "SessionCredentials.h" +#include "c/CPushConsumer.h" -using std::string; - -using ::testing::_; -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::_; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Mock; using testing::Return; using rocketmq::DefaultMQPushConsumer; -using rocketmq::elogLevel; using rocketmq::MessageListenerType; using rocketmq::MessageModel; using rocketmq::SessionCredentials; class MockDefaultMQPushConsumer : public DefaultMQPushConsumer { public: - MockDefaultMQPushConsumer(const string& groupname) : DefaultMQPushConsumer(groupname) {} + MockDefaultMQPushConsumer(const std::string& groupname) : DefaultMQPushConsumer(groupname) {} - MOCK_METHOD0(start, void()); - MOCK_METHOD0(shutdown, void()); - MOCK_METHOD2(setLogFileSizeAndNum, void(int, long)); - MOCK_METHOD1(setLogLevel, void(elogLevel)); + MOCK_METHOD(void, start, (), (override)); + MOCK_METHOD(void, shutdown, (), (override)); }; -TEST(cPushComsumer, infomock) { +TEST(CPushComsumerTest, InfoMock) { MockDefaultMQPushConsumer* pushComsumer = new MockDefaultMQPushConsumer("testGroup"); - CPushConsumer* consumer = (CPushConsumer*)pushComsumer; + CPushConsumer* consumer = reinterpret_cast(static_cast(pushComsumer)); EXPECT_CALL(*pushComsumer, start()).Times(1); EXPECT_EQ(StartPushConsumer(consumer), OK); @@ -61,65 +53,59 @@ TEST(cPushComsumer, infomock) { EXPECT_CALL(*pushComsumer, shutdown()).Times(1); EXPECT_EQ(ShutdownPushConsumer(consumer), OK); - EXPECT_CALL(*pushComsumer, setLogFileSizeAndNum(1, 1)).Times(1); - pushComsumer->setLogFileSizeAndNum(1, 1); - EXPECT_EQ(SetPushConsumerLogFileNumAndSize(consumer, 1, 1), OK); - - // EXPECT_CALL(*pushComsumer,setLogLevel(_)).Times(1); - EXPECT_EQ(SetPushConsumerLogLevel(consumer, E_LOG_LEVEL_FATAL), OK); - - Mock::AllowLeak(pushComsumer); + delete pushComsumer; } int MessageCallBackFunc(CPushConsumer* consumer, CMessageExt* msg) { return 0; } -TEST(cPushComsumer, info) { - CPushConsumer* cpushConsumer = CreatePushConsumer("testGroup"); - DefaultMQPushConsumer* mqPushConsumer = (DefaultMQPushConsumer*)cpushConsumer; +TEST(CPushComsumerTest, Info) { + CPushConsumer* cPushConsumer = CreatePushConsumer("testGroup"); + DefaultMQPushConsumer* mqPushConsumer = reinterpret_cast(cPushConsumer); - EXPECT_TRUE(cpushConsumer != NULL); - EXPECT_EQ(string(GetPushConsumerGroupID(cpushConsumer)), "testGroup"); + EXPECT_TRUE(cPushConsumer != NULL); + EXPECT_STREQ(GetPushConsumerGroupID(cPushConsumer), "testGroup"); - EXPECT_EQ(SetPushConsumerGroupID(cpushConsumer, "testGroupTwo"), OK); - EXPECT_EQ(string(GetPushConsumerGroupID(cpushConsumer)), "testGroupTwo"); + EXPECT_EQ(SetPushConsumerGroupID(cPushConsumer, "testGroupTwo"), OK); + EXPECT_STREQ(GetPushConsumerGroupID(cPushConsumer), "testGroupTwo"); - EXPECT_EQ(SetPushConsumerNameServerAddress(cpushConsumer, "127.0.0.1:9876"), OK); + EXPECT_EQ(SetPushConsumerNameServerAddress(cPushConsumer, "127.0.0.1:9876"), OK); EXPECT_EQ(mqPushConsumer->getNamesrvAddr(), "127.0.0.1:9876"); - EXPECT_EQ(Subscribe(cpushConsumer, "testTopic", "testSub"), OK); - - EXPECT_EQ(RegisterMessageCallbackOrderly(cpushConsumer, MessageCallBackFunc), OK); - EXPECT_EQ(mqPushConsumer->getMessageListenerType(), MessageListenerType::messageListenerOrderly); + EXPECT_EQ(Subscribe(cPushConsumer, "testTopic", "testSub"), OK); - EXPECT_EQ(RegisterMessageCallback(cpushConsumer, MessageCallBackFunc), OK); - EXPECT_EQ(mqPushConsumer->getMessageListenerType(), MessageListenerType::messageListenerConcurrently); + EXPECT_EQ(RegisterMessageCallbackOrderly(cPushConsumer, MessageCallBackFunc), OK); + EXPECT_EQ(mqPushConsumer->getMessageListener()->getMessageListenerType(), + MessageListenerType::messageListenerOrderly); + EXPECT_EQ(UnregisterMessageCallbackOrderly(cPushConsumer), OK); - EXPECT_EQ(UnregisterMessageCallbackOrderly(cpushConsumer), OK); - EXPECT_EQ(UnregisterMessageCallback(cpushConsumer), OK); + EXPECT_EQ(RegisterMessageCallback(cPushConsumer, MessageCallBackFunc), OK); + EXPECT_EQ(mqPushConsumer->getMessageListener()->getMessageListenerType(), + MessageListenerType::messageListenerConcurrently); + EXPECT_EQ(UnregisterMessageCallback(cPushConsumer), OK); - EXPECT_EQ(SetPushConsumerThreadCount(cpushConsumer, 10), OK); - EXPECT_EQ(mqPushConsumer->getConsumeThreadCount(), 10); + EXPECT_EQ(SetPushConsumerThreadCount(cPushConsumer, 10), OK); + EXPECT_EQ(mqPushConsumer->getConsumeThreadNum(), 10); - EXPECT_EQ(SetPushConsumerMessageBatchMaxSize(cpushConsumer, 1024), OK); + EXPECT_EQ(SetPushConsumerMessageBatchMaxSize(cPushConsumer, 1024), OK); EXPECT_EQ(mqPushConsumer->getConsumeMessageBatchMaxSize(), 1024); - EXPECT_EQ(SetPushConsumerInstanceName(cpushConsumer, "instance"), OK); + EXPECT_EQ(SetPushConsumerInstanceName(cPushConsumer, "instance"), OK); EXPECT_EQ(mqPushConsumer->getInstanceName(), "instance"); - EXPECT_EQ(SetPushConsumerSessionCredentials(cpushConsumer, "accessKey", "secretKey", "channel"), OK); - SessionCredentials sessionCredentials = mqPushConsumer->getSessionCredentials(); - EXPECT_EQ(sessionCredentials.getAccessKey(), "accessKey"); + EXPECT_EQ(SetPushConsumerSessionCredentials(cPushConsumer, "accessKey", "secretKey", "channel"), OK); + // SessionCredentials sessionCredentials = mqPushConsumer->getSessionCredentials(); + // EXPECT_EQ(sessionCredentials.getAccessKey(), "accessKey"); - EXPECT_EQ(SetPushConsumerMessageModel(cpushConsumer, BROADCASTING), OK); + EXPECT_EQ(SetPushConsumerMessageModel(cPushConsumer, BROADCASTING), OK); EXPECT_EQ(mqPushConsumer->getMessageModel(), MessageModel::BROADCASTING); - Mock::AllowLeak(mqPushConsumer); + DestroyPushConsumer(cPushConsumer); } -TEST(cPushComsumer, null) { - CPushConsumer* cpushConsumer = CreatePushConsumer("testGroup"); +TEST(CPushComsumerTest, CheckNull) { + CPushConsumer* cPushConsumer = CreatePushConsumer("testGroup"); EXPECT_TRUE(CreatePushConsumer(NULL) == NULL); EXPECT_EQ(DestroyPushConsumer(NULL), NULL_POINTER); @@ -130,7 +116,7 @@ TEST(cPushComsumer, null) { EXPECT_EQ(SetPushConsumerNameServerAddress(NULL, NULL), NULL_POINTER); EXPECT_EQ(Subscribe(NULL, NULL, NULL), NULL_POINTER); EXPECT_EQ(RegisterMessageCallbackOrderly(NULL, NULL), NULL_POINTER); - EXPECT_EQ(RegisterMessageCallbackOrderly(cpushConsumer, NULL), NULL_POINTER); + EXPECT_EQ(RegisterMessageCallbackOrderly(cPushConsumer, NULL), NULL_POINTER); EXPECT_EQ(RegisterMessageCallback(NULL, NULL), NULL_POINTER); EXPECT_EQ(UnregisterMessageCallbackOrderly(NULL), NULL_POINTER); EXPECT_EQ(UnregisterMessageCallback(NULL), NULL_POINTER); @@ -142,11 +128,13 @@ TEST(cPushComsumer, null) { EXPECT_EQ(SetPushConsumerLogFileNumAndSize(NULL, 1, 1), NULL_POINTER); EXPECT_EQ(SetPushConsumerLogLevel(NULL, E_LOG_LEVEL_LEVEL_NUM), NULL_POINTER); EXPECT_EQ(SetPushConsumerMessageModel(NULL, BROADCASTING), NULL_POINTER); + + DestroyPushConsumer(cPushConsumer); } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); - testing::GTEST_FLAG(filter) = "cPushComsumer.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(throw_on_failure) = true; + testing::GTEST_FLAG(filter) = "CPushComsumerTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/message/MQDecoderTest.cpp b/test/src/message/MQDecoderTest.cpp index 748d89c54..2d43ac6a4 100644 --- a/test/src/message/MQDecoderTest.cpp +++ b/test/src/message/MQDecoderTest.cpp @@ -15,28 +15,27 @@ * limitations under the License. */ +#include +#include #include + #include #include -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "MemoryInputStream.h" -#include "MemoryOutputStream.h" -#include "CommandHeader.h" #include "MQDecoder.h" #include "MQMessage.h" +#include "MQMessageConst.h" #include "MQMessageExt.h" #include "MQMessageId.h" +#include "MemoryInputStream.h" +#include "MemoryOutputStream.h" #include "MessageSysFlag.h" #include "RemotingCommand.h" #include "UtilAll.h" +#include "protocol/header/CommandHeader.h" -using namespace std; - -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::MemoryBlock; @@ -45,6 +44,7 @@ using rocketmq::MemoryOutputStream; using rocketmq::MessageSysFlag; using rocketmq::MQDecoder; using rocketmq::MQMessage; +using rocketmq::MQMessageConst; using rocketmq::MQMessageExt; using rocketmq::MQMessageId; using rocketmq::RemotingCommand; @@ -52,153 +52,155 @@ using rocketmq::SendMessageRequestHeader; using rocketmq::UtilAll; // TODO -TEST(decoders, messageId) { - int host; - int port; - string msgIdStr = - MQDecoder::createMessageId(rocketmq::IPPort2socketAddress(inet_addr("127.0.0.1"), 10091), (int64)1024); - MQMessageId msgId = MQDecoder::decodeMessageId(msgIdStr); +TEST(MessageDecoderTest, MessageId) { + std::string strMsgId = MQDecoder::createMessageId(rocketmq::string2SocketAddress("127.0.0.1:10091"), 1024LL); + EXPECT_EQ(strMsgId, "0100007F0000276B0000000000000400"); + MQMessageId msgId = MQDecoder::decodeMessageId(strMsgId); EXPECT_EQ(msgId.getOffset(), 1024); - - rocketmq::socketAddress2IPPort(msgId.getAddress(), host, port); - EXPECT_EQ(host, inet_addr("127.0.0.1")); - EXPECT_EQ(port, 10091); } -TEST(decoder, decoder) { - MQMessageExt mext; +TEST(MessageDecoderTest, Decode) { MemoryOutputStream* memoryOut = new MemoryOutputStream(1024); + MQMessageExt msgExt; - // 1 TOTALSIZE 4 - memoryOut->writeIntBigEndian(107); - mext.setStoreSize(107); + // 1 TOTALSIZE 4=0+4 + memoryOut->writeIntBigEndian(111); + msgExt.setStoreSize(111); // 2 MAGICCODE sizeof(int) 8=4+4 memoryOut->writeIntBigEndian(14); // 3 BODYCRC 12=8+4 memoryOut->writeIntBigEndian(24); - mext.setBodyCRC(24); - // 4 QUEUEID 16=12+4 + msgExt.setBodyCRC(24); + + // 4 QUEUEID 16=12+4 memoryOut->writeIntBigEndian(4); - mext.setQueueId(4); - // 5 FLAG 20=16+4 + msgExt.setQueueId(4); + + // 5 FLAG 20=16+4 memoryOut->writeIntBigEndian(4); - mext.setFlag(4); - // 6 QUEUEOFFSET 28 = 20+8 - memoryOut->writeInt64BigEndian((int64)1024); - mext.setQueueOffset(1024); - // 7 PHYSICALOFFSET 36=28+8 - memoryOut->writeInt64BigEndian((int64)2048); - mext.setCommitLogOffset(2048); + msgExt.setFlag(4); + + // 6 QUEUEOFFSET 28=20+8 + memoryOut->writeInt64BigEndian(1024LL); + msgExt.setQueueOffset(1024LL); + + // 7 PHYSICALOFFSET 36=28+8 + memoryOut->writeInt64BigEndian(2048LL); + msgExt.setCommitLogOffset(2048LL); + // 8 SYSFLAG 40=36+4 memoryOut->writeIntBigEndian(0); - mext.setSysFlag(0); - // 9 BORNTIMESTAMP 48 = 40+8 - memoryOut->writeInt64BigEndian((int64)4096); - mext.setBornTimestamp(4096); - // 10 BORNHOST 56= 48+8 - memoryOut->writeIntBigEndian(inet_addr("127.0.0.1")); + msgExt.setSysFlag(0); + + // 9 BORNTIMESTAMP 48=40+8 + memoryOut->writeInt64BigEndian(4096LL); + msgExt.setBornTimestamp(4096LL); + + // 10 BORNHOST 56=48+4+4 + memoryOut->writeIntBigEndian(ntohl(inet_addr("127.0.0.1"))); memoryOut->writeIntBigEndian(10091); - mext.setBornHost(rocketmq::IPPort2socketAddress(inet_addr("127.0.0.1"), 10091)); - // 11 STORETIMESTAMP 64 =56+8 - memoryOut->writeInt64BigEndian((int64)4096); - mext.setStoreTimestamp(4096); - // 12 STOREHOST 72 = 64+8 - memoryOut->writeIntBigEndian(inet_addr("127.0.0.2")); + msgExt.setBornHost(rocketmq::string2SocketAddress("127.0.0.1:10091")); + + // 11 STORETIMESTAMP 64=56+8 + memoryOut->writeInt64BigEndian(4096LL); + msgExt.setStoreTimestamp(4096LL); + + // 12 STOREHOST 72=64+4+4 + memoryOut->writeIntBigEndian(ntohl(inet_addr("127.0.0.2"))); memoryOut->writeIntBigEndian(10092); - mext.setStoreHost(rocketmq::IPPort2socketAddress(inet_addr("127.0.0.2"), 10092)); - // 13 RECONSUMETIMES 76 = 72+4 - mext.setReconsumeTimes(111111); - memoryOut->writeIntBigEndian(mext.getReconsumeTimes()); - // 14 Prepared Transaction Offset 84 = 76+8 - memoryOut->writeInt64BigEndian((int64)12); - mext.setPreparedTransactionOffset(12); - // 15 BODY 88 = 84+4 10 - string* body = new string("1234567890"); - mext.setBody(body->c_str()); - memoryOut->writeIntBigEndian(10); - memoryOut->write(body->c_str(), body->size()); + msgExt.setStoreHost(rocketmq::string2SocketAddress("127.0.0.2:10092")); - // 16 TOPIC - memoryOut->writeByte(10); - memoryOut->write(body->c_str(), body->size()); - mext.setTopic(body->c_str()); + // 13 RECONSUMETIMES 76=72+4 + memoryOut->writeIntBigEndian(18); + msgExt.setReconsumeTimes(18); - // 17 PROPERTIES + // 14 Prepared Transaction Offset 84=76+8 + memoryOut->writeInt64BigEndian(12LL); + msgExt.setPreparedTransactionOffset(12LL); + + // 15 BODY 98=84+4+10 + std::string body = "1234567890"; + memoryOut->writeIntBigEndian(body.size()); + memoryOut->write(body.data(), body.size()); + msgExt.setBody(body); + + // 16 TOPIC 109=98+1+10 + std::string topic = "topic_1234"; + memoryOut->writeByte(topic.size()); + memoryOut->write(topic.data(), topic.size()); + msgExt.setTopic(topic); + + // 17 PROPERTIES 111=109+2 memoryOut->writeShortBigEndian(0); - mext.setMsgId(MQDecoder::createMessageId(mext.getStoreHost(), (int64)mext.getCommitLogOffset())); + msgExt.setMsgId(MQDecoder::createMessageId(msgExt.getStoreHost(), (int64_t)msgExt.getCommitLogOffset())); + + auto block = memoryOut->getMemoryBlock(); + auto msgs = MQDecoder::decodes(*static_cast(&block)); + EXPECT_EQ(msgs.size(), 1); - vector mqvec; - MemoryBlock block = memoryOut->getMemoryBlock(); - MQDecoder::decodes(&block, mqvec); - EXPECT_EQ(mqvec.size(), 1); - std::cout << mext.toString() << "\n"; - std::cout << mqvec[0].toString() << "\n"; - EXPECT_EQ(mqvec[0].toString(), mext.toString()); + std::cout << msgs[0]->toString() << std::endl; + std::cout << msgExt.toString() << std::endl; + EXPECT_EQ(msgs[0]->toString(), msgExt.toString()); - mqvec.clear(); - MQDecoder::decodes(&block, mqvec, false); - EXPECT_FALSE(mqvec[0].getBody().size()); + msgs = MQDecoder::decodes(*static_cast(&block), false); + EXPECT_EQ(msgs[0]->getBody().size(), 0); //=============================================================== + // 8 SYSFLAG 40=36+4 - mext.setSysFlag(0 | MessageSysFlag::CompressedFlag); memoryOut->setPosition(36); - memoryOut->writeIntBigEndian(mext.getSysFlag()); + memoryOut->writeIntBigEndian(0 | MessageSysFlag::CompressedFlag); + msgExt.setSysFlag(0 | MessageSysFlag::CompressedFlag); // 15 Body 84 - string outBody; - string boody("123123123"); - UtilAll::deflate(boody, outBody, 5); - mext.setBody(outBody); - + std::string compressedBody; + UtilAll::deflate(body, compressedBody, 5); memoryOut->setPosition(84); - memoryOut->writeIntBigEndian(outBody.size()); - memoryOut->write(outBody.c_str(), outBody.size()); + memoryOut->writeIntBigEndian(compressedBody.size()); + memoryOut->write(compressedBody.data(), compressedBody.size()); + msgExt.setBody(compressedBody); // 16 TOPIC - memoryOut->writeByte(10); - memoryOut->write(body->c_str(), body->size()); - mext.setTopic(body->c_str()); + memoryOut->writeByte(topic.size()); + memoryOut->write(topic.data(), topic.size()); + msgExt.setTopic(topic); // 17 PROPERTIES - map properties; + std::map properties; properties["RocketMQ"] = "cpp-client"; - properties[MQMessage::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX] = "123456"; - mext.setProperties(properties); - mext.setMsgId("123456"); + properties[MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX] = "123456"; + std::string props = MQDecoder::messageProperties2String(properties); + memoryOut->writeShortBigEndian(props.size()); + memoryOut->write(props.data(), props.size()); + msgExt.setProperties(properties); + msgExt.setMsgId("123456"); - string proString = MQDecoder::messageProperties2String(properties); - - memoryOut->writeShortBigEndian(proString.size()); - memoryOut->write(proString.c_str(), proString.size()); - - mext.setStoreSize(memoryOut->getDataSize()); memoryOut->setPosition(0); - memoryOut->writeIntBigEndian(mext.getStoreSize()); + memoryOut->writeIntBigEndian(memoryOut->getDataSize()); + msgExt.setStoreSize(memoryOut->getDataSize()); block = memoryOut->getMemoryBlock(); - MQDecoder::decodes(&block, mqvec); - EXPECT_EQ(mqvec[0].toString(), mext.toString()); + msgs = MQDecoder::decodes(*static_cast(&block)); + EXPECT_EQ(msgs[0]->toString(), msgExt.toString()); } -TEST(decoder, messagePropertiesAndToString) { - map properties; +TEST(MessageDecoderTest, MessagePropertiesAndToString) { + std::map properties; properties["RocketMQ"] = "cpp-client"; - string proString = MQDecoder::messageProperties2String(properties); + std::string props = MQDecoder::messageProperties2String(properties); + EXPECT_EQ(props, "RocketMQ\001cpp-client\002"); - map newProperties; - MQDecoder::string2messageProperties(proString, newProperties); - EXPECT_EQ(properties, newProperties); + auto properties2 = MQDecoder::string2messageProperties(props); + EXPECT_EQ(properties, properties2); } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); - - testing::GTEST_FLAG(filter) = "decoder.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(throw_on_failure) = true; + testing::GTEST_FLAG(filter) = "MessageDecoderTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/message/MQMessageExtTest.cpp b/test/src/message/MQMessageExtTest.cpp index df8303d55..86a28aae0 100644 --- a/test/src/message/MQMessageExtTest.cpp +++ b/test/src/message/MQMessageExtTest.cpp @@ -14,125 +14,116 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include +#include #include "MQMessageExt.h" #include "MessageSysFlag.h" #include "SocketUtil.h" #include "TopicFilterType.h" -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::MessageSysFlag; +using rocketmq::MQMessageClientExt; +using rocketmq::MQMessageConst; using rocketmq::MQMessageExt; using rocketmq::TopicFilterType; -TEST(messageExt, init) { - MQMessageExt messageExt; - EXPECT_EQ(messageExt.getQueueOffset(), 0); - EXPECT_EQ(messageExt.getCommitLogOffset(), 0); - EXPECT_EQ(messageExt.getBornTimestamp(), 0); - EXPECT_EQ(messageExt.getStoreTimestamp(), 0); - EXPECT_EQ(messageExt.getPreparedTransactionOffset(), 0); - EXPECT_EQ(messageExt.getQueueId(), 0); - EXPECT_EQ(messageExt.getStoreSize(), 0); - EXPECT_EQ(messageExt.getReconsumeTimes(), 3); - EXPECT_EQ(messageExt.getBodyCRC(), 0); - EXPECT_EQ(messageExt.getMsgId(), ""); - EXPECT_EQ(messageExt.getOffsetMsgId(), ""); +TEST(MessageExtTest, MessageClientExt) { + MQMessageClientExt messageClientExt; + EXPECT_EQ(messageClientExt.getQueueOffset(), 0); + EXPECT_EQ(messageClientExt.getCommitLogOffset(), 0); + EXPECT_EQ(messageClientExt.getBornTimestamp(), 0); + EXPECT_EQ(messageClientExt.getStoreTimestamp(), 0); + EXPECT_EQ(messageClientExt.getPreparedTransactionOffset(), 0); + EXPECT_EQ(messageClientExt.getQueueId(), 0); + EXPECT_EQ(messageClientExt.getStoreSize(), 0); + EXPECT_EQ(messageClientExt.getReconsumeTimes(), 3); + EXPECT_EQ(messageClientExt.getBodyCRC(), 0); + EXPECT_EQ(messageClientExt.getMsgId(), ""); + EXPECT_EQ(messageClientExt.getOffsetMsgId(), ""); - messageExt.setQueueOffset(1); - EXPECT_EQ(messageExt.getQueueOffset(), 1); + messageClientExt.setQueueOffset(1); + EXPECT_EQ(messageClientExt.getQueueOffset(), 1); - messageExt.setCommitLogOffset(1024); - EXPECT_EQ(messageExt.getCommitLogOffset(), 1024); + messageClientExt.setCommitLogOffset(1024); + EXPECT_EQ(messageClientExt.getCommitLogOffset(), 1024); - messageExt.setBornTimestamp(1024); - EXPECT_EQ(messageExt.getBornTimestamp(), 1024); - - messageExt.setStoreTimestamp(2048); - EXPECT_EQ(messageExt.getStoreTimestamp(), 2048); - - messageExt.setPreparedTransactionOffset(4096); - EXPECT_EQ(messageExt.getPreparedTransactionOffset(), 4096); - - messageExt.setQueueId(2); - EXPECT_EQ(messageExt.getQueueId(), 2); + messageClientExt.setBornTimestamp(1024); + EXPECT_EQ(messageClientExt.getBornTimestamp(), 1024); - messageExt.setStoreSize(12); - EXPECT_EQ(messageExt.getStoreSize(), 12); + messageClientExt.setStoreTimestamp(2048); + EXPECT_EQ(messageClientExt.getStoreTimestamp(), 2048); - messageExt.setReconsumeTimes(48); - EXPECT_EQ(messageExt.getReconsumeTimes(), 48); + messageClientExt.setPreparedTransactionOffset(4096); + EXPECT_EQ(messageClientExt.getPreparedTransactionOffset(), 4096); - messageExt.setBodyCRC(32); - EXPECT_EQ(messageExt.getBodyCRC(), 32); + messageClientExt.setQueueId(2); + EXPECT_EQ(messageClientExt.getQueueId(), 2); - messageExt.setMsgId("MsgId"); - EXPECT_EQ(messageExt.getMsgId(), "MsgId"); + messageClientExt.setStoreSize(12); + EXPECT_EQ(messageClientExt.getStoreSize(), 12); - messageExt.setOffsetMsgId("offsetMsgId"); - EXPECT_EQ(messageExt.getOffsetMsgId(), "offsetMsgId"); + messageClientExt.setReconsumeTimes(48); + EXPECT_EQ(messageClientExt.getReconsumeTimes(), 48); - messageExt.setBornTimestamp(1111); - EXPECT_EQ(messageExt.getBornTimestamp(), 1111); + messageClientExt.setBodyCRC(32); + EXPECT_EQ(messageClientExt.getBodyCRC(), 32); - messageExt.setStoreTimestamp(2222); - EXPECT_EQ(messageExt.getStoreTimestamp(), 2222); + messageClientExt.setMsgId("MsgId"); + EXPECT_EQ(messageClientExt.getMsgId(), ""); + messageClientExt.putProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX, "MsgId"); + EXPECT_EQ(messageClientExt.getMsgId(), "MsgId"); - struct sockaddr_in sa; - sa.sin_family = AF_INET; - sa.sin_port = htons(10091); - sa.sin_addr.s_addr = inet_addr("127.0.0.1"); + messageClientExt.setOffsetMsgId("offsetMsgId"); + EXPECT_EQ(messageClientExt.getOffsetMsgId(), "offsetMsgId"); - sockaddr bornHost; - memcpy(&bornHost, &sa, sizeof(sockaddr)); + messageClientExt.setBornTimestamp(1111); + EXPECT_EQ(messageClientExt.getBornTimestamp(), 1111); - messageExt.setBornHost(bornHost); - EXPECT_EQ(messageExt.getBornHostNameString(), rocketmq::getHostName(bornHost)); - EXPECT_EQ(messageExt.getBornHostString(), rocketmq::socketAddress2String(bornHost)); + messageClientExt.setStoreTimestamp(2222); + EXPECT_EQ(messageClientExt.getStoreTimestamp(), 2222); - struct sockaddr_in storeSa; - storeSa.sin_family = AF_INET; - storeSa.sin_port = htons(10092); - storeSa.sin_addr.s_addr = inet_addr("127.0.0.2"); + messageClientExt.setBornHost(rocketmq::string2SocketAddress("127.0.0.1:10091")); + EXPECT_EQ(messageClientExt.getBornHostString(), "127.0.0.1:10091"); - sockaddr storeHost; - memcpy(&storeHost, &storeSa, sizeof(sockaddr)); - messageExt.setStoreHost(storeHost); - EXPECT_EQ(messageExt.getStoreHostString(), rocketmq::socketAddress2String(storeHost)); + messageClientExt.setStoreHost(rocketmq::string2SocketAddress("127.0.0.2:10092")); + EXPECT_EQ(messageClientExt.getStoreHostString(), "127.0.0.2:10092"); +} - MQMessageExt twoMessageExt(2, 1024, bornHost, 2048, storeHost, "msgId"); - EXPECT_EQ(twoMessageExt.getQueueOffset(), 0); - EXPECT_EQ(twoMessageExt.getCommitLogOffset(), 0); - EXPECT_EQ(twoMessageExt.getBornTimestamp(), 1024); - EXPECT_EQ(twoMessageExt.getStoreTimestamp(), 2048); - EXPECT_EQ(twoMessageExt.getPreparedTransactionOffset(), 0); - EXPECT_EQ(twoMessageExt.getQueueId(), 2); - EXPECT_EQ(twoMessageExt.getStoreSize(), 0); - EXPECT_EQ(twoMessageExt.getReconsumeTimes(), 3); - EXPECT_EQ(twoMessageExt.getBodyCRC(), 0); - EXPECT_EQ(twoMessageExt.getMsgId(), "msgId"); - EXPECT_EQ(twoMessageExt.getOffsetMsgId(), ""); +TEST(MessageExtTest, MessageExt) { + struct sockaddr* bronHost = rocketmq::copySocketAddress(nullptr, rocketmq::string2SocketAddress("127.0.0.1:10091")); + struct sockaddr* storeHost = rocketmq::copySocketAddress(nullptr, rocketmq::string2SocketAddress("127.0.0.2:10092")); - EXPECT_EQ(twoMessageExt.getBornHostNameString(), rocketmq::getHostName(bornHost)); - EXPECT_EQ(twoMessageExt.getBornHostString(), rocketmq::socketAddress2String(bornHost)); + MQMessageExt messageExt(2, 1024, bronHost, 2048, storeHost, "msgId"); + EXPECT_EQ(messageExt.getQueueOffset(), 0); + EXPECT_EQ(messageExt.getCommitLogOffset(), 0); + EXPECT_EQ(messageExt.getBornTimestamp(), 1024); + EXPECT_EQ(messageExt.getStoreTimestamp(), 2048); + EXPECT_EQ(messageExt.getPreparedTransactionOffset(), 0); + EXPECT_EQ(messageExt.getQueueId(), 2); + EXPECT_EQ(messageExt.getStoreSize(), 0); + EXPECT_EQ(messageExt.getReconsumeTimes(), 3); + EXPECT_EQ(messageExt.getBodyCRC(), 0); + EXPECT_EQ(messageExt.getMsgId(), "msgId"); + EXPECT_EQ(messageExt.getBornHostString(), "127.0.0.1:10091"); + EXPECT_EQ(messageExt.getStoreHostString(), "127.0.0.2:10092"); - EXPECT_EQ(twoMessageExt.getStoreHostString(), rocketmq::socketAddress2String(storeHost)); + free(bronHost); + free(storeHost); +} +TEST(MessageExtTest, ParseTopicFilterType) { EXPECT_EQ(MQMessageExt::parseTopicFilterType(MessageSysFlag::MultiTagsFlag), TopicFilterType::MULTI_TAG); - EXPECT_EQ(MQMessageExt::parseTopicFilterType(0), TopicFilterType::SINGLE_TAG); } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); - - testing::GTEST_FLAG(filter) = "messageExt.init"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(throw_on_failure) = true; + testing::GTEST_FLAG(filter) = "MessageExtTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/message/MQMessageIdTest.cpp b/test/src/message/MQMessageIdTest.cpp index d83de2f28..2fd77796e 100644 --- a/test/src/message/MQMessageIdTest.cpp +++ b/test/src/message/MQMessageIdTest.cpp @@ -14,43 +14,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include +#include +#include #include "MQMessageId.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" using namespace std; -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::MQMessageId; -TEST(messageId, id) { - int host; - int port; - sockaddr addr = rocketmq::IPPort2socketAddress(inet_addr("127.0.0.1"), 10091); - MQMessageId id(addr, 1024); +TEST(MessageIdTest, MessageId) { + MQMessageId msgId(rocketmq::string2SocketAddress("127.0.0.1:10091"), 1024); + EXPECT_EQ(rocketmq::socketAddress2String(msgId.getAddress()), "127.0.0.1:10091"); + EXPECT_EQ(msgId.getOffset(), 1024); - rocketmq::socketAddress2IPPort(id.getAddress(), host, port); - EXPECT_EQ(host, inet_addr("127.0.0.1")); - EXPECT_EQ(port, 10091); - EXPECT_EQ(id.getOffset(), 1024); + msgId.setAddress(rocketmq::string2SocketAddress("127.0.0.2:10092")); + EXPECT_EQ(rocketmq::socketAddress2String(msgId.getAddress()), "127.0.0.2:10092"); - id.setAddress(rocketmq::IPPort2socketAddress(inet_addr("127.0.0.2"), 10092)); - id.setOffset(2048); - - rocketmq::socketAddress2IPPort(id.getAddress(), host, port); - EXPECT_EQ(host, inet_addr("127.0.0.2")); - EXPECT_EQ(port, 10092); - EXPECT_EQ(id.getOffset(), 2048); + msgId.setOffset(2048); + EXPECT_EQ(msgId.getOffset(), 2048); } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); - - testing::GTEST_FLAG(filter) = "messageId.id"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(throw_on_failure) = true; + testing::GTEST_FLAG(filter) = "MessageIdTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/message/MQMessageQueueTest.cpp b/test/src/message/MQMessageQueueTest.cpp index c1c542dd7..54b8f9180 100644 --- a/test/src/message/MQMessageQueueTest.cpp +++ b/test/src/message/MQMessageQueueTest.cpp @@ -14,18 +14,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include +#include #include "MQMessageQueue.h" -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::MQMessageQueue; -TEST(messageQueue, init) { +TEST(MessageQueueTest, Init) { MQMessageQueue messageQueue; EXPECT_EQ(messageQueue.getBrokerName(), ""); EXPECT_EQ(messageQueue.getTopic(), ""); @@ -37,25 +37,25 @@ TEST(messageQueue, init) { EXPECT_EQ(twoMessageQueue.getQueueId(), 1); MQMessageQueue threeMessageQueue("threeTestTopic", "threeTestBroker", 2); - MQMessageQueue frouMessageQueue(threeMessageQueue); - EXPECT_EQ(frouMessageQueue.getBrokerName(), "threeTestBroker"); - EXPECT_EQ(frouMessageQueue.getTopic(), "threeTestTopic"); - EXPECT_EQ(frouMessageQueue.getQueueId(), 2); - - frouMessageQueue = twoMessageQueue; - EXPECT_EQ(frouMessageQueue.getBrokerName(), "testBroker"); - EXPECT_EQ(frouMessageQueue.getTopic(), "testTopic"); - EXPECT_EQ(frouMessageQueue.getQueueId(), 1); - - frouMessageQueue.setBrokerName("frouTestBroker"); - frouMessageQueue.setTopic("frouTestTopic"); - frouMessageQueue.setQueueId(4); - EXPECT_EQ(frouMessageQueue.getBrokerName(), "frouTestBroker"); - EXPECT_EQ(frouMessageQueue.getTopic(), "frouTestTopic"); - EXPECT_EQ(frouMessageQueue.getQueueId(), 4); + MQMessageQueue fourMessageQueue(threeMessageQueue); + EXPECT_EQ(fourMessageQueue.getBrokerName(), "threeTestBroker"); + EXPECT_EQ(fourMessageQueue.getTopic(), "threeTestTopic"); + EXPECT_EQ(fourMessageQueue.getQueueId(), 2); + + fourMessageQueue = twoMessageQueue; + EXPECT_EQ(fourMessageQueue.getBrokerName(), "testBroker"); + EXPECT_EQ(fourMessageQueue.getTopic(), "testTopic"); + EXPECT_EQ(fourMessageQueue.getQueueId(), 1); + + fourMessageQueue.setBrokerName("fourTestBroker"); + fourMessageQueue.setTopic("fourTestTopic"); + fourMessageQueue.setQueueId(4); + EXPECT_EQ(fourMessageQueue.getBrokerName(), "fourTestBroker"); + EXPECT_EQ(fourMessageQueue.getTopic(), "fourTestTopic"); + EXPECT_EQ(fourMessageQueue.getQueueId(), 4); } -TEST(messageQueue, operators) { +TEST(MessageQueueTest, Operators) { MQMessageQueue messageQueue; EXPECT_EQ(messageQueue, messageQueue); EXPECT_EQ(messageQueue.compareTo(messageQueue), 0); @@ -66,11 +66,17 @@ TEST(messageQueue, operators) { twoMessageQueue.setTopic("testTopic"); EXPECT_FALSE(messageQueue == twoMessageQueue); - EXPECT_FALSE(messageQueue.compareTo(twoMessageQueue) == 0); + EXPECT_NE(messageQueue.compareTo(twoMessageQueue), 0); + + twoMessageQueue = messageQueue; + EXPECT_TRUE(messageQueue == twoMessageQueue); twoMessageQueue.setQueueId(1); EXPECT_FALSE(messageQueue == twoMessageQueue); - EXPECT_FALSE(messageQueue.compareTo(twoMessageQueue) == 0); + EXPECT_NE(messageQueue.compareTo(twoMessageQueue), 0); + + twoMessageQueue = messageQueue; + EXPECT_TRUE(messageQueue == twoMessageQueue); twoMessageQueue.setBrokerName("testBroker"); EXPECT_FALSE(messageQueue == twoMessageQueue); @@ -79,8 +85,8 @@ TEST(messageQueue, operators) { int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); - - testing::GTEST_FLAG(filter) = "messageQueue.*"; + testing::GTEST_FLAG(throw_on_failure) = true; + testing::GTEST_FLAG(filter) = "MessageQueueTest.*"; int itestts = RUN_ALL_TESTS(); return itestts; } diff --git a/test/src/message/MQMessageTest.cpp b/test/src/message/MQMessageTest.cpp index 6c0165ac4..bea6ae268 100644 --- a/test/src/message/MQMessageTest.cpp +++ b/test/src/message/MQMessageTest.cpp @@ -14,24 +14,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include +#include +#include #include #include #include "MQMessage.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" -using namespace std; - -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::MQMessage; +using rocketmq::MQMessageConst; -TEST(message, Init) { +TEST(MessageTest, Init) { MQMessage messageOne; EXPECT_EQ(messageOne.getTopic(), ""); EXPECT_EQ(messageOne.getBody(), ""); @@ -72,81 +70,68 @@ TEST(message, Init) { EXPECT_EQ(messageSix.getFlag(), 1); } -TEST(message, info) { +TEST(MessageTest, GetterAndSetter) { MQMessage message; - EXPECT_EQ(message.getTopic(), ""); + EXPECT_EQ(message.getTopic(), ""); // default message.setTopic("testTopic"); EXPECT_EQ(message.getTopic(), "testTopic"); - char* topic = "testTopic"; + + const char* topic = "testTopic"; message.setTopic(topic, 5); EXPECT_EQ(message.getTopic(), "testT"); - EXPECT_EQ(message.getBody(), ""); + EXPECT_EQ(message.getBody(), ""); // default message.setBody("testBody"); EXPECT_EQ(message.getBody(), "testBody"); - char* body = "testBody"; + const char* body = "testBody"; message.setBody(body, 5); EXPECT_EQ(message.getBody(), "testB"); - string tags(message.getTags()); - EXPECT_EQ(tags, ""); - EXPECT_EQ(message.getFlag(), 0); + EXPECT_EQ(message.getTags(), ""); // default + message.setTags("testTags"); + EXPECT_EQ(message.getTags(), "testTags"); + + EXPECT_EQ(message.getKeys(), ""); // default + message.setKeys("testKeys"); + EXPECT_EQ(message.getKeys(), "testKeys"); + + EXPECT_EQ(message.getFlag(), 0); // default message.setFlag(2); EXPECT_EQ(message.getFlag(), 2); - EXPECT_EQ(message.isWaitStoreMsgOK(), true); + EXPECT_EQ(message.isWaitStoreMsgOK(), true); // default message.setWaitStoreMsgOK(false); EXPECT_EQ(message.isWaitStoreMsgOK(), false); message.setWaitStoreMsgOK(true); EXPECT_EQ(message.isWaitStoreMsgOK(), true); - string keys(message.getTags()); - EXPECT_EQ(keys, ""); - message.setKeys("testKeys"); - EXPECT_EQ(message.getKeys(), "testKeys"); - - EXPECT_EQ(message.getDelayTimeLevel(), 0); + EXPECT_EQ(message.getDelayTimeLevel(), 0); // default message.setDelayTimeLevel(1); EXPECT_EQ(message.getDelayTimeLevel(), 1); - - message.setSysFlag(1); - EXPECT_EQ(message.getSysFlag(), 1); } -TEST(message, properties) { +TEST(MessageTest, Properties) { MQMessage message; - EXPECT_EQ(message.getProperties().size(), 1); - EXPECT_STREQ(message.getProperty(MQMessage::PROPERTY_TRANSACTION_PREPARED).c_str(), ""); - message.setProperty(MQMessage::PROPERTY_TRANSACTION_PREPARED, "true"); - EXPECT_EQ(message.getProperties().size(), 2); - EXPECT_EQ(message.getSysFlag(), 4); - EXPECT_EQ(message.getProperty(MQMessage::PROPERTY_TRANSACTION_PREPARED), "true"); + EXPECT_EQ(message.getProperties().size(), 1); + EXPECT_EQ(message.getProperty(MQMessageConst::PROPERTY_TRANSACTION_PREPARED), ""); - message.setProperty(MQMessage::PROPERTY_TRANSACTION_PREPARED, "false"); + message.putProperty(MQMessageConst::PROPERTY_TRANSACTION_PREPARED, "true"); EXPECT_EQ(message.getProperties().size(), 2); - EXPECT_EQ(message.getSysFlag(), 0); - EXPECT_EQ(message.getProperty(MQMessage::PROPERTY_TRANSACTION_PREPARED), "false"); - - map newProperties; + EXPECT_EQ(message.getProperty(MQMessageConst::PROPERTY_TRANSACTION_PREPARED), "true"); - newProperties[MQMessage::PROPERTY_TRANSACTION_PREPARED] = "true"; + std::map newProperties; + newProperties[MQMessageConst::PROPERTY_TRANSACTION_PREPARED] = "false"; message.setProperties(newProperties); - EXPECT_EQ(message.getSysFlag(), 4); - EXPECT_EQ(message.getProperty(MQMessage::PROPERTY_TRANSACTION_PREPARED), "true"); - - newProperties[MQMessage::PROPERTY_TRANSACTION_PREPARED] = "false"; - message.setProperties(newProperties); - EXPECT_EQ(message.getSysFlag(), 0); - EXPECT_EQ(message.getProperty(MQMessage::PROPERTY_TRANSACTION_PREPARED), "false"); + EXPECT_EQ(message.getProperties().size(), 1); + EXPECT_EQ(message.getProperty(MQMessageConst::PROPERTY_TRANSACTION_PREPARED), "false"); } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); - - testing::GTEST_FLAG(filter) = "message.info"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(throw_on_failure) = true; + testing::GTEST_FLAG(filter) = "MessageTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/message/MessageBatchTest.cpp b/test/src/message/MessageBatchTest.cpp new file mode 100644 index 000000000..f7ba0f3e6 --- /dev/null +++ b/test/src/message/MessageBatchTest.cpp @@ -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 +#include + +#include + +#include "MQDecoder.h" +#include "MQMessage.h" +#include "MessageBatch.h" + +using testing::InitGoogleMock; +using testing::InitGoogleTest; +using testing::Return; + +using rocketmq::MessageBatch; +using rocketmq::MQDecoder; +using rocketmq::MQMessage; + +TEST(MessageBatchTest, Encode) { + std::vector msgs; + msgs.push_back(new MQMessage("topic", "*", "test1")); + std::unique_ptr msgBatch(MessageBatch::generateFromList(msgs)); + auto encodeMessage = msgBatch->encode(); + auto encodeMessage2 = MQDecoder::encodeMessages(msgs); + EXPECT_EQ(encodeMessage, encodeMessage2); + // 20 + bodyLen(test1) + 2 + propertiesLength(TAGS:*;WAIT:true;); + EXPECT_EQ(encodeMessage.size(), 44); + + msgs.push_back(new MQMessage("topic", "*", "test2")); + msgs.push_back(new MQMessage("topic", "*", "test3")); + msgBatch.reset(MessageBatch::generateFromList(msgs)); + encodeMessage = msgBatch->encode(); + encodeMessage2 = MQDecoder::encodeMessages(msgs); + EXPECT_EQ(encodeMessage, encodeMessage2); + EXPECT_EQ(encodeMessage.size(), 132); // 44 * 3 + + for (auto* msg : msgs) { + delete msg; + } +} + +int main(int argc, char* argv[]) { + InitGoogleMock(&argc, argv); + testing::GTEST_FLAG(throw_on_failure) = true; + testing::GTEST_FLAG(filter) = "MessageBatchTest.*"; + return RUN_ALL_TESTS(); +} diff --git a/test/src/StringIdMakerTest.cpp b/test/src/message/MessageClientIDSetterTest.cpp similarity index 63% rename from test/src/StringIdMakerTest.cpp rename to test/src/message/MessageClientIDSetterTest.cpp index ebe5897f2..80f528eb5 100644 --- a/test/src/StringIdMakerTest.cpp +++ b/test/src/message/MessageClientIDSetterTest.cpp @@ -14,27 +14,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include +#include +#include -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include -#include "StringIdMaker.h" +#include "MessageClientIDSetter.h" -using namespace std; -using namespace rocketmq; -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; -TEST(StringIdMakerTest, get_unique_id) { - string unique_id = StringIdMaker::getInstance().createUniqID(); - cout << "unique_id: " << unique_id << endl; - EXPECT_EQ(unique_id.size(), 32); +using rocketmq::MessageClientIDSetter; + +TEST(MessageClientIDSetterTest, CreateUniqID) { + auto uniqueId = MessageClientIDSetter::createUniqID(); + std::cout << "uniqueId: " << uniqueId << std::endl; + EXPECT_EQ(uniqueId.size(), 32); + EXPECT_EQ(uniqueId.substr(28), "0000"); // seq } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); + testing::GTEST_FLAG(throw_on_failure) = true; + testing::GTEST_FLAG(filter) = "MessageClientIDSetterTest.*"; return RUN_ALL_TESTS(); } diff --git a/test/src/protocol/CommandHeaderTest.cpp b/test/src/protocol/CommandHeaderTest.cpp index ee19e0e21..37ed24167 100644 --- a/test/src/protocol/CommandHeaderTest.cpp +++ b/test/src/protocol/CommandHeaderTest.cpp @@ -14,33 +14,30 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include +#include +#include +#include +#include +#include #include #include -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "json/value.h" -#include "json/writer.h" - -#include "CommandHeader.h" +#include "DataBlock.h" #include "MQClientException.h" #include "MessageSysFlag.h" #include "UtilAll.h" -#include "dataBlock.h" -#include "json/json.h" +#include "protocol/header/CommandHeader.h" -using std::shared_ptr; - -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using Json::FastWriter; using Json::Value; -using rocketmq::CommandHeader; +using rocketmq::CommandCustomHeader; using rocketmq::ConsumerSendMsgBackRequestHeader; using rocketmq::CreateTopicRequestHeader; using rocketmq::GetConsumerListByGroupRequestHeader; @@ -55,6 +52,7 @@ using rocketmq::GetMinOffsetRequestHeader; using rocketmq::GetMinOffsetResponseHeader; using rocketmq::GetRouteInfoRequestHeader; using rocketmq::MemoryBlock; +using rocketmq::MemoryView; using rocketmq::NotifyConsumerIdsChangedRequestHeader; using rocketmq::PullMessageRequestHeader; using rocketmq::PullMessageResponseHeader; @@ -69,29 +67,25 @@ using rocketmq::UnregisterClientRequestHeader; using rocketmq::UpdateConsumerOffsetRequestHeader; using rocketmq::ViewMessageRequestHeader; -TEST(commandHeader, ConsumerSendMsgBackRequestHeader) {} +TEST(CommandHeaderTest, ConsumerSendMsgBackRequestHeader) {} -TEST(commandHeader, GetConsumerListByGroupResponseBody) { +TEST(CommandHeaderTest, GetConsumerListByGroupResponseBody) { Value value; - value[0] = "body"; - value[1] = 1; + value[0] = "consumer1"; + value[1] = "consumer2"; Value root; root["consumerIdList"] = value; FastWriter writer; - string data = writer.write(root); - - MemoryBlock* mem = new MemoryBlock(data.c_str(), data.size()); - vector cids; - GetConsumerListByGroupResponseBody::Decode(mem, cids); + std::string data = writer.write(root); - EXPECT_EQ(cids.size(), 1); - - delete mem; + std::unique_ptr mem(new MemoryBlock(const_cast(data.data()), data.size())); + std::unique_ptr body(GetConsumerListByGroupResponseBody::Decode(*mem)); + EXPECT_EQ(body->consumerIdList.size(), 2); } -TEST(commandHeader, ResetOffsetRequestHeader) { +TEST(CommandHeaderTest, ResetOffsetRequestHeader) { ResetOffsetRequestHeader header; header.setTopic("testTopic"); @@ -106,89 +100,54 @@ TEST(commandHeader, ResetOffsetRequestHeader) { header.setForceFlag(true); EXPECT_TRUE(header.getForceFlag()); - Value value; - value["isForce"] = "false"; - shared_ptr headersh( - static_cast(ResetOffsetRequestHeader::Decode(value))); - EXPECT_EQ(headersh->getTopic(), ""); - EXPECT_EQ(headersh->getGroup(), ""); - // EXPECT_EQ(headersh->getTimeStamp(), 0); - EXPECT_FALSE(headersh->getForceFlag()); - value["topic"] = "testTopic"; - headersh.reset(static_cast(ResetOffsetRequestHeader::Decode(value))); - EXPECT_EQ(headersh->getTopic(), "testTopic"); - EXPECT_EQ(headersh->getGroup(), ""); - // EXPECT_EQ(headersh->getTimeStamp(), 0); - EXPECT_FALSE(headersh->getForceFlag()); - - value["topic"] = "testTopic"; - value["group"] = "testGroup"; - headersh.reset(static_cast(ResetOffsetRequestHeader::Decode(value))); - EXPECT_EQ(headersh->getTopic(), "testTopic"); - EXPECT_EQ(headersh->getGroup(), "testGroup"); - // EXPECT_EQ(headersh->getTimeStamp(), 0); - EXPECT_FALSE(headersh->getForceFlag()); - - value["topic"] = "testTopic"; - value["group"] = "testGroup"; - value["timestamp"] = "123"; - headersh.reset(static_cast(ResetOffsetRequestHeader::Decode(value))); - EXPECT_EQ(headersh->getTopic(), "testTopic"); - EXPECT_EQ(headersh->getGroup(), "testGroup"); - EXPECT_EQ(headersh->getTimeStamp(), 123); - EXPECT_FALSE(headersh->getForceFlag()); - - value["topic"] = "testTopic"; - value["group"] = "testGroup"; - value["timestamp"] = "123"; - value["isForce"] = "1"; - headersh.reset(static_cast(ResetOffsetRequestHeader::Decode(value))); - EXPECT_EQ(headersh->getTopic(), "testTopic"); - EXPECT_EQ(headersh->getGroup(), "testGroup"); - EXPECT_EQ(headersh->getTimeStamp(), 123); - EXPECT_TRUE(headersh->getForceFlag()); + std::map resetOffsetFields; + resetOffsetFields["topic"] = "testTopic"; + resetOffsetFields["group"] = "testGroup"; + resetOffsetFields["timestamp"] = "123"; + resetOffsetFields["isForce"] = "true"; + std::unique_ptr resetOffsetHeader(ResetOffsetRequestHeader::Decode(resetOffsetFields)); + EXPECT_EQ(resetOffsetHeader->getTopic(), "testTopic"); + EXPECT_EQ(resetOffsetHeader->getGroup(), "testGroup"); + EXPECT_EQ(resetOffsetHeader->getTimeStamp(), 123); + EXPECT_TRUE(resetOffsetHeader->getForceFlag()); } -TEST(commandHeader, GetConsumerRunningInfoRequestHeader) { +TEST(CommandHeaderTest, GetConsumerRunningInfoRequestHeader) { GetConsumerRunningInfoRequestHeader header; header.setClientId("testClientId"); header.setConsumerGroup("testConsumer"); header.setJstackEnable(true); - map requestMap; + std::map requestMap; header.SetDeclaredFieldOfCommandHeader(requestMap); EXPECT_EQ(requestMap["clientId"], "testClientId"); EXPECT_EQ(requestMap["consumerGroup"], "testConsumer"); - EXPECT_EQ(requestMap["jstackEnable"], "1"); + EXPECT_EQ(requestMap["jstackEnable"], "true"); Value outData; header.Encode(outData); EXPECT_EQ(outData["clientId"], "testClientId"); EXPECT_EQ(outData["consumerGroup"], "testConsumer"); - EXPECT_TRUE(outData["jstackEnable"].asBool()); + EXPECT_EQ(outData["jstackEnable"], "true"); - shared_ptr decodeHeader( - static_cast(GetConsumerRunningInfoRequestHeader::Decode(outData))); + std::unique_ptr decodeHeader( + GetConsumerRunningInfoRequestHeader::Decode(requestMap)); EXPECT_EQ(decodeHeader->getClientId(), "testClientId"); EXPECT_EQ(decodeHeader->getConsumerGroup(), "testConsumer"); EXPECT_TRUE(decodeHeader->isJstackEnable()); } -TEST(commandHeader, NotifyConsumerIdsChangedRequestHeader) { - Json::Value ext; - shared_ptr header( - static_cast(NotifyConsumerIdsChangedRequestHeader::Decode(ext))); - EXPECT_EQ(header->getGroup(), ""); - - ext["consumerGroup"] = "testGroup"; - header.reset(static_cast(NotifyConsumerIdsChangedRequestHeader::Decode(ext))); - EXPECT_EQ(header->getGroup(), "testGroup"); +TEST(CommandHeaderTest, NotifyConsumerIdsChangedRequestHeader) { + std::map extFields; + extFields["consumerGroup"] = "testGroup"; + std::unique_ptr header( + NotifyConsumerIdsChangedRequestHeader::Decode(extFields)); + EXPECT_EQ(header->getConsumerGroup(), "testGroup"); } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "commandHeader.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "CommandHeaderTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/protocol/ConsumerRunningInfoTest.cpp b/test/src/protocol/ConsumerRunningInfoTest.cpp index fbea4b289..7c427fd26 100644 --- a/test/src/protocol/ConsumerRunningInfoTest.cpp +++ b/test/src/protocol/ConsumerRunningInfoTest.cpp @@ -14,15 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include "map" -#include "string" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include +#include +#include +#include -#include "json/reader.h" -#include "json/value.h" +#include +#include +#include #include "ConsumerRunningInfo.h" #include "MessageQueue.h" @@ -32,19 +31,19 @@ using std::map; using std::string; -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using Json::Reader; using Json::Value; using rocketmq::ConsumerRunningInfo; -using rocketmq::MessageQueue; +using rocketmq::MQMessageQueue; using rocketmq::ProcessQueueInfo; using rocketmq::SubscriptionData; -TEST(consumerRunningInfo, init) { +TEST(ConsumerRunningInfoTest, Init) { ConsumerRunningInfo consumerRunningInfo; consumerRunningInfo.setJstack("jstack"); EXPECT_EQ(consumerRunningInfo.getJstack(), "jstack"); @@ -60,7 +59,7 @@ TEST(consumerRunningInfo, init) { EXPECT_TRUE(consumerRunningInfo.getSubscriptionSet().empty()); - vector subscriptionSet; + std::vector subscriptionSet; subscriptionSet.push_back(SubscriptionData()); consumerRunningInfo.setSubscriptionSet(subscriptionSet); @@ -68,11 +67,11 @@ TEST(consumerRunningInfo, init) { EXPECT_TRUE(consumerRunningInfo.getMqTable().empty()); - MessageQueue messageQueue("testTopic", "testBroker", 3); + MQMessageQueue messageQueue("testTopic", "testBroker", 3); ProcessQueueInfo processQueueInfo; processQueueInfo.commitOffset = 1024; consumerRunningInfo.setMqTable(messageQueue, processQueueInfo); - map mqTable = consumerRunningInfo.getMqTable(); + std::map mqTable = consumerRunningInfo.getMqTable(); EXPECT_EQ(mqTable[messageQueue].commitOffset, processQueueInfo.commitOffset); // encode start @@ -82,6 +81,7 @@ TEST(consumerRunningInfo, init) { consumerRunningInfo.setProperty(ConsumerRunningInfo::PROP_CONSUME_TYPE, "consume_type"); consumerRunningInfo.setProperty(ConsumerRunningInfo::PROP_CLIENT_VERSION, "client_version"); consumerRunningInfo.setProperty(ConsumerRunningInfo::PROP_CONSUMER_START_TIMESTAMP, "127"); + // TODO /* string outstr = consumerRunningInfo.encode(); std::cout<< outstr; @@ -118,7 +118,6 @@ TEST(consumerRunningInfo, init) { int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "consumerRunningInfo.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "ConsumerRunningInfoTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/protocol/HeartbeatDataTest.cpp b/test/src/protocol/HeartbeatDataTest.cpp index c153ed58a..a1e5393a9 100644 --- a/test/src/protocol/HeartbeatDataTest.cpp +++ b/test/src/protocol/HeartbeatDataTest.cpp @@ -14,11 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include +#include -#include "vector" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include #include "ConsumeType.h" #include "HeartbeatData.h" @@ -26,8 +25,8 @@ using std::vector; -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::ConsumeFromWhere; @@ -38,7 +37,7 @@ using rocketmq::MessageModel; using rocketmq::ProducerData; using rocketmq::SubscriptionData; -TEST(heartbeatData, ProducerData) { +TEST(HeartbeatDataTest, ProducerData) { ProducerData producerData; producerData.groupName = "testGroup"; @@ -46,7 +45,7 @@ TEST(heartbeatData, ProducerData) { EXPECT_EQ(outJson["groupName"], "testGroup"); } -TEST(heartbeatData, ConsumerData) { +TEST(HeartbeatDataTest, ConsumerData) { ConsumerData consumerData; consumerData.groupName = "testGroup"; consumerData.consumeType = ConsumeType::CONSUME_ACTIVELY; @@ -71,7 +70,7 @@ TEST(heartbeatData, ConsumerData) { EXPECT_EQ(subsValue[0]["subString"], "sub"); } -TEST(heartbeatData, HeartbeatData) { +TEST(HeartbeatDataTest, HeartbeatData) { HeartbeatData heartbeatData; heartbeatData.setClientID("testClientId"); @@ -96,8 +95,7 @@ TEST(heartbeatData, HeartbeatData) { heartbeatData.insertDataToConsumerDataSet(consumerData); EXPECT_FALSE(heartbeatData.isConsumerDataSetEmpty()); - string outData; - heartbeatData.Encode(outData); + std::string outData = heartbeatData.encode(); Json::Value root; Json::Reader reader; @@ -109,7 +107,6 @@ TEST(heartbeatData, HeartbeatData) { int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "heartbeatData.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "HeartbeatDataTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/protocol/KVTableTest.cpp b/test/src/protocol/KVTableTest.cpp index b6fd50493..2b71a1422 100644 --- a/test/src/protocol/KVTableTest.cpp +++ b/test/src/protocol/KVTableTest.cpp @@ -14,38 +14,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include +#include + #include #include -#include "gmock/gmock.h" -#include "gtest/gtest.h" - #include "KVTable.h" -using std::map; -using std::string; - -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::KVTable; -TEST(KVTable, init) { +TEST(KVTableTest, Init) { KVTable table; EXPECT_EQ(table.getTable().size(), 0); - map maps; - maps["string"] = "string"; - table.setTable(maps); + std::map kvs; + kvs["string"] = "string"; + table.setTable(kvs); EXPECT_EQ(table.getTable().size(), 1); } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "KVTable.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "KVTableTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/protocol/LockBatchBodyTest.cpp b/test/src/protocol/LockBatchBodyTest.cpp index 9f8f3009f..567f27cee 100644 --- a/test/src/protocol/LockBatchBodyTest.cpp +++ b/test/src/protocol/LockBatchBodyTest.cpp @@ -14,20 +14,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include +#include -#include "vector" +#include -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "LockBatchBody.h" +#include "DataBlock.h" #include "MQMessageQueue.h" -#include "dataBlock.h" - -using std::vector; +#include "protocol/body/LockBatchBody.h" -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::LockBatchRequestBody; @@ -36,7 +33,7 @@ using rocketmq::MemoryBlock; using rocketmq::MQMessageQueue; using rocketmq::UnlockBatchRequestBody; -TEST(lockBatchBody, LockBatchRequestBody) { +TEST(LockBatchBodyTest, LockBatchRequestBody) { LockBatchRequestBody lockBatchRequestBody; lockBatchRequestBody.setClientId("testClientId"); @@ -45,31 +42,28 @@ TEST(lockBatchBody, LockBatchRequestBody) { lockBatchRequestBody.setConsumerGroup("testGroup"); EXPECT_EQ(lockBatchRequestBody.getConsumerGroup(), "testGroup"); - vector vectorMessageQueue; - vectorMessageQueue.push_back(MQMessageQueue()); - vectorMessageQueue.push_back(MQMessageQueue()); - - lockBatchRequestBody.setMqSet(vectorMessageQueue); - EXPECT_EQ(lockBatchRequestBody.getMqSet(), vectorMessageQueue); + std::vector messageQueueList; + messageQueueList.push_back(MQMessageQueue("testTopic", "testBroker", 1)); + messageQueueList.push_back(MQMessageQueue("testTopic", "testBroker", 2)); - Json::Value outJson = lockBatchRequestBody.toJson(MQMessageQueue("topicTest", "testBroker", 10)); - EXPECT_EQ(outJson["topic"], "topicTest"); - EXPECT_EQ(outJson["brokerName"], "testBroker"); - EXPECT_EQ(outJson["queueId"], 10); + lockBatchRequestBody.setMqSet(messageQueueList); + EXPECT_EQ(lockBatchRequestBody.getMqSet(), messageQueueList); - string outData; - lockBatchRequestBody.Encode(outData); + std::string outData = lockBatchRequestBody.encode(); Json::Value root; Json::Reader reader; reader.parse(outData, root); EXPECT_EQ(root["clientId"], "testClientId"); EXPECT_EQ(root["consumerGroup"], "testGroup"); + EXPECT_EQ(root["mqSet"][1]["topic"], "testTopic"); + EXPECT_EQ(root["mqSet"][1]["brokerName"], "testBroker"); + EXPECT_EQ(root["mqSet"][1]["queueId"], 2); } -TEST(lockBatchBody, UnlockBatchRequestBody) {} +TEST(LockBatchBodyTest, UnlockBatchRequestBody) {} -TEST(lockBatchBody, LockBatchResponseBody) { +TEST(LockBatchBodyTest, LockBatchResponseBody) { Json::Value root; Json::Value mqs; @@ -81,23 +75,18 @@ TEST(lockBatchBody, LockBatchResponseBody) { root["lockOKMQSet"] = mqs; Json::FastWriter fastwrite; - string outData = fastwrite.write(root); - - MemoryBlock* mem = new MemoryBlock(outData.c_str(), outData.size()); - - LockBatchResponseBody lockBatchResponseBody; + std::string outData = fastwrite.write(root); - vector messageQueues; - LockBatchResponseBody::Decode(mem, messageQueues); + std::unique_ptr mem(new MemoryBlock(const_cast(outData.data()), outData.size())); + std::unique_ptr lockBatchResponseBody(LockBatchResponseBody::Decode(*mem)); MQMessageQueue messageQueue("testTopic", "testBroker", 1); - EXPECT_EQ(messageQueue, messageQueues[0]); + EXPECT_EQ(messageQueue, lockBatchResponseBody->getLockOKMQSet()[0]); } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "lockBatchBody.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "LockBatchBodyTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/protocol/MessageQueueTest.cpp b/test/src/protocol/MessageQueueTest.cpp index eb943d206..fa6afa48d 100644 --- a/test/src/protocol/MessageQueueTest.cpp +++ b/test/src/protocol/MessageQueueTest.cpp @@ -14,76 +14,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include +#include #include "MessageQueue.h" -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; -using rocketmq::MessageQueue; +using rocketmq::MQMessageQueue; +using rocketmq::toJson; -TEST(messageExt, init) { - MessageQueue messageQueue; - EXPECT_EQ(messageQueue.getQueueId(), -1); - - MessageQueue twoMessageQueue("testTopic", "testBroker", 1); - EXPECT_EQ(twoMessageQueue.getQueueId(), 1); - EXPECT_EQ(twoMessageQueue.getTopic(), "testTopic"); - EXPECT_EQ(twoMessageQueue.getBrokerName(), "testBroker"); - - MessageQueue threeMessageQueue(twoMessageQueue); - EXPECT_EQ(threeMessageQueue.getQueueId(), 1); - EXPECT_EQ(threeMessageQueue.getTopic(), "testTopic"); - EXPECT_EQ(threeMessageQueue.getBrokerName(), "testBroker"); +TEST(MessageQueueTest, Json) { + MQMessageQueue messageQueue("testTopic", "testBroker", 1); + EXPECT_EQ(messageQueue.getQueueId(), 1); + EXPECT_EQ(messageQueue.getTopic(), "testTopic"); + EXPECT_EQ(messageQueue.getBrokerName(), "testBroker"); - Json::Value outJson = twoMessageQueue.toJson(); + Json::Value outJson = toJson(messageQueue); EXPECT_EQ(outJson["queueId"], 1); EXPECT_EQ(outJson["topic"], "testTopic"); EXPECT_EQ(outJson["brokerName"], "testBroker"); - - MessageQueue fiveMessageQueue = threeMessageQueue; - EXPECT_EQ(fiveMessageQueue.getQueueId(), 1); - EXPECT_EQ(fiveMessageQueue.getTopic(), "testTopic"); - EXPECT_EQ(fiveMessageQueue.getBrokerName(), "testBroker"); -} - -TEST(messageExt, info) { - MessageQueue messageQueue; - - messageQueue.setQueueId(11); - EXPECT_EQ(messageQueue.getQueueId(), 11); - - messageQueue.setTopic("testTopic"); - EXPECT_EQ(messageQueue.getTopic(), "testTopic"); - - messageQueue.setBrokerName("testBroker"); - EXPECT_EQ(messageQueue.getBrokerName(), "testBroker"); -} - -TEST(messageExt, operators) { - MessageQueue messageQueue; - EXPECT_TRUE(messageQueue == messageQueue); - - MessageQueue twoMessageQueue; - EXPECT_TRUE(messageQueue == twoMessageQueue); - - twoMessageQueue.setTopic("testTopic"); - EXPECT_FALSE(messageQueue == twoMessageQueue); - - messageQueue.setQueueId(11); - EXPECT_FALSE(messageQueue == twoMessageQueue); - - messageQueue.setBrokerName("testBroker"); - EXPECT_FALSE(messageQueue == twoMessageQueue); } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "messageExt.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "MessageQueueTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/protocol/ProcessQueueInfoTest.cpp b/test/src/protocol/ProcessQueueInfoTest.cpp index bb5e7141e..cfd1a5664 100644 --- a/test/src/protocol/ProcessQueueInfoTest.cpp +++ b/test/src/protocol/ProcessQueueInfoTest.cpp @@ -14,20 +14,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include +#include #include "MQMessageExt.h" #include "ProcessQueueInfo.h" -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::MQMessageExt; using rocketmq::ProcessQueueInfo; -TEST(processQueueInfo, init) { +TEST(ProcessQueueInfoTest, Init) { ProcessQueueInfo processQueueInfo; EXPECT_EQ(processQueueInfo.commitOffset, 0); EXPECT_EQ(processQueueInfo.cachedMsgMinOffset, 0); @@ -38,7 +38,7 @@ TEST(processQueueInfo, init) { EXPECT_EQ(processQueueInfo.transactionMsgCount, 0); EXPECT_EQ(processQueueInfo.locked, false); EXPECT_EQ(processQueueInfo.tryUnlockTimes, 0); - EXPECT_EQ(processQueueInfo.lastLockTimestamp, 123); + EXPECT_EQ(processQueueInfo.lastLockTimestamp, 0); EXPECT_EQ(processQueueInfo.droped, false); EXPECT_EQ(processQueueInfo.lastPullTimestamp, 0); EXPECT_EQ(processQueueInfo.lastConsumeTimestamp, 0); @@ -63,7 +63,7 @@ TEST(processQueueInfo, init) { EXPECT_EQ(outJson["transactionMsgCount"].asInt(), 0); EXPECT_EQ(outJson["locked"].asBool(), true); EXPECT_EQ(outJson["tryUnlockTimes"].asInt(), 0); - EXPECT_EQ(outJson["lastLockTimestamp"], "123"); + EXPECT_EQ(outJson["lastLockTimestamp"], "0"); EXPECT_EQ(outJson["droped"].asBool(), true); EXPECT_EQ(outJson["lastPullTimestamp"], "0"); EXPECT_EQ(outJson["lastConsumeTimestamp"], "0"); @@ -72,7 +72,6 @@ TEST(processQueueInfo, init) { int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "processQueueInfo.init"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "ProcessQueueInfoTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/protocol/RemotingCommandTest.cpp b/test/src/protocol/RemotingCommandTest.cpp index ca28aa3f4..e579e0027 100644 --- a/test/src/protocol/RemotingCommandTest.cpp +++ b/test/src/protocol/RemotingCommandTest.cpp @@ -14,28 +14,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include +#include -#include -#include #include +#include -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "CommandHeader.h" +#include "DataBlock.h" #include "MQProtos.h" #include "MQVersion.h" #include "MemoryOutputStream.h" #include "RemotingCommand.h" -#include "dataBlock.h" - -using std::shared_ptr; +#include "protocol/header/CommandHeader.h" -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; -using rocketmq::CommandHeader; using rocketmq::GetConsumerRunningInfoRequestHeader; using rocketmq::GetEarliestMsgStoretimeResponseHeader; using rocketmq::GetMaxOffsetResponseHeader; @@ -53,7 +48,7 @@ using rocketmq::ResetOffsetRequestHeader; using rocketmq::SearchOffsetResponseHeader; using rocketmq::SendMessageResponseHeader; -TEST(remotingCommand, init) { +TEST(RemotingCommandTest, Init) { RemotingCommand remotingCommand; EXPECT_EQ(remotingCommand.getCode(), 0); @@ -62,12 +57,12 @@ TEST(remotingCommand, init) { EXPECT_EQ(twoRemotingCommand.getOpaque(), 0); EXPECT_EQ(twoRemotingCommand.getRemark(), ""); EXPECT_EQ(twoRemotingCommand.getVersion(), MQVersion::s_CurrentVersion); - // EXPECT_EQ(twoRemotingCommand.getFlag() , 0); - EXPECT_EQ(twoRemotingCommand.getMsgBody(), ""); - EXPECT_TRUE(twoRemotingCommand.getCommandHeader() == nullptr); + EXPECT_EQ(twoRemotingCommand.getFlag(), 0); + EXPECT_TRUE(twoRemotingCommand.getBody() == nullptr); + EXPECT_TRUE(twoRemotingCommand.readCustomHeader() == nullptr); RemotingCommand threeRemotingCommand(13, new GetRouteInfoRequestHeader("topic")); - EXPECT_FALSE(threeRemotingCommand.getCommandHeader() == nullptr); + EXPECT_FALSE(threeRemotingCommand.readCustomHeader() == nullptr); RemotingCommand frouRemotingCommand(13, "CPP", MQVersion::s_CurrentVersion, 12, 3, "remark", new GetRouteInfoRequestHeader("topic")); @@ -76,17 +71,17 @@ TEST(remotingCommand, init) { EXPECT_EQ(frouRemotingCommand.getRemark(), "remark"); EXPECT_EQ(frouRemotingCommand.getVersion(), MQVersion::s_CurrentVersion); EXPECT_EQ(frouRemotingCommand.getFlag(), 3); - EXPECT_EQ(frouRemotingCommand.getMsgBody(), ""); - EXPECT_FALSE(frouRemotingCommand.getCommandHeader() == nullptr); + EXPECT_TRUE(frouRemotingCommand.getBody() == nullptr); + EXPECT_FALSE(frouRemotingCommand.readCustomHeader() == nullptr); - RemotingCommand sixRemotingCommand(frouRemotingCommand); + RemotingCommand sixRemotingCommand(std::move(frouRemotingCommand)); EXPECT_EQ(sixRemotingCommand.getCode(), 13); EXPECT_EQ(sixRemotingCommand.getOpaque(), 12); EXPECT_EQ(sixRemotingCommand.getRemark(), "remark"); EXPECT_EQ(sixRemotingCommand.getVersion(), MQVersion::s_CurrentVersion); EXPECT_EQ(sixRemotingCommand.getFlag(), 3); - EXPECT_EQ(sixRemotingCommand.getMsgBody(), ""); - EXPECT_TRUE(sixRemotingCommand.getCommandHeader() == nullptr); + EXPECT_TRUE(sixRemotingCommand.getBody() == nullptr); + EXPECT_FALSE(sixRemotingCommand.readCustomHeader() == nullptr); RemotingCommand* sevenRemotingCommand = &sixRemotingCommand; EXPECT_EQ(sevenRemotingCommand->getCode(), 13); @@ -94,11 +89,11 @@ TEST(remotingCommand, init) { EXPECT_EQ(sevenRemotingCommand->getRemark(), "remark"); EXPECT_EQ(sevenRemotingCommand->getVersion(), MQVersion::s_CurrentVersion); EXPECT_EQ(sevenRemotingCommand->getFlag(), 3); - EXPECT_EQ(sevenRemotingCommand->getMsgBody(), ""); - EXPECT_TRUE(sevenRemotingCommand->getCommandHeader() == nullptr); + EXPECT_TRUE(sevenRemotingCommand->getBody() == nullptr); + EXPECT_FALSE(sevenRemotingCommand->readCustomHeader() == nullptr); } -TEST(remotingCommand, info) { +TEST(RemotingCommandTest, Info) { RemotingCommand remotingCommand; remotingCommand.setCode(13); @@ -110,13 +105,13 @@ TEST(remotingCommand, info) { remotingCommand.setRemark("123"); EXPECT_EQ(remotingCommand.getRemark(), "123"); - remotingCommand.setMsgBody("msgBody"); - EXPECT_EQ(remotingCommand.getMsgBody(), "msgBody"); + remotingCommand.setBody("msgBody"); + EXPECT_EQ((std::string)*remotingCommand.getBody(), "msgBody"); remotingCommand.addExtField("key", "value"); } -TEST(remotingCommand, flag) { +TEST(RemotingCommandTest, Flag) { RemotingCommand remotingCommand(13, "CPP", MQVersion::s_CurrentVersion, 12, 0, "remark", new GetRouteInfoRequestHeader("topic")); ; @@ -136,25 +131,22 @@ TEST(remotingCommand, flag) { EXPECT_TRUE(remotingCommand.isOnewayRPC()); } -TEST(remotingCommand, encodeAndDecode) { - RemotingCommand remotingCommand(13, "CPP", MQVersion::s_CurrentVersion, 12, 3, "remark", NULL); - remotingCommand.SetBody("123123", 6); - remotingCommand.Encode(); - // no delete - const MemoryBlock* head = remotingCommand.GetHead(); - const MemoryBlock* body = remotingCommand.GetBody(); +TEST(RemotingCommandTest, EncodeAndDecode) { + RemotingCommand remotingCommand(MQRequestCode::QUERY_BROKER_OFFSET, "CPP", MQVersion::s_CurrentVersion, 12, 3, + "remark", nullptr); + remotingCommand.setBody("123123"); - unique_ptr result(new MemoryOutputStream(1024)); - result->write(head->getData() + 4, head->getSize() - 4); - result->write(body->getData(), body->getSize()); + auto package = remotingCommand.encode(); + + std::unique_ptr decodeRemtingCommand( + RemotingCommand::Decode(std::shared_ptr(std::move(package)), true)); - shared_ptr decodeRemtingCommand(RemotingCommand::Decode(result->getMemoryBlock())); EXPECT_EQ(remotingCommand.getCode(), decodeRemtingCommand->getCode()); EXPECT_EQ(remotingCommand.getOpaque(), decodeRemtingCommand->getOpaque()); EXPECT_EQ(remotingCommand.getRemark(), decodeRemtingCommand->getRemark()); EXPECT_EQ(remotingCommand.getVersion(), decodeRemtingCommand->getVersion()); EXPECT_EQ(remotingCommand.getFlag(), decodeRemtingCommand->getFlag()); - EXPECT_TRUE(decodeRemtingCommand->getCommandHeader() == NULL); + EXPECT_TRUE(decodeRemtingCommand->readCustomHeader() == nullptr); // ~RemotingCommand delete GetConsumerRunningInfoRequestHeader* requestHeader = new GetConsumerRunningInfoRequestHeader(); @@ -162,97 +154,35 @@ TEST(remotingCommand, encodeAndDecode) { requestHeader->setConsumerGroup("consumerGroup"); requestHeader->setJstackEnable(false); - RemotingCommand encodeRemotingCommand(307, "CPP", MQVersion::s_CurrentVersion, 12, 3, "remark", requestHeader); - encodeRemotingCommand.SetBody("123123", 6); - encodeRemotingCommand.Encode(); - - // no delete - const MemoryBlock* phead = encodeRemotingCommand.GetHead(); - const MemoryBlock* pbody = encodeRemotingCommand.GetBody(); + RemotingCommand remotingCommand2(MQRequestCode::GET_CONSUMER_RUNNING_INFO, "CPP", MQVersion::s_CurrentVersion, 12, 3, + "remark", requestHeader); + remotingCommand2.setBody("123123"); + package = remotingCommand2.encode(); - unique_ptr results(new MemoryOutputStream(1024)); - results->write(phead->getData() + 4, phead->getSize() - 4); - results->write(pbody->getData(), pbody->getSize()); + decodeRemtingCommand.reset(RemotingCommand::Decode(std::shared_ptr(std::move(package)), true)); - shared_ptr decodeRemtingCommandTwo(RemotingCommand::Decode(results->getMemoryBlock())); - - decodeRemtingCommandTwo->SetExtHeader(encodeRemotingCommand.getCode()); - GetConsumerRunningInfoRequestHeader* header = - reinterpret_cast(decodeRemtingCommandTwo->getCommandHeader()); + auto* header = decodeRemtingCommand->decodeCommandCustomHeader(); EXPECT_EQ(requestHeader->getClientId(), header->getClientId()); EXPECT_EQ(requestHeader->getConsumerGroup(), header->getConsumerGroup()); } -TEST(remotingCommand, SetExtHeader) { - shared_ptr remotingCommand(new RemotingCommand()); - - remotingCommand->SetExtHeader(-1); - EXPECT_TRUE(remotingCommand->getCommandHeader() == NULL); - - Json::Value object; - Json::Value extFields; - extFields["id"] = 1; - object["extFields"] = extFields; - remotingCommand->setParsedJson(object); - - remotingCommand->SetExtHeader(MQRequestCode::SEND_MESSAGE); - SendMessageResponseHeader* sendMessageResponseHeader = - reinterpret_cast(remotingCommand->getCommandHeader()); - EXPECT_EQ(sendMessageResponseHeader->msgId, ""); - - remotingCommand->SetExtHeader(MQRequestCode::PULL_MESSAGE); - PullMessageResponseHeader* pullMessageResponseHeader = - reinterpret_cast(remotingCommand->getCommandHeader()); - EXPECT_EQ(pullMessageResponseHeader->suggestWhichBrokerId, 0); - - remotingCommand->SetExtHeader(MQRequestCode::GET_MIN_OFFSET); - GetMinOffsetResponseHeader* getMinOffsetResponseHeader = - reinterpret_cast(remotingCommand->getCommandHeader()); - EXPECT_EQ(getMinOffsetResponseHeader->offset, 0); - - remotingCommand->SetExtHeader(MQRequestCode::GET_MAX_OFFSET); - GetMaxOffsetResponseHeader* getMaxOffsetResponseHeader = - reinterpret_cast(remotingCommand->getCommandHeader()); - EXPECT_EQ(getMaxOffsetResponseHeader->offset, 0); - - remotingCommand->SetExtHeader(MQRequestCode::SEARCH_OFFSET_BY_TIMESTAMP); - SearchOffsetResponseHeader* searchOffsetResponseHeader = - reinterpret_cast(remotingCommand->getCommandHeader()); - EXPECT_EQ(searchOffsetResponseHeader->offset, 0); - - remotingCommand->SetExtHeader(MQRequestCode::GET_EARLIEST_MSG_STORETIME); - GetEarliestMsgStoretimeResponseHeader* getEarliestMsgStoretimeResponseHeader = - reinterpret_cast(remotingCommand->getCommandHeader()); - EXPECT_EQ(getEarliestMsgStoretimeResponseHeader->timestamp, 0); - - remotingCommand->SetExtHeader(MQRequestCode::QUERY_CONSUMER_OFFSET); - QueryConsumerOffsetResponseHeader* queryConsumerOffsetResponseHeader = - reinterpret_cast(remotingCommand->getCommandHeader()); - EXPECT_EQ(queryConsumerOffsetResponseHeader->offset, 0); - - extFields["isForce"] = "true"; - object["extFields"] = extFields; - remotingCommand->setParsedJson(object); - remotingCommand->SetExtHeader(MQRequestCode::RESET_CONSUMER_CLIENT_OFFSET); - ResetOffsetRequestHeader* resetOffsetRequestHeader = - reinterpret_cast(remotingCommand->getCommandHeader()); - resetOffsetRequestHeader->setGroup("group"); +TEST(RemotingCommandTest, SetExtHeader) { + std::unique_ptr remotingCommand(new RemotingCommand()); - remotingCommand->SetExtHeader(MQRequestCode::GET_CONSUMER_RUNNING_INFO); - GetConsumerRunningInfoRequestHeader* getConsumerRunningInfoRequestHeader = - reinterpret_cast(remotingCommand->getCommandHeader()); - getConsumerRunningInfoRequestHeader->setClientId("id"); + EXPECT_TRUE(remotingCommand->readCustomHeader() == nullptr); - remotingCommand->SetExtHeader(MQRequestCode::NOTIFY_CONSUMER_IDS_CHANGED); - NotifyConsumerIdsChangedRequestHeader* notifyConsumerIdsChangedRequestHeader = - reinterpret_cast(remotingCommand->getCommandHeader()); - notifyConsumerIdsChangedRequestHeader->setGroup("group"); + remotingCommand->addExtField("msgId", "ABCD"); + remotingCommand->addExtField("queueId", "1"); + remotingCommand->addExtField("queueOffset", "1024"); + auto* sendMessageResponseHeader = remotingCommand->decodeCommandCustomHeader(); + EXPECT_EQ(sendMessageResponseHeader->msgId, "ABCD"); + EXPECT_EQ(sendMessageResponseHeader->queueId, 1); + EXPECT_EQ(sendMessageResponseHeader->queueOffset, 1024); } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "remotingCommand.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "RemotingCommandTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/protocol/TopicRouteDataTest.cpp b/test/src/protocol/TopicRouteDataTest.cpp index cf88ac106..b9671ede2 100644 --- a/test/src/protocol/TopicRouteDataTest.cpp +++ b/test/src/protocol/TopicRouteDataTest.cpp @@ -14,14 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include +#include +#include + +#include "DataBlock.h" #include "TopicRouteData.h" -#include "dataBlock.h" -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; using rocketmq::BrokerData; @@ -29,22 +31,21 @@ using rocketmq::MemoryBlock; using rocketmq::QueueData; using rocketmq::TopicRouteData; -TEST(topicRouteData, topicRouteData) { +TEST(TopicRouteDataTest, TopicRouteData) { Json::Value root; root["orderTopicConf"] = "orderTopicConf"; - Json::Value queueDatas; Json::Value queueData; - queueData["brokerName"] = "brokerTest"; queueData["readQueueNums"] = 8; queueData["writeQueueNums"] = 8; queueData["perm"] = 7; + + Json::Value queueDatas; queueDatas[0] = queueData; root["queueDatas"] = queueDatas; - Json::Value brokerDatas; Json::Value brokerData; brokerData["brokerName"] = "testBroker"; @@ -53,13 +54,16 @@ TEST(topicRouteData, topicRouteData) { brokerAddrs["1"] = "127.0.0.2:10092"; brokerData["brokerAddrs"] = brokerAddrs; + Json::Value brokerDatas; brokerDatas[0] = brokerData; root["brokerDatas"] = brokerDatas; - string out = root.toStyledString(); - MemoryBlock* block = new MemoryBlock(out.c_str(), out.size()); - TopicRouteData* topicRouteData = TopicRouteData::Decode(block); + std::string out = root.toStyledString(); + + std::unique_ptr block(new MemoryBlock(const_cast(out.data()), out.size())); + std::unique_ptr topicRouteData(TopicRouteData::Decode(*block)); + EXPECT_EQ(root["orderTopicConf"], topicRouteData->getOrderTopicConf()); BrokerData broker; @@ -67,7 +71,7 @@ TEST(topicRouteData, topicRouteData) { broker.brokerAddrs[0] = "127.0.0.1:10091"; broker.brokerAddrs[1] = "127.0.0.2:10092"; - vector brokerDataSt = topicRouteData->getBrokerDatas(); + std::vector brokerDataSt = topicRouteData->getBrokerDatas(); EXPECT_EQ(broker, brokerDataSt[0]); QueueData queue; @@ -75,19 +79,15 @@ TEST(topicRouteData, topicRouteData) { queue.readQueueNums = 8; queue.writeQueueNums = 8; queue.perm = 7; - vector queueDataSt = topicRouteData->getQueueDatas(); + std::vector queueDataSt = topicRouteData->getQueueDatas(); EXPECT_EQ(queue, queueDataSt[0]); EXPECT_EQ(topicRouteData->selectBrokerAddr(), "127.0.0.1:10091"); - - delete block; - delete topicRouteData; } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "topicRouteData.topicRouteData"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "TopicRouteDataTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/transport/ClientRemotingProcessorTest.cpp b/test/src/transport/ClientRemotingProcessorTest.cpp index 5c906ebde..d57fd320a 100644 --- a/test/src/transport/ClientRemotingProcessorTest.cpp +++ b/test/src/transport/ClientRemotingProcessorTest.cpp @@ -14,34 +14,32 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include +#include +#include +#include +#include #include -#include "map" -#include "string.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "json/value.h" -#include "json/writer.h" #include "ClientRPCHook.h" #include "ClientRemotingProcessor.h" #include "ConsumerRunningInfo.h" -#include "MQClientFactory.h" +#include "DataBlock.h" +#include "MQClientConfigImpl.h" +#include "MQClientInstance.h" #include "MQMessageQueue.h" #include "MQProtos.h" #include "RemotingCommand.h" #include "SessionCredentials.h" +#include "TcpTransport.h" #include "UtilAll.h" -#include "dataBlock.h" - -using std::map; -using std::string; +#include "protocol/body/ResetOffsetBody.h" +#include "protocol/header/CommandHeader.h" -using ::testing::_; -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::_; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Mock; using testing::Return; using testing::SetArgReferee; @@ -54,7 +52,9 @@ using rocketmq::ClientRPCHook; using rocketmq::ConsumerRunningInfo; using rocketmq::GetConsumerRunningInfoRequestHeader; using rocketmq::MemoryBlock; -using rocketmq::MQClientFactory; +using rocketmq::MQClientConfig; +using rocketmq::MQClientConfigImpl; +using rocketmq::MQClientInstance; using rocketmq::MQMessageQueue; using rocketmq::MQRequestCode; using rocketmq::MQResponseCode; @@ -63,175 +63,177 @@ using rocketmq::RemotingCommand; using rocketmq::ResetOffsetBody; using rocketmq::ResetOffsetRequestHeader; using rocketmq::SessionCredentials; +using rocketmq::TcpTransport; using rocketmq::UtilAll; class MockClientRemotingProcessor : public ClientRemotingProcessor { public: - MockClientRemotingProcessor(MQClientFactory* factrory) : ClientRemotingProcessor(factrory) {} - MOCK_METHOD1(resetOffset, RemotingCommand*(RemotingCommand* request)); - MOCK_METHOD1(getConsumerRunningInfo, RemotingCommand*(RemotingCommand* request)); - MOCK_METHOD1(notifyConsumerIdsChanged, RemotingCommand*(RemotingCommand* request)); + MockClientRemotingProcessor(MQClientInstance* instance) : ClientRemotingProcessor(instance) {} + + MOCK_METHOD(RemotingCommand*, resetOffset, (RemotingCommand*), ()); + MOCK_METHOD(RemotingCommand*, getConsumerRunningInfo, (RemotingCommand*), ()); + MOCK_METHOD(RemotingCommand*, notifyConsumerIdsChanged, (RemotingCommand*), ()); }; -class MockMQClientFactory : public MQClientFactory { +class MockMQClientInstance : public MQClientInstance { public: - MockMQClientFactory(const string& clientID, - int pullThreadNum, - uint64_t tcpConnectTimeout, - uint64_t tcpTransportTryLockTimeout, - string unitName) - : MQClientFactory(clientID, pullThreadNum, tcpConnectTimeout, tcpTransportTryLockTimeout, unitName) {} - - MOCK_METHOD3(resetOffset, - void(const string& group, const string& topic, const map& offsetTable)); - MOCK_METHOD1(consumerRunningInfo, ConsumerRunningInfo*(const string& consumerGroup)); - MOCK_METHOD2(getSessionCredentialFromConsumer, - bool(const string& consumerGroup, SessionCredentials& sessionCredentials)); - MOCK_METHOD1(doRebalanceByConsumerGroup, void(const string& consumerGroup)); + MockMQClientInstance(const MQClientConfig& clientConfig, const std::string& clientId) + : MQClientInstance(clientConfig, clientId) {} + + MOCK_METHOD(void, + resetOffset, + (const std::string&, const std::string&, (const std::map&)), + ()); + MOCK_METHOD(ConsumerRunningInfo*, consumerRunningInfo, (const std::string&), ()); + MOCK_METHOD(void, doRebalanceByConsumerGroup, (const std::string&), ()); }; -TEST(clientRemotingProcessor, processRequest) { - MockMQClientFactory* factory = new MockMQClientFactory("testClientId", 4, 3000, 4000, "a"); - ClientRemotingProcessor clientRemotingProcessor(factory); - - string addr = "127.0.0.1:9876"; - RemotingCommand* command = new RemotingCommand(); - RemotingCommand* pResponse = new RemotingCommand(13); +// TEST(ClientRemotingProcessorTest, ProcessRequest) { +// MQClientConfigImpl clientConfig; +// clientConfig.setUnitName("a"); +// clientConfig.setTcpTransportWorkerThreadNum(4); +// clientConfig.setTcpTransportConnectTimeout(3000); +// clientConfig.setTcpTransportTryLockTimeout(4000); +// std::unique_ptr instance(new MockMQClientInstance(clientConfig, "testClientId")); +// ClientRemotingProcessor clientRemotingProcessor(instance.get()); + +// auto channel = TcpTransport::CreateTransport(nullptr, nullptr, nullptr); +// std::string addr = "127.0.0.1:9876"; + +// std::unique_ptr requestCommand(new RemotingCommand()); - pResponse->setCode(MQRequestCode::RESET_CONSUMER_CLIENT_OFFSET); - command->setCode(MQRequestCode::RESET_CONSUMER_CLIENT_OFFSET); - EXPECT_TRUE(clientRemotingProcessor.processRequest(addr, command) == nullptr); - EXPECT_EQ(nullptr, clientRemotingProcessor.processRequest(addr, command)); +// // reset offset request without body +// requestCommand->setCode(MQRequestCode::RESET_CONSUMER_CLIENT_OFFSET); +// EXPECT_EQ(nullptr, clientRemotingProcessor.processRequest(channel, requestCommand.get())); - NotifyConsumerIdsChangedRequestHeader* header = new NotifyConsumerIdsChangedRequestHeader(); - header->setGroup("testGroup"); - RemotingCommand* twoCommand = new RemotingCommand(MQRequestCode::NOTIFY_CONSUMER_IDS_CHANGED, header); +// auto* header = new NotifyConsumerIdsChangedRequestHeader(); +// header->setConsumerGroup("testGroup"); +// RemotingCommand* twoCommand = new RemotingCommand(MQRequestCode::NOTIFY_CONSUMER_IDS_CHANGED, header); + +// EXPECT_EQ(NULL, clientRemotingProcessor.processRequest(addr, twoCommand)); + +// command->setCode(MQRequestCode::GET_CONSUMER_RUNNING_INFO); +// // EXPECT_EQ(NULL , clientRemotingProcessor.processRequest(addr, command)); + +// command->setCode(MQRequestCode::CHECK_TRANSACTION_STATE); +// EXPECT_TRUE(clientRemotingProcessor.processRequest(addr, command) == nullptr); + +// command->setCode(MQRequestCode::GET_CONSUMER_STATUS_FROM_CLIENT); +// EXPECT_TRUE(clientRemotingProcessor.processRequest(addr, command) == nullptr); - EXPECT_EQ(NULL, clientRemotingProcessor.processRequest(addr, twoCommand)); +// command->setCode(MQRequestCode::CONSUME_MESSAGE_DIRECTLY); +// EXPECT_TRUE(clientRemotingProcessor.processRequest(addr, command) == nullptr); - command->setCode(MQRequestCode::GET_CONSUMER_RUNNING_INFO); - // EXPECT_EQ(NULL , clientRemotingProcessor.processRequest(addr, command)); +// command->setCode(1); +// EXPECT_TRUE(clientRemotingProcessor.processRequest(addr, command) == nullptr); + +// delete twoCommand; +// delete command; +// delete pResponse; +// } + +// TEST(ClientRemotingProcessorTest, resetOffset) { +// MockMQClientFactory* factory = new MockMQClientFactory("testClientId", 4, 3000, 4000, "a"); +// Mock::AllowLeak(factory); +// ClientRemotingProcessor clientRemotingProcessor(factory); +// Value root; +// Value messageQueues; +// Value messageQueue; +// messageQueue["brokerName"] = "testBroker"; +// messageQueue["queueId"] = 4; +// messageQueue["topic"] = "testTopic"; +// messageQueue["offset"] = 1024; + +// messageQueues.append(messageQueue); +// root["offsetTable"] = messageQueues; + +// FastWriter wrtier; +// string strData = wrtier.write(root); + +// ResetOffsetRequestHeader* header = new ResetOffsetRequestHeader(); +// RemotingCommand* request = new RemotingCommand(13, header); + +// EXPECT_CALL(*factory, resetOffset(_, _, _)).Times(1); +// clientRemotingProcessor.resetOffset(request); + +// request->SetBody(strData.c_str(), strData.size() - 2); +// clientRemotingProcessor.resetOffset(request); + +// request->SetBody(strData.c_str(), strData.size()); +// clientRemotingProcessor.resetOffset(request); + +// // here header no need delete, it will managered by RemotingCommand +// // delete header; +// delete request; +// } + +// TEST(ClientRemotingProcessorTest, getConsumerRunningInfo) { +// MockMQClientFactory* factory = new MockMQClientFactory("testClientId", 4, 3000, 4000, "a"); +// ConsumerRunningInfo* info = new ConsumerRunningInfo(); +// EXPECT_CALL(*factory, consumerRunningInfo(_)).Times(2).WillOnce(Return(info)).WillOnce(Return(info)); +// EXPECT_CALL(*factory, getSessionCredentialFromConsumer(_, _)) +// .Times(2); //.WillRepeatedly(SetArgReferee<1>(sessionCredentials)); +// ClientRemotingProcessor clientRemotingProcessor(factory); + +// GetConsumerRunningInfoRequestHeader* header = new GetConsumerRunningInfoRequestHeader(); +// header->setConsumerGroup("testGroup"); + +// RemotingCommand* request = new RemotingCommand(14, header); + +// RemotingCommand* command = clientRemotingProcessor.getConsumerRunningInfo("127.0.0.1:9876", request); +// EXPECT_EQ(command->getCode(), MQResponseCode::SYSTEM_ERROR); +// EXPECT_EQ(command->getRemark(), "The Consumer Group not exist in this consumer"); +// delete command; +// delete request; +// } + +// TEST(ClientRemotingProcessorTest, notifyConsumerIdsChanged) { +// MockMQClientFactory* factory = new MockMQClientFactory("testClientId", 4, 3000, 4000, "a"); +// Mock::AllowLeak(factory); +// ClientRemotingProcessor clientRemotingProcessor(factory); +// NotifyConsumerIdsChangedRequestHeader* header = new NotifyConsumerIdsChangedRequestHeader(); +// header->setGroup("testGroup"); +// RemotingCommand* request = new RemotingCommand(14, header); - command->setCode(MQRequestCode::CHECK_TRANSACTION_STATE); - EXPECT_TRUE(clientRemotingProcessor.processRequest(addr, command) == nullptr); +// EXPECT_CALL(*factory, doRebalanceByConsumerGroup(_)).Times(1); +// clientRemotingProcessor.notifyConsumerIdsChanged(request); - command->setCode(MQRequestCode::GET_CONSUMER_STATUS_FROM_CLIENT); - EXPECT_TRUE(clientRemotingProcessor.processRequest(addr, command) == nullptr); - - command->setCode(MQRequestCode::CONSUME_MESSAGE_DIRECTLY); - EXPECT_TRUE(clientRemotingProcessor.processRequest(addr, command) == nullptr); - - command->setCode(1); - EXPECT_TRUE(clientRemotingProcessor.processRequest(addr, command) == nullptr); - - delete twoCommand; - delete command; - delete pResponse; -} +// delete request; +// } -TEST(clientRemotingProcessor, resetOffset) { - MockMQClientFactory* factory = new MockMQClientFactory("testClientId", 4, 3000, 4000, "a"); - Mock::AllowLeak(factory); - ClientRemotingProcessor clientRemotingProcessor(factory); - Value root; - Value messageQueues; - Value messageQueue; - messageQueue["brokerName"] = "testBroker"; - messageQueue["queueId"] = 4; - messageQueue["topic"] = "testTopic"; - messageQueue["offset"] = 1024; - - messageQueues.append(messageQueue); - root["offsetTable"] = messageQueues; - - FastWriter wrtier; - string strData = wrtier.write(root); - - ResetOffsetRequestHeader* header = new ResetOffsetRequestHeader(); - RemotingCommand* request = new RemotingCommand(13, header); - - EXPECT_CALL(*factory, resetOffset(_, _, _)).Times(1); - clientRemotingProcessor.resetOffset(request); - - request->SetBody(strData.c_str(), strData.size() - 2); - clientRemotingProcessor.resetOffset(request); - - request->SetBody(strData.c_str(), strData.size()); - clientRemotingProcessor.resetOffset(request); - - // here header no need delete, it will managered by RemotingCommand - // delete header; - delete request; -} +// TEST(ClientRemotingProcessorTest, resetOffsetBody) { +// MockMQClientFactory* factory = new MockMQClientFactory("testClientId", 4, 3000, 4000, "a"); +// ClientRemotingProcessor clientRemotingProcessor(factory); -TEST(clientRemotingProcessorS, getConsumerRunningInfo) { - MockMQClientFactory* factory = new MockMQClientFactory("testClientId", 4, 3000, 4000, "a"); - ConsumerRunningInfo* info = new ConsumerRunningInfo(); - EXPECT_CALL(*factory, consumerRunningInfo(_)).Times(2).WillOnce(Return(info)).WillOnce(Return(info)); - EXPECT_CALL(*factory, getSessionCredentialFromConsumer(_, _)) - .Times(2); //.WillRepeatedly(SetArgReferee<1>(sessionCredentials)); - ClientRemotingProcessor clientRemotingProcessor(factory); - - GetConsumerRunningInfoRequestHeader* header = new GetConsumerRunningInfoRequestHeader(); - header->setConsumerGroup("testGroup"); - - RemotingCommand* request = new RemotingCommand(14, header); - - RemotingCommand* command = clientRemotingProcessor.getConsumerRunningInfo("127.0.0.1:9876", request); - EXPECT_EQ(command->getCode(), MQResponseCode::SYSTEM_ERROR); - EXPECT_EQ(command->getRemark(), "The Consumer Group not exist in this consumer"); - delete command; - delete request; -} - -TEST(clientRemotingProcessor, notifyConsumerIdsChanged) { - MockMQClientFactory* factory = new MockMQClientFactory("testClientId", 4, 3000, 4000, "a"); - Mock::AllowLeak(factory); - ClientRemotingProcessor clientRemotingProcessor(factory); - NotifyConsumerIdsChangedRequestHeader* header = new NotifyConsumerIdsChangedRequestHeader(); - header->setGroup("testGroup"); - RemotingCommand* request = new RemotingCommand(14, header); - - EXPECT_CALL(*factory, doRebalanceByConsumerGroup(_)).Times(1); - clientRemotingProcessor.notifyConsumerIdsChanged(request); - - delete request; -} - -TEST(clientRemotingProcessor, resetOffsetBody) { - MockMQClientFactory* factory = new MockMQClientFactory("testClientId", 4, 3000, 4000, "a"); - ClientRemotingProcessor clientRemotingProcessor(factory); - - Value root; - Value messageQueues; - Value messageQueue; - messageQueue["brokerName"] = "testBroker"; - messageQueue["queueId"] = 4; - messageQueue["topic"] = "testTopic"; - messageQueue["offset"] = 1024; - - messageQueues.append(messageQueue); - root["offsetTable"] = messageQueues; - - FastWriter wrtier; - string strData = wrtier.write(root); - - MemoryBlock* mem = new MemoryBlock(strData.c_str(), strData.size()); - - ResetOffsetBody* resetOffset = ResetOffsetBody::Decode(mem); - - map map = resetOffset->getOffsetTable(); - MQMessageQueue mqmq("testTopic", "testBroker", 4); - EXPECT_EQ(map[mqmq], 1024); - Mock::AllowLeak(factory); - delete resetOffset; - delete mem; -} +// Value root; +// Value messageQueues; +// Value messageQueue; +// messageQueue["brokerName"] = "testBroker"; +// messageQueue["queueId"] = 4; +// messageQueue["topic"] = "testTopic"; +// messageQueue["offset"] = 1024; + +// messageQueues.append(messageQueue); +// root["offsetTable"] = messageQueues; + +// FastWriter wrtier; +// string strData = wrtier.write(root); + +// MemoryBlock* mem = new MemoryBlock(strData.c_str(), strData.size()); + +// ResetOffsetBody* resetOffset = ResetOffsetBody::Decode(mem); + +// map map = resetOffset->getOffsetTable(); +// MQMessageQueue mqmq("testTopic", "testBroker", 4); +// EXPECT_EQ(map[mqmq], 1024); +// Mock::AllowLeak(factory); +// delete resetOffset; +// delete mem; +// } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "clientRemotingProcessor.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "ClientRemotingProcessorTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/transport/ResponseFutureTest.cpp b/test/src/transport/ResponseFutureTest.cpp index 9c23ed813..bc717e0ac 100644 --- a/test/src/transport/ResponseFutureTest.cpp +++ b/test/src/transport/ResponseFutureTest.cpp @@ -14,110 +14,71 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include +#include -#include "AsyncCallback.h" -#include "AsyncCallbackWrap.h" -#include "MQClientAPIImpl.h" -#include "MQMessage.h" +#include "InvokeCallback.h" #include "RemotingCommand.h" #include "ResponseFuture.h" -#include "TcpRemotingClient.h" #include "UtilAll.h" +#include "protocol/RequestCode.h" using ::testing::_; -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; -using rocketmq::AsyncCallback; -using rocketmq::AsyncCallbackStatus; -using rocketmq::asyncCallBackType; -using rocketmq::AsyncCallbackWrap; -using rocketmq::MQClientAPIImpl; -using rocketmq::MQMessage; +using rocketmq::InvokeCallback; +using rocketmq::MQRequestCode; using rocketmq::RemotingCommand; using rocketmq::ResponseFuture; -using rocketmq::SendCallbackWrap; -using rocketmq::TcpRemotingClient; using rocketmq::UtilAll; -class MockAsyncCallbackWrap : public SendCallbackWrap { +class MockInvokeCallback : public InvokeCallback { public: - MockAsyncCallbackWrap(AsyncCallback* pAsyncCallback, MQClientAPIImpl* pclientAPI) - : SendCallbackWrap("", MQMessage(), pAsyncCallback, pclientAPI) {} - - MOCK_METHOD2(operationComplete, void(ResponseFuture*, bool)); - MOCK_METHOD0(onException, void()); - asyncCallBackType getCallbackType() { return asyncCallBackType::sendCallbackWrap; } + void operationComplete(ResponseFuture* responseFuture) noexcept {} }; -TEST(responseFuture, init) { - ResponseFuture responseFuture(13, 4, NULL, 1000); - EXPECT_EQ(responseFuture.getRequestCode(), 13); +TEST(ResponseFutureTest, Init) { + ResponseFuture responseFuture(MQRequestCode::QUERY_BROKER_OFFSET, 4, 1000); + EXPECT_EQ(responseFuture.getRequestCode(), MQRequestCode::QUERY_BROKER_OFFSET); EXPECT_EQ(responseFuture.getOpaque(), 4); - - EXPECT_EQ(responseFuture.getRequestCommand().getCode(), 0); + EXPECT_EQ(responseFuture.getTimeoutMillis(), 1000); EXPECT_FALSE(responseFuture.isSendRequestOK()); - EXPECT_EQ(responseFuture.getMaxRetrySendTimes(), 1); - EXPECT_EQ(responseFuture.getRetrySendTimes(), 1); - EXPECT_EQ(responseFuture.getBrokerAddr(), ""); - - EXPECT_FALSE(responseFuture.getAsyncFlag()); - EXPECT_TRUE(responseFuture.getAsyncCallbackWrap() == nullptr); + EXPECT_FALSE(responseFuture.hasInvokeCallback()); - // ~ResponseFuture delete pcall - SendCallbackWrap* pcall = new SendCallbackWrap("", MQMessage(), nullptr, nullptr); - ResponseFuture twoResponseFuture(13, 4, nullptr, 1000, true, pcall); - EXPECT_TRUE(twoResponseFuture.getAsyncFlag()); - EXPECT_FALSE(twoResponseFuture.getAsyncCallbackWrap() == nullptr); + // ~ResponseFuture delete callback + auto* callback = new MockInvokeCallback(); + ResponseFuture twoResponseFuture(MQRequestCode::QUERY_BROKER_OFFSET, 4, 1000, callback); + EXPECT_TRUE(twoResponseFuture.hasInvokeCallback()); } -TEST(responseFuture, info) { - ResponseFuture responseFuture(13, 4, NULL, 1000); - - responseFuture.setBrokerAddr("127.0.0.1:9876"); - EXPECT_EQ(responseFuture.getBrokerAddr(), "127.0.0.1:9876"); - - responseFuture.setMaxRetrySendTimes(3000); - EXPECT_EQ(responseFuture.getMaxRetrySendTimes(), 3000); - - responseFuture.setRetrySendTimes(3000); - EXPECT_EQ(responseFuture.getRetrySendTimes(), 3000); +TEST(ResponseFutureTest, Info) { + ResponseFuture responseFuture(MQRequestCode::QUERY_BROKER_OFFSET, 4, 1000); responseFuture.setSendRequestOK(true); EXPECT_TRUE(responseFuture.isSendRequestOK()); } -TEST(responseFuture, response) { - // m_bAsync = false m_syncResponse - ResponseFuture responseFuture(13, 4, NULL, 1000); - - EXPECT_FALSE(responseFuture.getAsyncFlag()); - - RemotingCommand* pResponseCommand = NULL; - responseFuture.setResponse(pResponseCommand); - EXPECT_EQ(responseFuture.getRequestCommand().getCode(), 0); +TEST(ResponseFutureTest, Response) { + ResponseFuture responseFuture(MQRequestCode::QUERY_BROKER_OFFSET, 4, 1000); + EXPECT_FALSE(responseFuture.hasInvokeCallback()); - // m_bAsync = true m_syncResponse - ResponseFuture twoResponseFuture(13, 4, NULL, 1000, true); - EXPECT_TRUE(twoResponseFuture.getAsyncFlag()); - - ResponseFuture threeSesponseFuture(13, 4, NULL, 1000); + std::unique_ptr responseCommand(new RemotingCommand()); + responseFuture.setResponseCommand(std::move(responseCommand)); + EXPECT_EQ(responseFuture.getResponseCommand()->getCode(), 0); + ResponseFuture responseFuture2(MQRequestCode::QUERY_BROKER_OFFSET, 4, 1000); uint64_t millis = UtilAll::currentTimeMillis(); - RemotingCommand* remotingCommand = threeSesponseFuture.waitResponse(10); + auto remotingCommand = responseFuture2.waitResponse(1000); uint64_t useTime = UtilAll::currentTimeMillis() - millis; - EXPECT_LT(useTime, 30); - - EXPECT_EQ(NULL, remotingCommand); + EXPECT_LT(useTime, 3000); + EXPECT_EQ(remotingCommand, nullptr); } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "responseFuture.*"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "ResponseFutureTest.*"; + return RUN_ALL_TESTS(); } diff --git a/test/src/transport/SocketUtilTest.cpp b/test/src/transport/SocketUtilTest.cpp index 09560b241..41d200d36 100644 --- a/test/src/transport/SocketUtilTest.cpp +++ b/test/src/transport/SocketUtilTest.cpp @@ -14,34 +14,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include +#include #include "SocketUtil.h" -using ::testing::InitGoogleMock; -using ::testing::InitGoogleTest; +using testing::InitGoogleMock; +using testing::InitGoogleTest; using testing::Return; -TEST(socketUtil, init) { - sockaddr addr = rocketmq::IPPort2socketAddress(inet_addr("127.0.0.1"), 10091); +using namespace rocketmq; - EXPECT_EQ(rocketmq::socketAddress2IPPort(addr), "1.0.0.127:10091"); +TEST(SocketUtilTest, Convert) { + struct sockaddr* sa = ipPort2SocketAddress(0x7F000001, 0x276B); + struct sockaddr_in* sin = (struct sockaddr_in*)sa; + EXPECT_EQ(sin->sin_addr.s_addr, 0x0100007F); + EXPECT_EQ(sin->sin_port, 0x6B27); - int host; - int port; + EXPECT_EQ(socketAddress2String(sa), "127.0.0.1:10091"); - rocketmq::socketAddress2IPPort(addr, host, port); - EXPECT_EQ(host, inet_addr("127.0.0.1")); - EXPECT_EQ(port, 10091); - - EXPECT_EQ(rocketmq::socketAddress2String(addr), "1.0.0.127"); + sa = string2SocketAddress("127.0.0.1:10091"); + sin = (struct sockaddr_in*)sa; + EXPECT_EQ(sin->sin_addr.s_addr, 0x0100007F); + EXPECT_EQ(sin->sin_port, 0x6B27); } int main(int argc, char* argv[]) { InitGoogleMock(&argc, argv); testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "socketUtil.init"; - int itestts = RUN_ALL_TESTS(); - return itestts; + testing::GTEST_FLAG(filter) = "SocketUtilTest.*"; + return RUN_ALL_TESTS(); } From 8c6f24d5cfcd9cf1c739ce14013b2eb4f4c3e254 Mon Sep 17 00:00:00 2001 From: James Yin Date: Sat, 9 May 2020 17:17:22 +0800 Subject: [PATCH 03/62] findConsumerIds from same broker more time --- src/MQClientInstance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MQClientInstance.cpp b/src/MQClientInstance.cpp index 1ac65166b..213d74b64 100644 --- a/src/MQClientInstance.cpp +++ b/src/MQClientInstance.cpp @@ -873,7 +873,7 @@ void MQClientInstance::findConsumerIds(const std::string& topic, std::lock_guard lock(m_topicBrokerAddrTableMutex); const auto& it = m_topicBrokerAddrTable.find(topic); if (it != m_topicBrokerAddrTable.end()) { - if (UtilAll::currentTimeMillis() < it->second.second + 40000) { + if (UtilAll::currentTimeMillis() < it->second.second + 120000) { brokerAddr = it->second.first; } } From 7eef63909442d1b522fce2170f9f10c746292199 Mon Sep 17 00:00:00 2001 From: James Yin Date: Mon, 18 May 2020 11:23:35 +0800 Subject: [PATCH 04/62] fixed uniqMsgId for batch result. --- src/MQClientAPIImpl.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index 53da5865c..23fea6a18 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -219,14 +219,13 @@ SendResult* MQClientAPIImpl::processSendResponse(const std::string& brokerName, if (msg->isBatch()) { const auto& messages = static_cast(msg)->getMessages(); uniqMsgId.clear(); - uniqMsgId.reserve(33 * messages.size()); - bool isFirst = true; + uniqMsgId.reserve(33 * messages.size() + 1); for (const auto& message : messages) { - if (!isFirst) { - uniqMsgId.append(","); - isFirst = false; - } uniqMsgId.append(MessageClientIDSetter::getUniqID(*message)); + uniqMsgId.append(","); + } + if (!uniqMsgId.empty()) { + uniqMsgId.resize(uniqMsgId.length() - 1); } } From 3636d60d6a034b551d74a83da1a6e030033819f1 Mon Sep 17 00:00:00 2001 From: James Yin Date: Fri, 22 May 2020 12:07:13 +0800 Subject: [PATCH 05/62] Catch exception when resolve domain failed --- src/transport/EventLoop.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/transport/EventLoop.cpp b/src/transport/EventLoop.cpp index b1ccde7fc..62e535c41 100644 --- a/src/transport/EventLoop.cpp +++ b/src/transport/EventLoop.cpp @@ -30,7 +30,7 @@ EventLoop* EventLoop::GetDefaultEventLoop() { EventLoop::EventLoop(const struct event_config* config, bool run_immediately) : m_eventBase(nullptr), m_loopThread("EventLoop"), _is_running(false) { - // tell libevent support multi-threads +// tell libevent support multi-threads #ifdef WIN32 evthread_use_windows_threads(); #else @@ -206,9 +206,14 @@ int BufferEvent::connect(const std::string& addr) { return -1; } - auto* sa = string2SocketAddress(addr); - m_peerAddrPort = socketAddress2String(sa); // resolve domain - return bufferevent_socket_connect(m_bufferEvent, sa, sockaddr_size(sa)); + try { + auto* sa = string2SocketAddress(addr); // resolve domain + m_peerAddrPort = socketAddress2String(sa); + return bufferevent_socket_connect(m_bufferEvent, sa, sockaddr_size(sa)); + } catch (const std::exception& e) { + LOG_ERROR_NEW("can not connect to {}, {}", addr, e.what()); + return -1; + } } void BufferEvent::close() { From 8e6c3b939c2a18a0ecf20b1cffadb5f51b6176fe Mon Sep 17 00:00:00 2001 From: James Yin Date: Thu, 28 May 2020 10:59:51 +0800 Subject: [PATCH 06/62] remove redundant code --- src/producer/MQFaultStrategy.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/producer/MQFaultStrategy.cpp b/src/producer/MQFaultStrategy.cpp index a73b14920..9abef32c4 100644 --- a/src/producer/MQFaultStrategy.cpp +++ b/src/producer/MQFaultStrategy.cpp @@ -33,9 +33,7 @@ const MQMessageQueue& MQFaultStrategy::selectOneMessageQueue(const TopicPublishI auto pos = index++ % messageQueueList.size(); const auto& mq = messageQueueList[pos]; if (m_latencyFaultTolerance.isAvailable(mq.getBrokerName())) { - if (lastBrokerName.empty() || mq.getBrokerName() != lastBrokerName) { - return mq; - } + return mq; } } } From c595776c5939982da4a913811a95db7fbb37f07e Mon Sep 17 00:00:00 2001 From: James Yin Date: Thu, 16 Jul 2020 08:42:12 +0800 Subject: [PATCH 07/62] fix(executor): incorrect param pass to forward --- src/concurrent/concurrent_queue.hpp | 7 ++++--- src/concurrent/executor.hpp | 10 +++++----- src/concurrent/executor_impl.hpp | 7 ++++--- src/concurrent/thread_group.hpp | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/concurrent/concurrent_queue.hpp b/src/concurrent/concurrent_queue.hpp index 5a67e8f17..20ae5f5d7 100644 --- a/src/concurrent/concurrent_queue.hpp +++ b/src/concurrent/concurrent_queue.hpp @@ -38,8 +38,9 @@ class concurrent_queue_node { private: template ::type, value_type>::value, int>::type = 0> - explicit concurrent_queue_node(E v) : value_(new value_type(std::forward(v))) {} + explicit concurrent_queue_node(E&& v) : value_(new value_type(std::forward(v))) {} + // for pointer template ::value, int>::type = 0> explicit concurrent_queue_node(E v) : value_(v) {} @@ -76,7 +77,7 @@ class concurrent_queue { bool empty() { return sentinel == tail_.load(); } template - void push_back(E v) { + void push_back(E&& v) { auto* node = new node_type(std::forward(v)); push_back_impl(node); } @@ -144,7 +145,7 @@ class concurrent_queue { } } - std::atomic head_, tail_; + std::atomic head_, tail_; node_type* const sentinel; bool _clear_when_destruct; }; diff --git a/src/concurrent/executor.hpp b/src/concurrent/executor.hpp index 3ed5ad5fb..7f530d97b 100644 --- a/src/concurrent/executor.hpp +++ b/src/concurrent/executor.hpp @@ -28,12 +28,12 @@ namespace rocketmq { typedef std::function handler_type; struct executor_handler { - handler_type handler_; + const handler_type handler_; std::unique_ptr> promise_; template ::type, handler_type>::value, int>::type = 0> - explicit executor_handler(H handler) + explicit executor_handler(H&& handler) : handler_(std::forward(handler)), promise_(new std::promise) {} void operator()() noexcept { @@ -51,9 +51,9 @@ struct executor_handler { } } - template - void abort(_Ep&& exception) noexcept { - promise_->set_exception(std::make_exception_ptr(std::forward<_Ep>(exception))); + template + void abort(E&& exception) noexcept { + promise_->set_exception(std::make_exception_ptr(std::forward(exception))); } private: diff --git a/src/concurrent/executor_impl.hpp b/src/concurrent/executor_impl.hpp index 0c0a0cb2b..10acdd569 100644 --- a/src/concurrent/executor_impl.hpp +++ b/src/concurrent/executor_impl.hpp @@ -31,7 +31,7 @@ namespace rocketmq { class abstract_executor_service : virtual public executor_service { public: std::future submit(const handler_type& task) override { - std::unique_ptr handler(new executor_handler(task)); + std::unique_ptr handler(new executor_handler(const_cast(task))); std::future fut = handler->promise_->get_future(); execute(std::move(handler)); return fut; @@ -132,7 +132,7 @@ struct scheduled_executor_handler : public executor_handler { template ::type, handler_type>::value, int>::type = 0> - explicit scheduled_executor_handler(H handler, const std::chrono::steady_clock::time_point& time) + explicit scheduled_executor_handler(H&& handler, const std::chrono::steady_clock::time_point& time) : executor_handler(std::forward(handler)), wakeup_time_(time) {} bool operator<(const scheduled_executor_handler& other) const { return (wakeup_time_ > other.wakeup_time_); } @@ -232,7 +232,8 @@ class scheduled_thread_pool_executor : public thread_pool_executor, virtual publ std::future schedule(const handler_type& task, long delay, time_unit unit) override { auto time_point = until_time_point(delay, unit); - std::unique_ptr handler(new scheduled_executor_handler(task, time_point)); + std::unique_ptr handler( + new scheduled_executor_handler(const_cast(task), time_point)); std::future fut = handler->promise_->get_future(); { diff --git a/src/concurrent/thread_group.hpp b/src/concurrent/thread_group.hpp index a7ea833d4..59bcd9a3f 100644 --- a/src/concurrent/thread_group.hpp +++ b/src/concurrent/thread_group.hpp @@ -29,7 +29,7 @@ class thread_group { template thread_group(const std::string& name, Function f, std::size_t num_threads) : name_(name), first_(nullptr) { - create_thread(f, num_threads); + create_threads(f, num_threads); } // Destructor joins any remaining threads in the group. From 4d79bcf0f13b6962cfd0f1d86d649f372e32e158 Mon Sep 17 00:00:00 2001 From: James Yin Date: Sat, 18 Jul 2020 21:47:05 +0800 Subject: [PATCH 08/62] refactor(MQMessage): MQMessage[Ext] as reference --- example/PullConsumer.cpp | 10 +- example/common.h | 4 +- include/DefaultMQProducer.h | 42 ++-- include/DefaultMQPullConsumer.h | 4 +- include/DefaultMQPushConsumer.h | 4 +- include/MQAdmin.h | 2 +- include/MQConsumer.h | 4 +- include/MQMessage.h | 121 +++++----- include/MQMessageConst.h | 2 +- include/MQMessageExt.h | 138 +++++------ include/MQMessageListener.h | 13 +- include/MQProducer.h | 46 ++-- include/Message.h | 94 ++++++++ include/MessageExt.h | 88 +++++++ include/MessageUtil.h | 13 +- include/QueryResult.h | 6 +- include/RequestCallback.h | 4 +- include/RocketMQClient.h | 10 +- include/TopicFilterType.h | 7 +- include/TransactionMQProducer.h | 2 +- src/ClientRemotingProcessor.cpp | 6 +- src/MQAdminImpl.cpp | 4 +- src/MQAdminImpl.h | 2 +- src/MQClientAPIImpl.cpp | 24 +- src/MQClientAPIImpl.h | 14 +- src/MQClientImpl.cpp | 2 +- src/MQClientImpl.h | 2 +- src/common/ByteOrder.h | 21 +- src/common/MessageSysFlag.cpp | 3 + src/common/MessageSysFlag.h | 3 + src/common/SendCallbackWrap.cpp | 4 +- src/common/SendCallbackWrap.h | 8 +- src/common/UtilAll.cpp | 62 ++--- src/common/UtilAll.h | 3 +- src/common/Validators.cpp | 2 +- src/common/Validators.h | 4 +- .../ConsumeMessageConcurrentlyService.cpp | 19 +- src/consumer/ConsumeMessageOrderlyService.cpp | 14 +- src/consumer/ConsumeMsgService.h | 10 +- src/consumer/DefaultMQPullConsumer.cpp | 4 +- src/consumer/DefaultMQPushConsumer.cpp | 4 +- src/consumer/DefaultMQPushConsumerImpl.cpp | 38 ++-- src/consumer/DefaultMQPushConsumerImpl.h | 6 +- src/consumer/ProcessQueue.cpp | 8 +- src/consumer/ProcessQueue.h | 14 +- src/consumer/PullAPIWrapper.cpp | 18 +- src/consumer/PullResult.cpp | 47 ++-- {include => src/consumer}/PullResult.h | 39 ++-- src/extern/CBatchMessage.cpp | 9 +- src/extern/CProducer.cpp | 20 +- src/extern/CPullConsumer.cpp | 20 +- src/extern/CPushConsumer.cpp | 10 +- src/message/MQMessage.cpp | 174 ++++---------- src/message/MQMessageConst.cpp | 60 +++++ src/message/MQMessageExt.cpp | 133 ++++------- src/message/MQMessageId.h | 55 ----- src/message/MessageAccessor.h | 18 +- src/message/MessageBatch.cpp | 37 ++- src/message/MessageBatch.h | 20 +- src/message/MessageClientIDSetter.h | 4 +- .../{MQDecoder.cpp => MessageDecoder.cpp} | 137 +++++------ src/message/{MQDecoder.h => MessageDecoder.h} | 36 ++- src/message/MessageExtImpl.cpp | 214 ++++++++++++++++++ src/message/MessageExtImpl.h | 117 ++++++++++ src/message/MessageId.h | 58 +++++ src/message/MessageImpl.cpp | 187 +++++++++++++++ src/message/MessageImpl.h | 91 ++++++++ src/message/MessageUtil.cpp | 52 ++--- src/producer/DefaultMQProducer.cpp | 42 ++-- src/producer/DefaultMQProducerImpl.cpp | 177 +++++++-------- src/producer/DefaultMQProducerImpl.h | 60 ++--- src/producer/MQProducerInner.h | 2 +- src/producer/RequestResponseFuture.cpp | 6 +- src/producer/RequestResponseFuture.h | 10 +- src/producer/TransactionMQProducer.cpp | 2 +- src/transport/SocketUtil.cpp | 14 +- test/src/message/MessageBatchTest.cpp | 24 +- ...DecoderTest.cpp => MessageDecoderTest.cpp} | 26 +-- ...{MQMessageIdTest.cpp => MessageIdTest.cpp} | 6 +- 79 files changed, 1776 insertions(+), 1044 deletions(-) create mode 100644 include/Message.h create mode 100644 include/MessageExt.h rename {include => src/consumer}/PullResult.h (61%) create mode 100644 src/message/MQMessageConst.cpp delete mode 100644 src/message/MQMessageId.h rename src/message/{MQDecoder.cpp => MessageDecoder.cpp} (66%) rename src/message/{MQDecoder.h => MessageDecoder.h} (62%) create mode 100644 src/message/MessageExtImpl.cpp create mode 100644 src/message/MessageExtImpl.h create mode 100644 src/message/MessageId.h create mode 100644 src/message/MessageImpl.cpp create mode 100644 src/message/MessageImpl.h rename test/src/message/{MQDecoderTest.cpp => MessageDecoderTest.cpp} (87%) rename test/src/message/{MQMessageIdTest.cpp => MessageIdTest.cpp} (92%) diff --git a/example/PullConsumer.cpp b/example/PullConsumer.cpp index 7bd7ffd49..e7472b331 100644 --- a/example/PullConsumer.cpp +++ b/example/PullConsumer.cpp @@ -77,18 +77,18 @@ int main(int argc, char* argv[]) { do { try { PullResult result = consumer.pull(mq, "*", getMessageQueueOffset(mq), 32); - g_msgCount += result.msgFoundList.size(); - std::cout << result.msgFoundList.size() << std::endl; + g_msgCount += result.msg_found_list_.size(); + std::cout << result.msg_found_list_.size() << std::endl; // if pull request timeout or received NULL response, pullStatus will be // setted to BROKER_TIMEOUT, // And nextBeginOffset/minOffset/MaxOffset will be setted to 0 - if (result.pullStatus != BROKER_TIMEOUT) { - putMessageQueueOffset(mq, result.nextBeginOffset); + if (result.pull_status_ != BROKER_TIMEOUT) { + putMessageQueueOffset(mq, result.next_begin_offset_); PrintPullResult(&result); } else { std::cout << "broker timeout occur" << std::endl; } - switch (result.pullStatus) { + switch (result.pull_status_) { case FOUND: case NO_MATCHED_MSG: case OFFSET_ILLEGAL: diff --git a/example/common.h b/example/common.h index 84683bc39..90bff8e66 100644 --- a/example/common.h +++ b/example/common.h @@ -114,9 +114,9 @@ static void PrintResult(rocketmq::SendResult* result) { void PrintPullResult(rocketmq::PullResult* result) { std::cout << result->toString() << std::endl; - if (result->pullStatus == rocketmq::FOUND) { + if (result->pull_status_ == rocketmq::FOUND) { std::cout << result->toString() << std::endl; - for (auto& msg : result->msgFoundList) { + for (auto& msg : result->msg_found_list_) { std::cout << "=======================================================" << std::endl << msg->toString() << std::endl; } diff --git a/include/DefaultMQProducer.h b/include/DefaultMQProducer.h index 91e0e2b4d..2219dfe2f 100644 --- a/include/DefaultMQProducer.h +++ b/include/DefaultMQProducer.h @@ -38,43 +38,43 @@ class ROCKETMQCLIENT_API DefaultMQProducer : public MQProducer, public DefaultMQ void shutdown() override; // Sync: caller will be responsible for the lifecycle of messages. - SendResult send(MQMessagePtr msg) override; - SendResult send(MQMessagePtr msg, long timeout) override; - SendResult send(MQMessagePtr msg, const MQMessageQueue& mq) override; - SendResult send(MQMessagePtr msg, const MQMessageQueue& mq, long timeout) override; + SendResult send(MQMessage& msg) override; + SendResult send(MQMessage& msg, long timeout) override; + SendResult send(MQMessage& msg, const MQMessageQueue& mq) override; + SendResult send(MQMessage& msg, const MQMessageQueue& mq, long timeout) override; // Async: don't delete msg object, until callback occur. - void send(MQMessagePtr msg, SendCallback* sendCallback) noexcept override; - void send(MQMessagePtr msg, SendCallback* sendCallback, long timeout) noexcept override; - void send(MQMessagePtr msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept override; - void send(MQMessagePtr msg, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) noexcept override; + void send(MQMessage& msg, SendCallback* sendCallback) noexcept override; + void send(MQMessage& msg, SendCallback* sendCallback, long timeout) noexcept override; + void send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept override; + void send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) noexcept override; // Oneyway: same as sync send, but don't care its result. - void sendOneway(MQMessagePtr msg) override; - void sendOneway(MQMessagePtr msg, const MQMessageQueue& mq) override; + void sendOneway(MQMessage& msg) override; + void sendOneway(MQMessage& msg, const MQMessageQueue& mq) override; // Select - SendResult send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) override; - SendResult send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg, long timeout) override; - void send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg, SendCallback* sendCallback) noexcept override; - void send(MQMessagePtr msg, + SendResult send(MQMessage& msg, MessageQueueSelector* selector, void* arg) override; + SendResult send(MQMessage& msg, MessageQueueSelector* selector, void* arg, long timeout) override; + void send(MQMessage& msg, MessageQueueSelector* selector, void* arg, SendCallback* sendCallback) noexcept override; + void send(MQMessage& msg, MessageQueueSelector* selector, void* arg, SendCallback* sendCallback, long timeout) noexcept override; - void sendOneway(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) override; + void sendOneway(MQMessage& msg, MessageQueueSelector* selector, void* arg) override; // Transaction - TransactionSendResult sendMessageInTransaction(MQMessagePtr msg, void* arg) override; + TransactionSendResult sendMessageInTransaction(MQMessage& msg, void* arg) override; // Batch: power by sync send, caller will be responsible for the lifecycle of messages. - SendResult send(std::vector& msgs) override; - SendResult send(std::vector& msgs, long timeout) override; - SendResult send(std::vector& msgs, const MQMessageQueue& mq) override; - SendResult send(std::vector& msgs, const MQMessageQueue& mq, long timeout) override; + SendResult send(std::vector& msgs) override; + SendResult send(std::vector& msgs, long timeout) override; + SendResult send(std::vector& msgs, const MQMessageQueue& mq) override; + SendResult send(std::vector& msgs, const MQMessageQueue& mq, long timeout) override; // RPC - MQMessagePtr request(MQMessagePtr msg, long timeout) override; + MQMessage request(MQMessage& msg, long timeout) override; public: // DefaultMQProducerConfig bool isSendLatencyFaultEnable() const override; diff --git a/include/DefaultMQPullConsumer.h b/include/DefaultMQPullConsumer.h index 8461969b6..8b4c71981 100755 --- a/include/DefaultMQPullConsumer.h +++ b/include/DefaultMQPullConsumer.h @@ -37,8 +37,8 @@ class ROCKETMQCLIENT_API DefaultMQPullConsumer : public MQPullConsumer, public D void start() override; void shutdown() override; - bool sendMessageBack(MQMessageExt& msg, int delayLevel) override; - bool sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) override; + bool sendMessageBack(MessageExtPtr msg, int delayLevel) override; + bool sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) override; void fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) override; public: // MQPullConsumer diff --git a/include/DefaultMQPushConsumer.h b/include/DefaultMQPushConsumer.h index e90eb953d..83e473257 100755 --- a/include/DefaultMQPushConsumer.h +++ b/include/DefaultMQPushConsumer.h @@ -33,8 +33,8 @@ class ROCKETMQCLIENT_API DefaultMQPushConsumer : public MQPushConsumer, public D void start() override; void shutdown() override; - bool sendMessageBack(MQMessageExt& msg, int delayLevel) override; - bool sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) override; + bool sendMessageBack(MessageExtPtr msg, int delayLevel) override; + bool sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) override; void fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) override; public: // MQPushConsumer diff --git a/include/MQAdmin.h b/include/MQAdmin.h index 50179ce30..eb681fb57 100644 --- a/include/MQAdmin.h +++ b/include/MQAdmin.h @@ -79,7 +79,7 @@ class ROCKETMQCLIENT_API MQAdmin { * @param offsetMsgId message id * @return message */ - virtual MQMessageExtPtr viewMessage(const std::string& offsetMsgId) = 0; + virtual MQMessageExt viewMessage(const std::string& offsetMsgId) = 0; /** * Query messages diff --git a/include/MQConsumer.h b/include/MQConsumer.h index ebbda3fc6..54ff57605 100755 --- a/include/MQConsumer.h +++ b/include/MQConsumer.h @@ -35,8 +35,8 @@ class ROCKETMQCLIENT_API MQConsumer { virtual void start() = 0; virtual void shutdown() = 0; - virtual bool sendMessageBack(MQMessageExt& msg, int delayLevel) = 0; - virtual bool sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) = 0; + virtual bool sendMessageBack(MessageExtPtr msg, int delayLevel) = 0; + virtual bool sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) = 0; virtual void fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) = 0; }; diff --git a/include/MQMessage.h b/include/MQMessage.h index 19f581d02..3016ec5a5 100644 --- a/include/MQMessage.h +++ b/include/MQMessage.h @@ -14,25 +14,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_MESSAGE_H__ -#define __MQ_MESSAGE_H__ +#ifndef ROCKETMQ_MQMESSAGE_H_ +#define ROCKETMQ_MQMESSAGE_H_ -#include -#include -#include -#include -#include +#include // std::nullptr_t +#include "Message.h" #include "MQMessageConst.h" namespace rocketmq { -class MQMessage; -typedef MQMessage* MQMessagePtr; -typedef std::shared_ptr MQMessagePtr2; -typedef std::unique_ptr MQMessagePtr3; - -class ROCKETMQCLIENT_API MQMessage { +/** + * MQMessage - Reference of Message + */ +class ROCKETMQCLIENT_API MQMessage : virtual public Message // interface +{ public: MQMessage(); MQMessage(const std::string& topic, const std::string& body); @@ -41,68 +37,83 @@ class ROCKETMQCLIENT_API MQMessage { MQMessage(const std::string& topic, const std::string& tags, const std::string& keys, - const int flag, + int32_t flag, const std::string& body, bool waitStoreMsgOK); - MQMessage(const MQMessage& other); - MQMessage& operator=(const MQMessage& other); + public: + // reference constructor + MQMessage(MessagePtr impl) : message_impl_(impl) {} + + // copy constructor + MQMessage(const MQMessage& other) : message_impl_(other.message_impl_) {} + + // assign operator + MQMessage& operator=(const MQMessage& other) { + if (this != &other) { + message_impl_ = other.message_impl_; + } + return *this; + } + + bool operator==(std::nullptr_t) noexcept { return nullptr == message_impl_; } + + friend bool operator==(std::nullptr_t, const MQMessage& message) noexcept { return nullptr == message.message_impl_; } + // convert to boolean + operator bool() noexcept { return nullptr != message_impl_; } + + public: virtual ~MQMessage(); - const std::string& getProperty(const std::string& name) const; - void putProperty(const std::string& name, const std::string& value); - void clearProperty(const std::string& name); + public: // Message + const std::string& getProperty(const std::string& name) const override; + void putProperty(const std::string& name, const std::string& value) override; + void clearProperty(const std::string& name) override; - const std::string& getTopic() const; - void setTopic(const std::string& topic); - void setTopic(const char* body, int len); + const std::string& getTopic() const override; + void setTopic(const std::string& topic) override; + void setTopic(const char* body, int len) override; - const std::string& getTags() const; - void setTags(const std::string& tags); + const std::string& getTags() const override; + void setTags(const std::string& tags) override; - const std::string& getKeys() const; - void setKeys(const std::string& keys); - void setKeys(const std::vector& keys); + const std::string& getKeys() const override; + void setKeys(const std::string& keys) override; + void setKeys(const std::vector& keys) override; - int getDelayTimeLevel() const; - void setDelayTimeLevel(int level); + int getDelayTimeLevel() const override; + void setDelayTimeLevel(int level) override; - bool isWaitStoreMsgOK() const; - void setWaitStoreMsgOK(bool waitStoreMsgOK); + bool isWaitStoreMsgOK() const override; + void setWaitStoreMsgOK(bool waitStoreMsgOK) override; - int getFlag() const; - void setFlag(int flag); + int32_t getFlag() const override; + void setFlag(int32_t flag) override; - const std::string& getBody() const; - void setBody(const char* body, int len); - void setBody(const std::string& body); - void setBody(std::string&& body); + const std::string& getBody() const override; + void setBody(const char* body, int len) override; + void setBody(const std::string& body) override; + void setBody(std::string&& body) override; - const std::string& getTransactionId() const; - void setTransactionId(const std::string& transactionId); + const std::string& getTransactionId() const override; + void setTransactionId(const std::string& transactionId) override; - const std::map& getProperties() const; - void setProperties(const std::map& properties); - void setProperties(std::map&& properties); + const std::map& getProperties() const override; + void setProperties(const std::map& properties) override; + void setProperties(std::map&& properties) override; - virtual bool isBatch() { return false; } + bool isBatch() const override; - virtual std::string toString() const { - std::stringstream ss; - ss << "Message [topic=" << m_topic << ", flag=" << m_flag << ", tag=" << getTags() << ", transactionId='" - << m_transactionId + "']"; - return ss.str(); - } + std::string toString() const override; + + public: + MessagePtr getMessageImpl(); protected: - std::string m_topic; - int m_flag; - std::map m_properties; - std::string m_body; - std::string m_transactionId; + MessagePtr message_impl_; }; } // namespace rocketmq -#endif // __MQ_MESSAGE_H__ +#endif // ROCKETMQ_MQMESSAGE_H_ diff --git a/include/MQMessageConst.h b/include/MQMessageConst.h index 06572197e..071d94d86 100644 --- a/include/MQMessageConst.h +++ b/include/MQMessageConst.h @@ -17,7 +17,7 @@ #ifndef __MQ_MESSAGE_CONST_H__ #define __MQ_MESSAGE_CONST_H__ -#include +#include // std::string #include "RocketMQClient.h" diff --git a/include/MQMessageExt.h b/include/MQMessageExt.h index 42e50783e..0001f7032 100644 --- a/include/MQMessageExt.h +++ b/include/MQMessageExt.h @@ -14,30 +14,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_MESSAGE_EXT_H__ -#define __MQ_MESSAGE_EXT_H__ - -#ifdef WIN32 -// clang-format off -#include -#include -// clang-format on -#else -#include -#endif +#ifndef ROCKETMQ_MQMESSAGEEXT_H_ +#define ROCKETMQ_MQMESSAGEEXT_H_ +#include "MessageExt.h" #include "MQMessage.h" -#include "TopicFilterType.h" namespace rocketmq { -class MQMessageExt; - -typedef MQMessageExt* MQMessageExtPtr; -typedef std::shared_ptr MQMessageExtPtr2; - -// message extend class, which was generated on broker -class ROCKETMQCLIENT_API MQMessageExt : public MQMessage { +/** + * MQMessageExt - Reference of MessageExt + */ +class ROCKETMQCLIENT_API MQMessageExt : public MQMessage, // base + virtual public MessageExt // interface +{ public: MQMessageExt(); MQMessageExt(int queueId, @@ -45,84 +35,64 @@ class ROCKETMQCLIENT_API MQMessageExt : public MQMessage { const struct sockaddr* bornHost, int64_t storeTimestamp, const struct sockaddr* storeHost, - std::string msgId); - - virtual ~MQMessageExt(); - - static TopicFilterType parseTopicFilterType(int32_t sysFlag); - - int32_t getStoreSize() const; - void setStoreSize(int32_t storeSize); - - int32_t getBodyCRC() const; - void setBodyCRC(int32_t bodyCRC); + const std::string& msgId); - int32_t getQueueId() const; - void setQueueId(int32_t queueId); + public: + // reference constructor + MQMessageExt(MessageExtPtr impl) : MQMessage(impl) {} + + // copy constructor + MQMessageExt(const MQMessageExt& other) : MQMessage(other) {} + + // assign operator + MQMessageExt& operator=(const MQMessageExt& other) { + if (this != &other) { + message_impl_ = other.message_impl_; + } + return *this; + } - int64_t getQueueOffset() const; - void setQueueOffset(int64_t queueOffset); + public: + virtual ~MQMessageExt(); - int64_t getCommitLogOffset() const; - void setCommitLogOffset(int64_t physicOffset); + public: // MessageExt + int32_t getStoreSize() const override; + void setStoreSize(int32_t storeSize) override; - int32_t getSysFlag() const; - void setSysFlag(int32_t sysFlag); + int32_t getBodyCRC() const override; + void setBodyCRC(int32_t bodyCRC) override; - int64_t getBornTimestamp() const; - void setBornTimestamp(int64_t bornTimestamp); + int32_t getQueueId() const override; + void setQueueId(int32_t queueId) override; - const struct sockaddr* getBornHost() const; - std::string getBornHostString() const; - void setBornHost(const struct sockaddr* bornHost); + int64_t getQueueOffset() const override; + void setQueueOffset(int64_t queueOffset) override; - int64_t getStoreTimestamp() const; - void setStoreTimestamp(int64_t storeTimestamp); + int64_t getCommitLogOffset() const override; + void setCommitLogOffset(int64_t physicOffset) override; - const struct sockaddr* getStoreHost() const; - std::string getStoreHostString() const; - void setStoreHost(const struct sockaddr* storeHost); + int32_t getSysFlag() const override; + void setSysFlag(int32_t sysFlag) override; - int32_t getReconsumeTimes() const; - void setReconsumeTimes(int32_t reconsumeTimes); + int64_t getBornTimestamp() const override; + void setBornTimestamp(int64_t bornTimestamp) override; - int64_t getPreparedTransactionOffset() const; - void setPreparedTransactionOffset(int64_t preparedTransactionOffset); + std::string getBornHostString() const override; + const struct sockaddr* getBornHost() const override; + void setBornHost(const struct sockaddr* bornHost) override; - virtual const std::string& getMsgId() const; - virtual void setMsgId(const std::string& msgId); + int64_t getStoreTimestamp() const override; + void setStoreTimestamp(int64_t storeTimestamp) override; - std::string toString() const override { - std::stringstream ss; - ss << "MessageExt [queueId=" << m_queueId << ", storeSize=" << m_storeSize << ", queueOffset=" << m_queueOffset - << ", sysFlag=" << m_sysFlag << ", bornTimestamp=" << m_bornTimestamp << ", bornHost=" << getBornHostString() - << ", storeTimestamp=" << m_storeTimestamp << ", storeHost=" << getStoreHostString() << ", msgId=" << getMsgId() - << ", commitLogOffset=" << m_commitLogOffset << ", bodyCRC=" << m_bodyCRC - << ", reconsumeTimes=" << m_reconsumeTimes << ", preparedTransactionOffset=" << m_preparedTransactionOffset - << ", toString()=" << MQMessage::toString() << "]"; - return ss.str(); - } + std::string getStoreHostString() const override; + const struct sockaddr* getStoreHost() const override; + void setStoreHost(const struct sockaddr* storeHost) override; - private: - int32_t m_storeSize; - int32_t m_bodyCRC; - int32_t m_queueId; - int64_t m_queueOffset; - int64_t m_commitLogOffset; - int32_t m_sysFlag; - int64_t m_bornTimestamp; - struct sockaddr* m_bornHost; - int64_t m_storeTimestamp; - struct sockaddr* m_storeHost; - int32_t m_reconsumeTimes; - int64_t m_preparedTransactionOffset; - std::string m_msgId; -}; + int32_t getReconsumeTimes() const override; + void setReconsumeTimes(int32_t reconsumeTimes) override; -class ROCKETMQCLIENT_API MQMessageClientExt : public MQMessageExt { - public: - const std::string& getOffsetMsgId() const; - void setOffsetMsgId(const std::string& offsetMsgId); + int64_t getPreparedTransactionOffset() const override; + void setPreparedTransactionOffset(int64_t preparedTransactionOffset) override; const std::string& getMsgId() const override; void setMsgId(const std::string& msgId) override; @@ -130,4 +100,4 @@ class ROCKETMQCLIENT_API MQMessageClientExt : public MQMessageExt { } // namespace rocketmq -#endif // __MQ_MESSAGE_EXT_H__ +#endif // ROCKETMQ_MQMESSAGEEXT_H_ diff --git a/include/MQMessageListener.h b/include/MQMessageListener.h index 61bb24375..b12763226 100644 --- a/include/MQMessageListener.h +++ b/include/MQMessageListener.h @@ -38,18 +38,7 @@ class ROCKETMQCLIENT_API MQMessageListener { virtual MessageListenerType getMessageListenerType() { return messageListenerDefaultly; } - // Recommended - virtual ConsumeStatus consumeMessage(const std::vector& msgs) { - std::vector msgs2; - msgs2.reserve(msgs.size()); - for (auto& msg : msgs) { - msgs2.push_back(msg.get()); - } - return consumeMessage(msgs2); - } - - // SDK will be responsible for the lifecycle of messages. - virtual ConsumeStatus consumeMessage(const std::vector& msgs) { return RECONSUME_LATER; }; + virtual ConsumeStatus consumeMessage(const std::vector& msgs) { return RECONSUME_LATER; }; }; class ROCKETMQCLIENT_API MessageListenerConcurrently : virtual public MQMessageListener { diff --git a/include/MQProducer.h b/include/MQProducer.h index 81a1c3195..dc32fa317 100644 --- a/include/MQProducer.h +++ b/include/MQProducer.h @@ -36,47 +36,43 @@ class ROCKETMQCLIENT_API MQProducer { virtual void shutdown() = 0; // Sync - virtual SendResult send(MQMessagePtr msg) = 0; - virtual SendResult send(MQMessagePtr msg, long timeout) = 0; - virtual SendResult send(MQMessagePtr msg, const MQMessageQueue& mq) = 0; - virtual SendResult send(MQMessagePtr msg, const MQMessageQueue& mq, long timeout) = 0; + virtual SendResult send(MQMessage& msg) = 0; + virtual SendResult send(MQMessage& msg, long timeout) = 0; + virtual SendResult send(MQMessage& msg, const MQMessageQueue& mq) = 0; + virtual SendResult send(MQMessage& msg, const MQMessageQueue& mq, long timeout) = 0; // Async - // TODO: replace MQMessagePtr by MQMessagePtr2(shared_ptr) - virtual void send(MQMessagePtr msg, SendCallback* sendCallback) noexcept = 0; - virtual void send(MQMessagePtr msg, SendCallback* sendCallback, long timeout) noexcept = 0; - virtual void send(MQMessagePtr msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept = 0; - virtual void send(MQMessagePtr msg, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) noexcept = 0; + virtual void send(MQMessage& msg, SendCallback* sendCallback) noexcept = 0; + virtual void send(MQMessage& msg, SendCallback* sendCallback, long timeout) noexcept = 0; + virtual void send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept = 0; + virtual void send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) noexcept = 0; // Oneyway - virtual void sendOneway(MQMessagePtr msg) = 0; - virtual void sendOneway(MQMessagePtr msg, const MQMessageQueue& mq) = 0; + virtual void sendOneway(MQMessage& msg) = 0; + virtual void sendOneway(MQMessage& msg, const MQMessageQueue& mq) = 0; // Select - virtual SendResult send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) = 0; - virtual SendResult send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg, long timeout) = 0; - virtual void send(MQMessagePtr msg, - MessageQueueSelector* selector, - void* arg, - SendCallback* sendCallback) noexcept = 0; - virtual void send(MQMessagePtr msg, + virtual SendResult send(MQMessage& msg, MessageQueueSelector* selector, void* arg) = 0; + virtual SendResult send(MQMessage& msg, MessageQueueSelector* selector, void* arg, long timeout) = 0; + virtual void send(MQMessage& msg, MessageQueueSelector* selector, void* arg, SendCallback* sendCallback) noexcept = 0; + virtual void send(MQMessage& msg, MessageQueueSelector* selector, void* arg, SendCallback* sendCallback, long timeout) noexcept = 0; - virtual void sendOneway(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) = 0; + virtual void sendOneway(MQMessage& msg, MessageQueueSelector* selector, void* arg) = 0; // Transaction - virtual TransactionSendResult sendMessageInTransaction(MQMessagePtr msg, void* arg) = 0; + virtual TransactionSendResult sendMessageInTransaction(MQMessage& msg, void* arg) = 0; // Batch - virtual SendResult send(std::vector& msgs) = 0; - virtual SendResult send(std::vector& msgs, long timeout) = 0; - virtual SendResult send(std::vector& msgs, const MQMessageQueue& mq) = 0; - virtual SendResult send(std::vector& msgs, const MQMessageQueue& mq, long timeout) = 0; + virtual SendResult send(std::vector& msgs) = 0; + virtual SendResult send(std::vector& msgs, long timeout) = 0; + virtual SendResult send(std::vector& msgs, const MQMessageQueue& mq) = 0; + virtual SendResult send(std::vector& msgs, const MQMessageQueue& mq, long timeout) = 0; // RPC - virtual MQMessagePtr request(MQMessagePtr msg, long timeout) = 0; + virtual MQMessage request(MQMessage& msg, long timeout) = 0; }; } // namespace rocketmq diff --git a/include/Message.h b/include/Message.h new file mode 100644 index 000000000..0320c0ea9 --- /dev/null +++ b/include/Message.h @@ -0,0 +1,94 @@ +/* + * 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_MESSAGE_H_ +#define ROCKETMQ_MESSAGE_H_ + +#include // std::map +#include // std::string +#include // std::vector +#include // std::shared_ptr + +#include "RocketMQClient.h" + +namespace rocketmq { + +class Message; +typedef std::shared_ptr MessagePtr; + +/** + * Message Interface + */ +class ROCKETMQCLIENT_API Message { + public: + virtual ~Message() = default; + + public: + // property + virtual const std::string& getProperty(const std::string& name) const = 0; + virtual void putProperty(const std::string& name, const std::string& value) = 0; + virtual void clearProperty(const std::string& name) = 0; + + // topic + virtual const std::string& getTopic() const = 0; + virtual void setTopic(const std::string& topic) = 0; + virtual void setTopic(const char* body, int len) = 0; + + // tags + virtual const std::string& getTags() const = 0; + virtual void setTags(const std::string& tags) = 0; + + // keys + virtual const std::string& getKeys() const = 0; + virtual void setKeys(const std::string& keys) = 0; + virtual void setKeys(const std::vector& keys) = 0; + + // delay time level + virtual int getDelayTimeLevel() const = 0; + virtual void setDelayTimeLevel(int level) = 0; + + // wait store message ok + virtual bool isWaitStoreMsgOK() const = 0; + virtual void setWaitStoreMsgOK(bool waitStoreMsgOK) = 0; + + // flag + virtual int32_t getFlag() const = 0; + virtual void setFlag(int32_t flag) = 0; + + // body + virtual const std::string& getBody() const = 0; + virtual void setBody(const char* body, int len) = 0; + virtual void setBody(const std::string& body) = 0; + virtual void setBody(std::string&& body) = 0; + + // transaction id + virtual const std::string& getTransactionId() const = 0; + virtual void setTransactionId(const std::string& transactionId) = 0; + + // properties + virtual const std::map& getProperties() const = 0; + virtual void setProperties(const std::map& properties) = 0; + virtual void setProperties(std::map&& properties) = 0; + + // batch flag + virtual bool isBatch() const { return false; } + + virtual std::string toString() const = 0; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_MESSAGE_H_ diff --git a/include/MessageExt.h b/include/MessageExt.h new file mode 100644 index 000000000..172aa9244 --- /dev/null +++ b/include/MessageExt.h @@ -0,0 +1,88 @@ +/* + * 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_MESSAGEEXT_H_ +#define ROCKETMQ_MESSAGEEXT_H_ + +#ifdef WIN32 +// clang-format off +#include +#include +// clang-format on +#else +#include +#endif + +#include "Message.h" + +namespace rocketmq { + +class MessageExt; +typedef std::shared_ptr MessageExtPtr; + +/** + * MessageExt - Message extend class, which was generated on broker + */ +class ROCKETMQCLIENT_API MessageExt : virtual public Message // base interface +{ + public: + virtual ~MessageExt() = default; + + virtual int32_t getStoreSize() const = 0; + virtual void setStoreSize(int32_t storeSize) = 0; + + virtual int32_t getBodyCRC() const = 0; + virtual void setBodyCRC(int32_t bodyCRC) = 0; + + virtual int32_t getQueueId() const = 0; + virtual void setQueueId(int32_t queueId) = 0; + + virtual int64_t getQueueOffset() const = 0; + virtual void setQueueOffset(int64_t queueOffset) = 0; + + virtual int64_t getCommitLogOffset() const = 0; + virtual void setCommitLogOffset(int64_t physicOffset) = 0; + + virtual int32_t getSysFlag() const = 0; + virtual void setSysFlag(int32_t sysFlag) = 0; + + virtual int64_t getBornTimestamp() const = 0; + virtual void setBornTimestamp(int64_t bornTimestamp) = 0; + + virtual std::string getBornHostString() const = 0; + virtual const struct sockaddr* getBornHost() const = 0; + virtual void setBornHost(const struct sockaddr* bornHost) = 0; + + virtual int64_t getStoreTimestamp() const = 0; + virtual void setStoreTimestamp(int64_t storeTimestamp) = 0; + + virtual std::string getStoreHostString() const = 0; + virtual const struct sockaddr* getStoreHost() const = 0; + virtual void setStoreHost(const struct sockaddr* storeHost) = 0; + + virtual int32_t getReconsumeTimes() const = 0; + virtual void setReconsumeTimes(int32_t reconsumeTimes) = 0; + + virtual int64_t getPreparedTransactionOffset() const = 0; + virtual void setPreparedTransactionOffset(int64_t preparedTransactionOffset) = 0; + + virtual const std::string& getMsgId() const = 0; + virtual void setMsgId(const std::string& msgId) = 0; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_MESSAGEEXT_H_ diff --git a/include/MessageUtil.h b/include/MessageUtil.h index ad6808a37..d44fd8fdc 100644 --- a/include/MessageUtil.h +++ b/include/MessageUtil.h @@ -14,10 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MESSAGE_UTIL_H__ -#define __MESSAGE_UTIL_H__ - -#include +#ifndef ROCKETMQ_MESSAGEUTIL_H_ +#define ROCKETMQ_MESSAGEUTIL_H_ #include "MQClientException.h" #include "MQMessage.h" @@ -26,12 +24,11 @@ namespace rocketmq { class ROCKETMQCLIENT_API MessageUtil { public: - static MQMessagePtr createReplyMessage(const MQMessagePtr requestMessage, - const std::string& body) throw(MQClientException); + static MQMessage createReplyMessage(const Message& requestMessage, const std::string& body) throw(MQClientException); - static const std::string& getReplyToClient(const MQMessagePtr msg); + static const std::string& getReplyToClient(const Message& msg); }; } // namespace rocketmq -#endif // __MESSAGE_UTIL_H__ +#endif // ROCKETMQ_MESSAGEUTIL_H_ diff --git a/include/QueryResult.h b/include/QueryResult.h index 958a499b1..1939fd33b 100644 --- a/include/QueryResult.h +++ b/include/QueryResult.h @@ -23,18 +23,18 @@ namespace rocketmq { class ROCKETMQCLIENT_API QueryResult { public: - QueryResult(uint64_t indexLastUpdateTimestamp, const std::vector& messageList) { + QueryResult(uint64_t indexLastUpdateTimestamp, const std::vector& messageList) { m_indexLastUpdateTimestamp = indexLastUpdateTimestamp; m_messageList = messageList; } uint64_t getIndexLastUpdateTimestamp() { return m_indexLastUpdateTimestamp; } - std::vector& getMessageList() { return m_messageList; } + std::vector& getMessageList() { return m_messageList; } private: uint64_t m_indexLastUpdateTimestamp; - std::vector m_messageList; + std::vector m_messageList; }; } // namespace rocketmq diff --git a/include/RequestCallback.h b/include/RequestCallback.h index 8b31098b9..d79e95594 100644 --- a/include/RequestCallback.h +++ b/include/RequestCallback.h @@ -28,10 +28,10 @@ class ROCKETMQCLIENT_API RequestCallback { public: virtual ~RequestCallback() = default; - virtual void onSuccess(MQMessagePtr3 message) { onSuccess(message.get()); } + virtual void onSuccess(MessagePtr message) { onSuccess(MQMessage(message)); } // SDK will be responsible for the lifecycle of message. - virtual void onSuccess(MQMessagePtr message) = 0; + virtual void onSuccess(MQMessage message) = 0; virtual void onException(MQException& e) noexcept = 0; diff --git a/include/RocketMQClient.h b/include/RocketMQClient.h index fc5bb6a92..d6247938f 100644 --- a/include/RocketMQClient.h +++ b/include/RocketMQClient.h @@ -14,10 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __ROCKETMQ_CLIENT_H__ -#define __ROCKETMQ_CLIENT_H__ +#ifndef ROCKETMQ_ROCKETMQCLIENT_H_ +#define ROCKETMQ_ROCKETMQCLIENT_H_ +#ifdef __cplusplus #include +#else +#include +#endif #ifdef WIN32 #ifdef ROCKETMQCLIENT_EXPORTS @@ -49,4 +53,4 @@ #define FILE_SEPARATOR "/" #endif -#endif // __ROCKETMQ_CLIENT_H__ +#endif // ROCKETMQ_ROCKETMQCLIENT_H_ diff --git a/include/TopicFilterType.h b/include/TopicFilterType.h index 9f57a4266..604334749 100644 --- a/include/TopicFilterType.h +++ b/include/TopicFilterType.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __TOPIC_FILTER_TYPE_H__ -#define __TOPIC_FILTER_TYPE_H__ +#ifndef ROCKETMQ_TOPICFILTERTYPE_H_ +#define ROCKETMQ_TOPICFILTERTYPE_H_ namespace rocketmq { @@ -24,6 +24,7 @@ enum TopicFilterType { * each msg could only have one tag */ SINGLE_TAG, + /** * not support now */ @@ -32,4 +33,4 @@ enum TopicFilterType { } // namespace rocketmq -#endif // __TOPIC_FILTER_TYPE_H__ +#endif // ROCKETMQ_TOPICFILTERTYPE_H_ diff --git a/include/TransactionMQProducer.h b/include/TransactionMQProducer.h index 0a1380fcb..4efe26df1 100644 --- a/include/TransactionMQProducer.h +++ b/include/TransactionMQProducer.h @@ -37,7 +37,7 @@ class ROCKETMQCLIENT_API TransactionMQProducer : public DefaultMQProducer, virtu void shutdown() override; // Transaction: don't delete msg object, until callback occur. - TransactionSendResult sendMessageInTransaction(MQMessagePtr msg, void* arg) override; + TransactionSendResult sendMessageInTransaction(MQMessage& msg, void* arg) override; }; } // namespace rocketmq diff --git a/src/ClientRemotingProcessor.cpp b/src/ClientRemotingProcessor.cpp index 4f8d8a410..97286a17a 100644 --- a/src/ClientRemotingProcessor.cpp +++ b/src/ClientRemotingProcessor.cpp @@ -17,7 +17,7 @@ #include "ClientRemotingProcessor.h" #include "ConsumerRunningInfo.h" -#include "MQDecoder.h" +#include "MessageDecoder.h" #include "MQProtos.h" #include "MessageAccessor.h" #include "MessageSysFlag.h" @@ -65,7 +65,7 @@ RemotingCommand* ClientRemotingProcessor::checkTransactionState(const std::strin auto requestBody = request->getBody(); if (requestBody != nullptr && requestBody->getSize() > 0) { - MQMessageExtPtr2 messageExt = MQDecoder::decode(*requestBody); + MessageExtPtr messageExt = MessageDecoder::decode(*requestBody); if (messageExt != nullptr) { const auto& transactionId = messageExt->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX); if (!transactionId.empty()) { @@ -173,7 +173,7 @@ RemotingCommand* ClientRemotingProcessor::receiveReplyMessage(RemotingCommand* r } msg->setFlag(requestHeader->getFlag()); - MessageAccessor::setProperties(*msg, MQDecoder::string2messageProperties(requestHeader->getProperties())); + MessageAccessor::setProperties(*msg, MessageDecoder::string2messageProperties(requestHeader->getProperties())); MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_REPLY_MESSAGE_ARRIVE_TIME, UtilAll::to_string(receiveTime)); msg->setBornTimestamp(requestHeader->getBornTimestamp()); diff --git a/src/MQAdminImpl.cpp b/src/MQAdminImpl.cpp index be67fce31..5f334a2d9 100644 --- a/src/MQAdminImpl.cpp +++ b/src/MQAdminImpl.cpp @@ -115,9 +115,9 @@ int64_t MQAdminImpl::earliestMsgStoreTime(const MQMessageQueue& mq) { THROW_MQEXCEPTION(MQClientException, "The broker is not exist", -1); } -MQMessageExtPtr MQAdminImpl::viewMessage(const std::string& msgId) { +MQMessageExt MQAdminImpl::viewMessage(const std::string& msgId) { try { - return nullptr; + return MQMessageExt(nullptr); } catch (MQException& e) { THROW_MQEXCEPTION(MQClientException, "message id illegal", -1); } diff --git a/src/MQAdminImpl.h b/src/MQAdminImpl.h index ee3d18d05..27949c77a 100644 --- a/src/MQAdminImpl.h +++ b/src/MQAdminImpl.h @@ -40,7 +40,7 @@ class MQAdminImpl { int64_t minOffset(const MQMessageQueue& mq); int64_t earliestMsgStoreTime(const MQMessageQueue& mq); - MQMessageExtPtr viewMessage(const std::string& msgId); + MQMessageExt viewMessage(const std::string& msgId); QueryResult queryMessage(const std::string& topic, const std::string& key, int maxNum, int64_t begin, int64_t end); private: diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index 23fea6a18..1dcc163b9 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -87,7 +87,7 @@ void MQClientAPIImpl::createTopic(const std::string& addr, const std::string& de SendResult* MQClientAPIImpl::sendMessage(const std::string& addr, const std::string& brokerName, - const MQMessagePtr msg, + const MessagePtr msg, std::unique_ptr requestHeader, int timeoutMillis, CommunicationMode communicationMode, @@ -98,7 +98,7 @@ SendResult* MQClientAPIImpl::sendMessage(const std::string& addr, SendResult* MQClientAPIImpl::sendMessage(const std::string& addr, const std::string& brokerName, - const MQMessagePtr msg, + const MessagePtr msg, std::unique_ptr requestHeader, int timeoutMillis, CommunicationMode communicationMode, @@ -149,7 +149,7 @@ SendResult* MQClientAPIImpl::sendMessage(const std::string& addr, void MQClientAPIImpl::sendMessageAsync(const std::string& addr, const std::string& brokerName, - const MQMessagePtr msg, + const MessagePtr msg, RemotingCommand&& request, SendCallback* sendCallback, TopicPublishInfoPtr topicPublishInfo, @@ -177,7 +177,7 @@ void MQClientAPIImpl::sendMessageAsyncImpl(SendCallbackWrap* cbw, int64_t timeou SendResult* MQClientAPIImpl::sendMessageSync(const std::string& addr, const std::string& brokerName, - const MQMessagePtr msg, + const MessagePtr msg, RemotingCommand& request, int timeoutMillis) { // block until response @@ -187,7 +187,7 @@ SendResult* MQClientAPIImpl::sendMessageSync(const std::string& addr, } SendResult* MQClientAPIImpl::processSendResponse(const std::string& brokerName, - const MQMessagePtr msg, + const MessagePtr msg, RemotingCommand* response) { SendStatus sendStatus = SEND_OK; switch (response->getCode()) { @@ -217,11 +217,11 @@ SendResult* MQClientAPIImpl::processSendResponse(const std::string& brokerName, // MessageBatch if (msg->isBatch()) { - const auto& messages = static_cast(msg)->getMessages(); + const auto& messages = std::dynamic_pointer_cast(msg)->getMessages(); uniqMsgId.clear(); uniqMsgId.reserve(33 * messages.size() + 1); for (const auto& message : messages) { - uniqMsgId.append(MessageClientIDSetter::getUniqID(*message)); + uniqMsgId.append(MessageClientIDSetter::getUniqID(message)); uniqMsgId.append(","); } if (!uniqMsgId.empty()) { @@ -307,7 +307,7 @@ PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* response) { responseHeader->maxOffset, (int)responseHeader->suggestWhichBrokerId, response->getBody()); } -MQMessageExtPtr MQClientAPIImpl::viewMessage(const std::string& addr, int64_t phyoffset, int timeoutMillis) { +MQMessageExt MQClientAPIImpl::viewMessage(const std::string& addr, int64_t phyoffset, int timeoutMillis) { auto* requestHeader = new ViewMessageRequestHeader(); requestHeader->offset = phyoffset; @@ -552,17 +552,17 @@ void MQClientAPIImpl::endTransactionOneway(const std::string& addr, } void MQClientAPIImpl::consumerSendMessageBack(const std::string& addr, - MQMessageExt& msg, + MessageExtPtr msg, const std::string& consumerGroup, int delayLevel, int timeoutMillis, int maxConsumeRetryTimes) { auto* requestHeader = new ConsumerSendMsgBackRequestHeader(); requestHeader->group = consumerGroup; - requestHeader->originTopic = msg.getTopic(); - requestHeader->offset = msg.getCommitLogOffset(); + requestHeader->originTopic = msg->getTopic(); + requestHeader->offset = msg->getCommitLogOffset(); requestHeader->delayLevel = delayLevel; - requestHeader->originMsgId = msg.getMsgId(); + requestHeader->originMsgId = msg->getMsgId(); requestHeader->maxReconsumeTimes = maxConsumeRetryTimes; RemotingCommand request(CONSUMER_SEND_MSG_BACK, requestHeader); diff --git a/src/MQClientAPIImpl.h b/src/MQClientAPIImpl.h index b2f94fa7a..dcf8da9c4 100644 --- a/src/MQClientAPIImpl.h +++ b/src/MQClientAPIImpl.h @@ -60,14 +60,14 @@ class MQClientAPIImpl { SendResult* sendMessage(const std::string& addr, const std::string& brokerName, - const MQMessagePtr msg, + const MessagePtr msg, std::unique_ptr requestHeader, int timeoutMillis, CommunicationMode communicationMode, DefaultMQProducerImplPtr producer); SendResult* sendMessage(const std::string& addr, const std::string& brokerName, - const MQMessagePtr msg, + const MessagePtr msg, std::unique_ptr requestHeader, int timeoutMillis, CommunicationMode communicationMode, @@ -76,7 +76,7 @@ class MQClientAPIImpl { MQClientInstancePtr instance, int retryTimesWhenSendFailed, DefaultMQProducerImplPtr producer); - SendResult* processSendResponse(const std::string& brokerName, const MQMessagePtr msg, RemotingCommand* pResponse); + SendResult* processSendResponse(const std::string& brokerName, const MessagePtr msg, RemotingCommand* pResponse); PullResult* pullMessage(const std::string& addr, PullMessageRequestHeader* requestHeader, @@ -85,7 +85,7 @@ class MQClientAPIImpl { PullCallback* pullCallback); PullResult* processPullResponse(RemotingCommand* pResponse); - MQMessageExtPtr viewMessage(const std::string& addr, int64_t phyoffset, int timeoutMillis); + MQMessageExt viewMessage(const std::string& addr, int64_t phyoffset, int timeoutMillis); int64_t searchOffset(const std::string& addr, const std::string& topic, @@ -125,7 +125,7 @@ class MQClientAPIImpl { const std::string& remark); void consumerSendMessageBack(const std::string& addr, - MQMessageExt& msg, + MessageExtPtr msg, const std::string& consumerGroup, int delayLevel, int timeoutMillis, @@ -166,13 +166,13 @@ class MQClientAPIImpl { SendResult* sendMessageSync(const std::string& addr, const std::string& brokerName, - const MQMessagePtr msg, + const MessagePtr msg, RemotingCommand& request, int timeoutMillis); void sendMessageAsync(const std::string& addr, const std::string& brokerName, - const MQMessagePtr msg, + const MessagePtr msg, RemotingCommand&& request, SendCallback* sendCallback, TopicPublishInfoPtr topicPublishInfo, diff --git a/src/MQClientImpl.cpp b/src/MQClientImpl.cpp index 58376b54d..83b110cd6 100644 --- a/src/MQClientImpl.cpp +++ b/src/MQClientImpl.cpp @@ -71,7 +71,7 @@ int64_t MQClientImpl::earliestMsgStoreTime(const MQMessageQueue& mq) { return m_clientInstance->getMQAdminImpl()->earliestMsgStoreTime(mq); } -MQMessageExtPtr MQClientImpl::viewMessage(const std::string& msgId) { +MQMessageExt MQClientImpl::viewMessage(const std::string& msgId) { return m_clientInstance->getMQAdminImpl()->viewMessage(msgId); } diff --git a/src/MQClientImpl.h b/src/MQClientImpl.h index 3b689bdb5..08078189c 100644 --- a/src/MQClientImpl.h +++ b/src/MQClientImpl.h @@ -35,7 +35,7 @@ class MQClientImpl : public MQAdmin { int64_t maxOffset(const MQMessageQueue& mq) override; int64_t minOffset(const MQMessageQueue& mq) override; int64_t earliestMsgStoreTime(const MQMessageQueue& mq) override; - MQMessageExtPtr viewMessage(const std::string& offsetMsgId) override; + MQMessageExt viewMessage(const std::string& offsetMsgId) override; QueryResult queryMessage(const std::string& topic, const std::string& key, int maxNum, diff --git a/src/common/ByteOrder.h b/src/common/ByteOrder.h index 1d4d7a2a5..cdc52a9e3 100644 --- a/src/common/ByteOrder.h +++ b/src/common/ByteOrder.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __BYTE_ORDER_H__ -#define __BYTE_ORDER_H__ +#ifndef ROCKETMQ_COMMON_BYTEORDER_H_ +#define ROCKETMQ_COMMON_BYTEORDER_H_ #include @@ -24,9 +24,10 @@ namespace rocketmq { /** * Contains static methods for converting the byte order between different endiannesses. */ -class ROCKETMQCLIENT_API ByteOrder { +class ByteOrder { public: //============================================================================== + /** Swaps the upper and lower bytes of a 16-bit integer. */ static uint16_t swap(uint16_t value); @@ -37,6 +38,7 @@ class ROCKETMQCLIENT_API ByteOrder { static uint64_t swap(uint64_t value); //============================================================================== + /** Swaps the byte order of a 16-bit int if the CPU is big-endian */ static uint16_t swapIfBigEndian(uint16_t value); @@ -56,6 +58,7 @@ class ROCKETMQCLIENT_API ByteOrder { static uint64_t swapIfLittleEndian(uint64_t value); //============================================================================== + /** Turns 4 bytes into a little-endian integer. */ static uint32_t littleEndianInt(const void* bytes); @@ -75,6 +78,7 @@ class ROCKETMQCLIENT_API ByteOrder { static uint16_t 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); @@ -90,6 +94,7 @@ class ROCKETMQCLIENT_API ByteOrder { static void bigEndian24BitToChars(int value, void* destBytes); //============================================================================== + /** Returns true if the current CPU is big-endian. */ static bool isBigEndian(); }; @@ -109,6 +114,7 @@ inline uint64_t ByteOrder::swap(uint64_t value) { } #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ //__BYTE_ORDER__ is defined by GCC + inline uint16_t ByteOrder::swapIfBigEndian(const uint16_t v) { return v; } @@ -160,7 +166,9 @@ inline uint16_t ByteOrder::bigEndianShort(const void* const bytes) { inline bool ByteOrder::isBigEndian() { return false; } -#else + +#else // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + inline uint16_t ByteOrder::swapIfBigEndian(const uint16_t v) { return swap(v); } @@ -212,7 +220,8 @@ inline uint16_t ByteOrder::bigEndianShort(const void* const bytes) { inline bool ByteOrder::isBigEndian() { return true; } -#endif + +#endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ inline int ByteOrder::littleEndian24Bit(const void* const bytes) { return (((int)static_cast(bytes)[2]) << 16) | (((int)static_cast(bytes)[1]) << 8) | @@ -238,4 +247,4 @@ inline void ByteOrder::bigEndian24BitToChars(const int value, void* const destBy } // namespace rocketmq -#endif // __BYTE_ORDER_H__ +#endif // ROCKETMQ_COMMON_BYTEORDER_H_ diff --git a/src/common/MessageSysFlag.cpp b/src/common/MessageSysFlag.cpp index 6c980b048..a61d36c0f 100644 --- a/src/common/MessageSysFlag.cpp +++ b/src/common/MessageSysFlag.cpp @@ -26,6 +26,9 @@ const int MessageSysFlag::TransactionPreparedType = 0x1 << 2; const int MessageSysFlag::TransactionCommitType = 0x2 << 2; const int MessageSysFlag::TransactionRollbackType = 0x3 << 2; +const int MessageSysFlag::BronhostV6Flag = 0x1 << 4; +const int MessageSysFlag::StorehostV6Flag = 0x1 << 5; + int MessageSysFlag::getTransactionValue(int flag) { return flag & TransactionRollbackType; } diff --git a/src/common/MessageSysFlag.h b/src/common/MessageSysFlag.h index a5e8852b9..8c61579c6 100644 --- a/src/common/MessageSysFlag.h +++ b/src/common/MessageSysFlag.h @@ -34,6 +34,9 @@ class MessageSysFlag { static const int TransactionPreparedType; static const int TransactionCommitType; static const int TransactionRollbackType; + + static const int BronhostV6Flag; + static const int StorehostV6Flag; }; } // namespace rocketmq diff --git a/src/common/SendCallbackWrap.cpp b/src/common/SendCallbackWrap.cpp index 4df888365..698fe5673 100755 --- a/src/common/SendCallbackWrap.cpp +++ b/src/common/SendCallbackWrap.cpp @@ -22,7 +22,7 @@ #include "Logging.h" #include "MQClientAPIImpl.h" #include "MQClientInstance.h" -#include "MQDecoder.h" +#include "MessageDecoder.h" #include "MQMessageQueue.h" #include "MQProtos.h" #include "PullAPIWrapper.h" @@ -34,7 +34,7 @@ namespace rocketmq { SendCallbackWrap::SendCallbackWrap(const std::string& addr, const std::string& brokerName, - const MQMessagePtr msg, + const MessagePtr msg, RemotingCommand&& request, SendCallback* sendCallback, TopicPublishInfoPtr topicPublishInfo, diff --git a/src/common/SendCallbackWrap.h b/src/common/SendCallbackWrap.h index a969f7527..2ef8ffa34 100755 --- a/src/common/SendCallbackWrap.h +++ b/src/common/SendCallbackWrap.h @@ -22,7 +22,7 @@ #include "DefaultMQProducerImpl.h" #include "InvokeCallback.h" #include "MQClientInstance.h" -#include "MQMessage.h" +#include "Message.h" #include "RemotingCommand.h" #include "ResponseFuture.h" #include "SendCallback.h" @@ -34,7 +34,7 @@ class SendCallbackWrap : public InvokeCallback { public: SendCallbackWrap(const std::string& addr, const std::string& brokerName, - const MQMessagePtr msg, + const MessagePtr msg, RemotingCommand&& request, SendCallback* sendCallback, TopicPublishInfoPtr topicPublishInfo, @@ -47,7 +47,7 @@ class SendCallbackWrap : public InvokeCallback { void onExceptionImpl(ResponseFuture* responseFuture, long timeoutMillis, MQException& e, bool needRetry); const std::string& getAddr() { return m_addr; } - const MQMessagePtr getMessage() { return m_msg; } + const MessagePtr getMessage() { return m_msg; } RemotingCommand& getRemotingCommand() { return m_request; } void setRetrySendTimes(int retrySendTimes) { m_times = retrySendTimes; } @@ -57,7 +57,7 @@ class SendCallbackWrap : public InvokeCallback { private: std::string m_addr; std::string m_brokerName; - const MQMessagePtr m_msg; + const MessagePtr m_msg; RemotingCommand m_request; SendCallback* m_sendCallback; TopicPublishInfoPtr m_topicPublishInfo; diff --git a/src/common/UtilAll.cpp b/src/common/UtilAll.cpp index 4333ecdae..7f2dbb281 100644 --- a/src/common/UtilAll.cpp +++ b/src/common/UtilAll.cpp @@ -68,44 +68,54 @@ int32_t UtilAll::HashCode(const std::string& str) { return h; } -static 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_t UtilAll::hexstr2ull(const char* str) { - uint64_t num = 0; - unsigned char* ch = (unsigned char*)str; - while (*ch != '\0') { - num = (num << 4) + hex2int[*ch]; - ch++; - } - return num; -} - -static const char sHexAlphabet[] = "0123456789ABCDEF"; +static const char kHexAlphabet[] = "0123456789ABCDEF"; std::string UtilAll::bytes2string(const char* bytes, size_t len) { if (bytes == nullptr || len <= 0) { - return std::string(); + return null; } std::string buffer; buffer.reserve(len * 2 + 1); for (std::size_t i = 0; i < len; i++) { - unsigned char v = (unsigned char)bytes[i]; - buffer.append(1, sHexAlphabet[v >> 4]); - buffer.append(1, sHexAlphabet[v & 0x0FU]); + uint8_t v = (uint8_t)bytes[i]; + buffer.append(1, kHexAlphabet[v >> 4]); + buffer.append(1, kHexAlphabet[v & 0x0FU]); } return buffer; } +// clang-format off +static const uint8_t kHexIndex[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, + 0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +// clang-format on + +void UtilAll::string2bytes(char* dest, const std::string& src) { + if (dest == nullptr || src.empty()) { + return; + } + for (size_t i = 0; i < src.size() / 2; i++) { + size_t pos = i * 2; + dest[i] = kHexIndex[(uint8_t)src[pos]] << 4 | kHexIndex[(uint8_t)src[pos + 1]]; + } +} + bool UtilAll::isRetryTopic(const std::string& topic) { return topic.find(RETRY_GROUP_TOPIC_PREFIX) == 0; } diff --git a/src/common/UtilAll.h b/src/common/UtilAll.h index 2e2c34f0e..a919db724 100644 --- a/src/common/UtilAll.h +++ b/src/common/UtilAll.h @@ -93,9 +93,8 @@ class UtilAll { static int32_t HashCode(const std::string& str); - static uint64_t hexstr2ull(const char* str); - static std::string bytes2string(const char* bytes, size_t len); + static void string2bytes(char* dest, const std::string& src); static bool isRetryTopic(const std::string& topic); static std::string getRetryTopic(const std::string& consumerGroup); diff --git a/src/common/Validators.cpp b/src/common/Validators.cpp index c293aa4ea..4cd843e6f 100644 --- a/src/common/Validators.cpp +++ b/src/common/Validators.cpp @@ -95,7 +95,7 @@ void Validators::checkGroup(const std::string& group) { } } -void Validators::checkMessage(const MQMessage& msg, int maxMessageSize) { +void Validators::checkMessage(const Message& msg, int maxMessageSize) { checkTopic(msg.getTopic()); const auto& body = msg.getBody(); diff --git a/src/common/Validators.h b/src/common/Validators.h index e5a60935e..3ffe52773 100644 --- a/src/common/Validators.h +++ b/src/common/Validators.h @@ -20,7 +20,7 @@ #include #include "MQClientException.h" -#include "MQMessage.h" +#include "Message.h" #include "UtilAll.h" namespace rocketmq { @@ -31,7 +31,7 @@ class Validators { static std::string getGroupWithRegularExpression(const std::string& origin, const std::string& patternStr); static void checkTopic(const std::string& topic); static void checkGroup(const std::string& group); - static void checkMessage(const MQMessage& msg, int maxMessageSize); + static void checkMessage(const Message& msg, int maxMessageSize); public: static const std::string validPatternStr; diff --git a/src/consumer/ConsumeMessageConcurrentlyService.cpp b/src/consumer/ConsumeMessageConcurrentlyService.cpp index 26063e574..42cde1263 100755 --- a/src/consumer/ConsumeMessageConcurrentlyService.cpp +++ b/src/consumer/ConsumeMessageConcurrentlyService.cpp @@ -43,7 +43,7 @@ void ConsumeMessageConcurrentlyService::shutdown() { m_consumeExecutor.shutdown(); } -void ConsumeMessageConcurrentlyService::submitConsumeRequest(std::vector& msgs, +void ConsumeMessageConcurrentlyService::submitConsumeRequest(std::vector& msgs, ProcessQueuePtr processQueue, const MQMessageQueue& messageQueue, const bool dispathToConsume) { @@ -51,7 +51,7 @@ void ConsumeMessageConcurrentlyService::submitConsumeRequest(std::vector& msgs, +void ConsumeMessageConcurrentlyService::submitConsumeRequestLater(std::vector& msgs, ProcessQueuePtr processQueue, const MQMessageQueue& messageQueue) { m_scheduledExecutorService.schedule( @@ -59,7 +59,7 @@ void ConsumeMessageConcurrentlyService::submitConsumeRequestLater(std::vector& msgs, +void ConsumeMessageConcurrentlyService::ConsumeRequest(std::vector& msgs, ProcessQueuePtr processQueue, const MQMessageQueue& messageQueue) { if (processQueue->isDropped()) { @@ -83,11 +83,16 @@ void ConsumeMessageConcurrentlyService::ConsumeRequest(std::vectorsetLastConsumeTimestamp(consumeTimestamp); if (!msgs.empty()) { auto timestamp = UtilAll::to_string(consumeTimestamp); - for (auto& msg : msgs) { + for (const auto& msg : msgs) { MessageAccessor::setConsumeStartTimeStamp(*msg, timestamp); } } - status = m_messageListener->consumeMessage(msgs); + std::vector message_list; + message_list.reserve(msgs.size()); + for (const auto& msg : msgs) { + message_list.emplace_back(msg); + } + status = m_messageListener->consumeMessage(message_list); } catch (const std::exception& e) { LOG_WARN_NEW("encounter unexpected exception when consume messages.\n{}", e.what()); } @@ -122,13 +127,13 @@ void ConsumeMessageConcurrentlyService::ConsumeRequest(std::vector msgBackFailed; + std::vector msgBackFailed; int idx = ackIndex + 1; for (auto iter = msgs.begin() + idx; iter != msgs.end(); idx++) { LOG_WARN_NEW("consume fail, MQ is:{}, its msgId is:{}, index is:{}, reconsume times is:{}", messageQueue.toString(), (*iter)->getMsgId(), idx, (*iter)->getReconsumeTimes()); auto& msg = (*iter); - bool result = m_consumer->sendMessageBack(*msg, 0, messageQueue.getBrokerName()); + bool result = m_consumer->sendMessageBack(msg, 0, messageQueue.getBrokerName()); if (!result) { msg->setReconsumeTimes(msg->getReconsumeTimes() + 1); msgBackFailed.push_back(msg); diff --git a/src/consumer/ConsumeMessageOrderlyService.cpp b/src/consumer/ConsumeMessageOrderlyService.cpp index 9411666d0..ec6c3ff1b 100755 --- a/src/consumer/ConsumeMessageOrderlyService.cpp +++ b/src/consumer/ConsumeMessageOrderlyService.cpp @@ -67,7 +67,7 @@ bool ConsumeMessageOrderlyService::lockOneMQ(const MQMessageQueue& mq) { return m_consumer->getRebalanceImpl()->lock(mq); } -void ConsumeMessageOrderlyService::submitConsumeRequest(std::vector& msgs, +void ConsumeMessageOrderlyService::submitConsumeRequest(std::vector& msgs, ProcessQueuePtr processQueue, const MQMessageQueue& messageQueue, const bool dispathToConsume) { @@ -87,7 +87,7 @@ void ConsumeMessageOrderlyService::submitConsumeRequestLater(ProcessQueuePtr pro timeMillis = std::max(10L, std::min(timeMillis, 30000L)); - static std::vector dummy; + static std::vector dummy; m_scheduledExecutorService.schedule(std::bind(&ConsumeMessageOrderlyService::submitConsumeRequest, this, std::ref(dummy), processQueue, messageQueue, true), timeMillis, time_unit::milliseconds); @@ -145,7 +145,7 @@ void ConsumeMessageOrderlyService::ConsumeRequest(ProcessQueuePtr processQueue, const int consumeBatchSize = m_consumer->getDefaultMQPushConsumerConfig()->getConsumeMessageBatchMaxSize(); - std::vector msgs; + std::vector msgs; processQueue->takeMessages(msgs, consumeBatchSize); m_consumer->resetRetryTopic(msgs, m_consumer->getDefaultMQPushConsumerConfig()->getGroupName()); if (!msgs.empty()) { @@ -157,8 +157,12 @@ void ConsumeMessageOrderlyService::ConsumeRequest(ProcessQueuePtr processQueue, messageQueue.toString()); break; } - - status = m_messageListener->consumeMessage(msgs); + std::vector message_list; + message_list.reserve(msgs.size()); + for (const auto& msg : msgs) { + message_list.emplace_back(msg); + } + status = m_messageListener->consumeMessage(message_list); } catch (const std::exception& e) { LOG_WARN_NEW("encounter unexpected exception when consume messages.\n{}", e.what()); } diff --git a/src/consumer/ConsumeMsgService.h b/src/consumer/ConsumeMsgService.h index c854d76cf..b8e1d8aea 100755 --- a/src/consumer/ConsumeMsgService.h +++ b/src/consumer/ConsumeMsgService.h @@ -33,7 +33,7 @@ class ConsumeMsgService { virtual void start() {} virtual void shutdown() {} - virtual void submitConsumeRequest(std::vector& msgs, + virtual void submitConsumeRequest(std::vector& msgs, ProcessQueuePtr processQueue, const MQMessageQueue& messageQueue, const bool dispathToConsume) = 0; @@ -47,17 +47,17 @@ class ConsumeMessageConcurrentlyService : public ConsumeMsgService { void start() override; void shutdown() override; - void submitConsumeRequest(std::vector& msgs, + void submitConsumeRequest(std::vector& msgs, ProcessQueuePtr processQueue, const MQMessageQueue& messageQueue, const bool dispathToConsume) override; - void ConsumeRequest(std::vector& msgs, + void ConsumeRequest(std::vector& msgs, ProcessQueuePtr processQueue, const MQMessageQueue& messageQueue); private: - void submitConsumeRequestLater(std::vector& msgs, + void submitConsumeRequestLater(std::vector& msgs, ProcessQueuePtr processQueue, const MQMessageQueue& messageQueue); @@ -78,7 +78,7 @@ class ConsumeMessageOrderlyService : public ConsumeMsgService { void shutdown() override; void stopThreadPool(); - void submitConsumeRequest(std::vector& msgs, + void submitConsumeRequest(std::vector& msgs, ProcessQueuePtr processQueue, const MQMessageQueue& messageQueue, const bool dispathToConsume) override; diff --git a/src/consumer/DefaultMQPullConsumer.cpp b/src/consumer/DefaultMQPullConsumer.cpp index 4512a381c..66d324e9e 100644 --- a/src/consumer/DefaultMQPullConsumer.cpp +++ b/src/consumer/DefaultMQPullConsumer.cpp @@ -45,11 +45,11 @@ void DefaultMQPullConsumer::shutdown() { m_pullConsumerDelegate->shutdown(); } -bool DefaultMQPullConsumer::sendMessageBack(MQMessageExt& msg, int delayLevel) { +bool DefaultMQPullConsumer::sendMessageBack(MessageExtPtr msg, int delayLevel) { return m_pullConsumerDelegate->sendMessageBack(msg, delayLevel); } -bool DefaultMQPullConsumer::sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) { +bool DefaultMQPullConsumer::sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) { return m_pullConsumerDelegate->sendMessageBack(msg, delayLevel, brokerName); } diff --git a/src/consumer/DefaultMQPushConsumer.cpp b/src/consumer/DefaultMQPushConsumer.cpp index 0d717fd9e..4ef9b36e7 100644 --- a/src/consumer/DefaultMQPushConsumer.cpp +++ b/src/consumer/DefaultMQPushConsumer.cpp @@ -48,11 +48,11 @@ void DefaultMQPushConsumer::shutdown() { m_pushConsumerDelegate->shutdown(); } -bool DefaultMQPushConsumer::sendMessageBack(MQMessageExt& msg, int delayLevel) { +bool DefaultMQPushConsumer::sendMessageBack(MessageExtPtr msg, int delayLevel) { return m_pushConsumerDelegate->sendMessageBack(msg, delayLevel); } -bool DefaultMQPushConsumer::sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) { +bool DefaultMQPushConsumer::sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) { return m_pushConsumerDelegate->sendMessageBack(msg, delayLevel, brokerName); } diff --git a/src/consumer/DefaultMQPushConsumerImpl.cpp b/src/consumer/DefaultMQPushConsumerImpl.cpp index 40630f3f3..800b4c78c 100644 --- a/src/consumer/DefaultMQPushConsumerImpl.cpp +++ b/src/consumer/DefaultMQPushConsumerImpl.cpp @@ -63,39 +63,39 @@ class AsyncPullCallback : public AutoDeletePullCallback { PullResult result = defaultMQPushConsumer->getPullAPIWrapper()->processPullResult(m_pullRequest->getMessageQueue(), pullResult, m_subscriptionData); - switch (result.pullStatus) { + switch (result.pull_status()) { case FOUND: { int64_t prevRequestOffset = m_pullRequest->getNextOffset(); - m_pullRequest->setNextOffset(result.nextBeginOffset); + m_pullRequest->setNextOffset(result.next_begin_offset()); int64_t firstMsgOffset = (std::numeric_limits::max)(); - if (result.msgFoundList.empty()) { + if (result.msg_found_list().empty()) { defaultMQPushConsumer->executePullRequestImmediately(m_pullRequest); } else { - firstMsgOffset = (*result.msgFoundList.begin())->getQueueOffset(); + firstMsgOffset = result.msg_found_list()[0]->getQueueOffset(); - m_pullRequest->getProcessQueue()->putMessage(result.msgFoundList); + m_pullRequest->getProcessQueue()->putMessage(result.msg_found_list()); defaultMQPushConsumer->getConsumerMsgService()->submitConsumeRequest( - result.msgFoundList, m_pullRequest->getProcessQueue(), m_pullRequest->getMessageQueue(), true); + result.msg_found_list(), m_pullRequest->getProcessQueue(), m_pullRequest->getMessageQueue(), true); defaultMQPushConsumer->executePullRequestImmediately(m_pullRequest); } - if (result.nextBeginOffset < prevRequestOffset || firstMsgOffset < prevRequestOffset) { + if (result.next_begin_offset() < prevRequestOffset || firstMsgOffset < prevRequestOffset) { LOG_WARN_NEW( "[BUG] pull message result maybe data wrong, nextBeginOffset:{} firstMsgOffset:{} prevRequestOffset:{}", - result.nextBeginOffset, firstMsgOffset, prevRequestOffset); + result.next_begin_offset(), firstMsgOffset, prevRequestOffset); } } break; case NO_NEW_MSG: case NO_MATCHED_MSG: - m_pullRequest->setNextOffset(result.nextBeginOffset); + m_pullRequest->setNextOffset(result.next_begin_offset()); defaultMQPushConsumer->correctTagsOffset(m_pullRequest); defaultMQPushConsumer->executePullRequestImmediately(m_pullRequest); break; case NO_LATEST_MSG: - m_pullRequest->setNextOffset(result.nextBeginOffset); + m_pullRequest->setNextOffset(result.next_begin_offset()); defaultMQPushConsumer->correctTagsOffset(m_pullRequest); defaultMQPushConsumer->executePullRequestLater( m_pullRequest, @@ -104,7 +104,7 @@ class AsyncPullCallback : public AutoDeletePullCallback { case OFFSET_ILLEGAL: { LOG_WARN_NEW("the pull request offset illegal, {} {}", m_pullRequest->toString(), result.toString()); - m_pullRequest->setNextOffset(result.nextBeginOffset); + m_pullRequest->setNextOffset(result.next_begin_offset()); m_pullRequest->getProcessQueue()->setDropped(true); // update and persist offset, then removeProcessQueue @@ -177,13 +177,13 @@ int DefaultMQPushConsumerImpl::getMaxReconsumeTimes() { } } -bool DefaultMQPushConsumerImpl::sendMessageBack(MQMessageExt& msg, int delayLevel) { +bool DefaultMQPushConsumerImpl::sendMessageBack(MessageExtPtr msg, int delayLevel) { return sendMessageBack(msg, delayLevel, null); } -bool DefaultMQPushConsumerImpl::sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) { +bool DefaultMQPushConsumerImpl::sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) { try { - std::string brokerAddr = brokerName.empty() ? socketAddress2String(msg.getStoreHost()) + std::string brokerAddr = brokerName.empty() ? socketAddress2String(msg->getStoreHost()) : m_clientInstance->findBrokerAddressInPublish(brokerName); m_clientInstance->getMQClientAPIImpl()->consumerSendMessageBack( @@ -191,7 +191,7 @@ bool DefaultMQPushConsumerImpl::sendMessageBack(MQMessageExt& msg, int delayLeve return true; } catch (const std::exception& e) { LOG_ERROR_NEW("sendMessageBack exception, group: {}, msg: {}. {}", m_pushConsumerConfig->getGroupName(), - msg.toString(), e.what()); + msg->toString(), e.what()); } return false; } @@ -293,9 +293,8 @@ void DefaultMQPushConsumerImpl::start() { if (!registerOK) { m_serviceState = CREATE_JUST; m_consumeService->shutdown(); - THROW_MQEXCEPTION(MQClientException, - "The cousumer group[" + m_pushConsumerConfig->getGroupName() + - "] has been created before, specify another name please.", + THROW_MQEXCEPTION(MQClientException, "The cousumer group[" + m_pushConsumerConfig->getGroupName() + + "] has been created before, specify another name please.", -1); } @@ -575,7 +574,8 @@ void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pullRequest) { } } -void DefaultMQPushConsumerImpl::resetRetryTopic(std::vector& msgs, const std::string& consumerGroup) { +void DefaultMQPushConsumerImpl::resetRetryTopic(const std::vector& msgs, + const std::string& consumerGroup) { std::string groupTopic = UtilAll::getRetryTopic(consumerGroup); for (auto& msg : msgs) { std::string retryTopic = msg->getProperty(MQMessageConst::PROPERTY_RETRY_TOPIC); diff --git a/src/consumer/DefaultMQPushConsumerImpl.h b/src/consumer/DefaultMQPushConsumerImpl.h index 67f03efb9..95563a251 100755 --- a/src/consumer/DefaultMQPushConsumerImpl.h +++ b/src/consumer/DefaultMQPushConsumerImpl.h @@ -64,8 +64,8 @@ class DefaultMQPushConsumerImpl : public std::enable_shared_from_this& mqs) override; public: // MQPushConsumer @@ -105,7 +105,7 @@ class DefaultMQPushConsumerImpl : public std::enable_shared_from_this& msgs, const std::string& consumerGroup); + void resetRetryTopic(const std::vector& msgs, const std::string& consumerGroup); public: bool isConsumeOrderly() { return m_consumeOrderly; } diff --git a/src/consumer/ProcessQueue.cpp b/src/consumer/ProcessQueue.cpp index 53554486c..285caed4d 100644 --- a/src/consumer/ProcessQueue.cpp +++ b/src/consumer/ProcessQueue.cpp @@ -47,7 +47,7 @@ bool ProcessQueue::isPullExpired() const { return (UtilAll::currentTimeMillis() - m_lastPullTimestamp) > PullMaxIdleTime; } -void ProcessQueue::putMessage(std::vector& msgs) { +void ProcessQueue::putMessage(const std::vector& msgs) { std::lock_guard lock(m_lockTreeMap); for (const auto& msg : msgs) { @@ -61,7 +61,7 @@ void ProcessQueue::putMessage(std::vector& msgs) { LOG_DEBUG_NEW("ProcessQueue: putMessage m_queueOffsetMax:{}", m_queueOffsetMax); } -int64_t ProcessQueue::removeMessage(std::vector& msgs) { +int64_t ProcessQueue::removeMessage(const std::vector& msgs) { int64_t result = -1; const auto now = UtilAll::currentTimeMillis(); @@ -131,7 +131,7 @@ int64_t ProcessQueue::commit() { } } -void ProcessQueue::makeMessageToCosumeAgain(std::vector& msgs) { +void ProcessQueue::makeMessageToCosumeAgain(std::vector& msgs) { std::lock_guard lock(m_lockTreeMap); for (const auto& msg : msgs) { m_msgTreeMap[msg->getQueueOffset()] = msg; @@ -139,7 +139,7 @@ void ProcessQueue::makeMessageToCosumeAgain(std::vector& msgs) } } -void ProcessQueue::takeMessages(std::vector& out_msgs, int batchSize) { +void ProcessQueue::takeMessages(std::vector& out_msgs, int batchSize) { std::lock_guard lock(m_lockTreeMap); for (int i = 0; i != batchSize; i++) { const auto& it = m_msgTreeMap.begin(); diff --git a/src/consumer/ProcessQueue.h b/src/consumer/ProcessQueue.h index 84672c548..e2780ed8c 100644 --- a/src/consumer/ProcessQueue.h +++ b/src/consumer/ProcessQueue.h @@ -23,7 +23,7 @@ #include #include -#include "MQMessageExt.h" +#include "MessageExt.h" namespace rocketmq { @@ -44,8 +44,8 @@ class ROCKETMQCLIENT_API ProcessQueue { bool isLockExpired() const; bool isPullExpired() const; - void putMessage(std::vector& msgs); - int64_t removeMessage(std::vector& msgs); + void putMessage(const std::vector& msgs); + int64_t removeMessage(const std::vector& msgs); int getCacheMsgCount(); int64_t getCacheMinOffset(); @@ -58,8 +58,8 @@ class ROCKETMQCLIENT_API ProcessQueue { void setLocked(bool locked); int64_t commit(); - void makeMessageToCosumeAgain(std::vector& msgs); - void takeMessages(std::vector& out_msgs, int batchSize); + void makeMessageToCosumeAgain(std::vector& msgs); + void takeMessages(std::vector& out_msgs, int batchSize); void clearAllMsgs(); @@ -84,9 +84,9 @@ class ROCKETMQCLIENT_API ProcessQueue { private: std::mutex m_lockTreeMap; - std::map m_msgTreeMap; + std::map m_msgTreeMap; std::timed_mutex m_lockConsume; - std::map m_consumingMsgOrderlyTreeMap; + std::map m_consumingMsgOrderlyTreeMap; std::atomic m_tryUnlockTimes; volatile int64_t m_queueOffsetMax; std::atomic m_dropped; diff --git a/src/consumer/PullAPIWrapper.cpp b/src/consumer/PullAPIWrapper.cpp index 7af5f8e87..4b7e936ed 100644 --- a/src/consumer/PullAPIWrapper.cpp +++ b/src/consumer/PullAPIWrapper.cpp @@ -18,7 +18,7 @@ #include "MQClientAPIImpl.h" #include "MQClientInstance.h" -#include "MQDecoder.h" +#include "MessageDecoder.h" #include "MessageAccessor.h" #include "PullResultExt.h" #include "PullSysFlag.h" @@ -58,10 +58,10 @@ PullResult PullAPIWrapper::processPullResult(const MQMessageQueue& mq, // update node updatePullFromWhichNode(mq, pullResultExt.suggestWhichBrokerId); - std::vector msgListFilterAgain; - if (FOUND == pullResultExt.pullStatus) { + std::vector msgListFilterAgain; + if (FOUND == pullResultExt.pull_status()) { // decode all msg list - auto msgList = MQDecoder::decodes(*pullResultExt.msgMemBlock); + auto msgList = MessageDecoder::decodes(*pullResultExt.msgMemBlock); // filter msg list again if (subscriptionData != nullptr && !subscriptionData->getTagsSet().empty()) { @@ -81,13 +81,15 @@ PullResult PullAPIWrapper::processPullResult(const MQMessageQueue& mq, if (UtilAll::stob(tranMsg)) { msg->setTransactionId(msg->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX)); } - MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_MIN_OFFSET, UtilAll::to_string(pullResult.minOffset)); - MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_MAX_OFFSET, UtilAll::to_string(pullResult.maxOffset)); + MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_MIN_OFFSET, + UtilAll::to_string(pullResult.min_offset())); + MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_MAX_OFFSET, + UtilAll::to_string(pullResult.max_offset())); } } - return PullResult(pullResultExt.pullStatus, pullResultExt.nextBeginOffset, pullResultExt.minOffset, - pullResultExt.maxOffset, std::move(msgListFilterAgain)); + return PullResult(pullResultExt.pull_status(), pullResultExt.next_begin_offset(), pullResultExt.min_offset(), + pullResultExt.max_offset(), std::move(msgListFilterAgain)); } PullResult* PullAPIWrapper::pullKernelImpl(const MQMessageQueue& mq, // 1 diff --git a/src/consumer/PullResult.cpp b/src/consumer/PullResult.cpp index 8fe82f2dc..133f2fe1d 100644 --- a/src/consumer/PullResult.cpp +++ b/src/consumer/PullResult.cpp @@ -16,50 +16,55 @@ */ #include "PullResult.h" +#include // std::move +#include // std::stringstream + #include "UtilAll.h" namespace rocketmq { -static const char* EnumStrings[] = {"FOUND", "NO_NEW_MSG", "NO_MATCHED_MSG", - "NO_LATEST_MSG" - "OFFSET_ILLEGAL", - "BROKER_TIMEOUT"}; +static const char* kPullStatusStrings[] = {"FOUND", "NO_NEW_MSG", "NO_MATCHED_MSG", + "NO_LATEST_MSG" + "OFFSET_ILLEGAL", + "BROKER_TIMEOUT"}; -PullResult::PullResult() : pullStatus(NO_MATCHED_MSG), nextBeginOffset(0), minOffset(0), maxOffset(0) {} +PullResult::PullResult() : pull_status_(NO_MATCHED_MSG), next_begin_offset_(0), min_offset_(0), max_offset_(0) {} -PullResult::PullResult(PullStatus status) : pullStatus(status), nextBeginOffset(0), minOffset(0), maxOffset(0) {} +PullResult::PullResult(PullStatus status) + : pull_status_(status), next_begin_offset_(0), min_offset_(0), max_offset_(0) {} PullResult::PullResult(PullStatus pullStatus, int64_t nextBeginOffset, int64_t minOffset, int64_t maxOffset) - : pullStatus(pullStatus), nextBeginOffset(nextBeginOffset), minOffset(minOffset), maxOffset(maxOffset) {} + : pull_status_(pullStatus), next_begin_offset_(nextBeginOffset), min_offset_(minOffset), max_offset_(maxOffset) {} PullResult::PullResult(PullStatus pullStatus, int64_t nextBeginOffset, int64_t minOffset, int64_t maxOffset, - const std::vector& src) - : pullStatus(pullStatus), - nextBeginOffset(nextBeginOffset), - minOffset(minOffset), - maxOffset(maxOffset), - msgFoundList(src) {} + const std::vector& msgFoundList) + : pull_status_(pullStatus), + next_begin_offset_(nextBeginOffset), + min_offset_(minOffset), + max_offset_(maxOffset), + msg_found_list_(msgFoundList) {} PullResult::PullResult(PullStatus pullStatus, int64_t nextBeginOffset, int64_t minOffset, int64_t maxOffset, - std::vector&& src) - : pullStatus(pullStatus), - nextBeginOffset(nextBeginOffset), - minOffset(minOffset), - maxOffset(maxOffset), - msgFoundList(std::forward>(src)) {} + std::vector&& msgFoundList) + : pull_status_(pullStatus), + next_begin_offset_(nextBeginOffset), + min_offset_(minOffset), + max_offset_(maxOffset), + msg_found_list_(std::move(msgFoundList)) {} PullResult::~PullResult() = default; std::string PullResult::toString() const { std::stringstream ss; - ss << "PullResult [ pullStatus=" << EnumStrings[pullStatus] << ", nextBeginOffset=" << nextBeginOffset - << ", minOffset=" << minOffset << ", maxOffset=" << maxOffset << ", msgFoundList=" << msgFoundList.size() << " ]"; + ss << "PullResult [ pullStatus=" << kPullStatusStrings[pull_status_] << ", nextBeginOffset=" << next_begin_offset_ + << ", minOffset=" << min_offset_ << ", maxOffset=" << max_offset_ << ", msgFoundList=" << msg_found_list_.size() + << " ]"; return ss.str(); } diff --git a/include/PullResult.h b/src/consumer/PullResult.h similarity index 61% rename from include/PullResult.h rename to src/consumer/PullResult.h index eccf19ea5..0802fef23 100644 --- a/include/PullResult.h +++ b/src/consumer/PullResult.h @@ -14,13 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __PULL_RESULT_H__ -#define __PULL_RESULT_H__ +#ifndef ROCKETMQ_CONSUMER_PULLRESULT_H_ +#define ROCKETMQ_CONSUMER_PULLRESULT_H_ -#include -#include - -#include "MQMessageExt.h" +#include "MessageExt.h" namespace rocketmq { @@ -33,7 +30,7 @@ enum PullStatus { BROKER_TIMEOUT // indicate pull request timeout or received NULL response }; -class ROCKETMQCLIENT_API PullResult { +class PullResult { public: PullResult(); PullResult(PullStatus status); @@ -43,25 +40,35 @@ class ROCKETMQCLIENT_API PullResult { int64_t nextBeginOffset, int64_t minOffset, int64_t maxOffset, - const std::vector& src); + const std::vector& msgFoundList); PullResult(PullStatus pullStatus, int64_t nextBeginOffset, int64_t minOffset, int64_t maxOffset, - std::vector&& src); + std::vector&& msgFoundList); virtual ~PullResult(); std::string toString() const; - public: - PullStatus pullStatus; - int64_t nextBeginOffset; - int64_t minOffset; - int64_t maxOffset; - std::vector msgFoundList; + inline PullStatus pull_status() const { return pull_status_; }; + inline void set_pull_status(PullStatus pull_status) { pull_status_ = pull_status; } + + inline int64_t next_begin_offset() const { return next_begin_offset_; }; + inline int64_t min_offset() const { return min_offset_; } + inline int64_t max_offset() const { return max_offset_; } + + inline std::vector& msg_found_list() { return msg_found_list_; } + inline const std::vector& msg_found_list() const { return msg_found_list_; } + + private: + PullStatus pull_status_; + int64_t next_begin_offset_; + int64_t min_offset_; + int64_t max_offset_; + std::vector msg_found_list_; }; } // namespace rocketmq -#endif // __PULL_RESULT_H__ +#endif // ROCKETMQ_CONSUMER_PULLRESULT_H_ diff --git a/src/extern/CBatchMessage.cpp b/src/extern/CBatchMessage.cpp index 2ea6ece2a..ecc452a9d 100644 --- a/src/extern/CBatchMessage.cpp +++ b/src/extern/CBatchMessage.cpp @@ -23,7 +23,7 @@ using namespace rocketmq; CBatchMessage* CreateBatchMessage() { - auto* msgs = new std::vector(); + auto* msgs = new std::vector(); return reinterpret_cast(msgs); } @@ -35,7 +35,7 @@ int AddMessage(CBatchMessage* batchMsg, CMessage* msg) { return NULL_POINTER; } auto* message = reinterpret_cast(msg); - reinterpret_cast*>(batchMsg)->push_back(message); + reinterpret_cast*>(batchMsg)->push_back(*message); return OK; } @@ -43,10 +43,7 @@ int DestroyBatchMessage(CBatchMessage* batchMsg) { if (batchMsg == NULL) { return NULL_POINTER; } - auto* msgs = reinterpret_cast*>(batchMsg); - for (auto* msg : *msgs) { - delete msg; - } + auto* msgs = reinterpret_cast*>(batchMsg); delete msgs; return OK; } diff --git a/src/extern/CProducer.cpp b/src/extern/CProducer.cpp index 60502c2d3..cf2df53ff 100644 --- a/src/extern/CProducer.cpp +++ b/src/extern/CProducer.cpp @@ -256,7 +256,7 @@ int SendMessageSync(CProducer* producer, CMessage* msg, CSendResult* result) { try { auto* defaultMQProducer = reinterpret_cast(producer); auto* message = reinterpret_cast(msg); - auto sendResult = defaultMQProducer->send(message); + auto sendResult = defaultMQProducer->send(*message); switch (sendResult.getSendStatus()) { case SEND_OK: result->sendStatus = E_SEND_OK; @@ -290,7 +290,7 @@ int SendBatchMessage(CProducer* producer, CBatchMessage* batcMsg, CSendResult* r } try { auto* defaultMQProducer = reinterpret_cast(producer); - auto* message = reinterpret_cast*>(batcMsg); + auto* message = reinterpret_cast*>(batcMsg); auto sendResult = defaultMQProducer->send(*message); switch (sendResult.getSendStatus()) { case SEND_OK: @@ -328,7 +328,7 @@ int SendMessageAsync(CProducer* producer, auto* defaultMQProducer = reinterpret_cast(producer); auto* message = reinterpret_cast(msg); auto* sendCallback = new CSendCallback(sendSuccessCallback, sendExceptionCallback); - defaultMQProducer->send(message, sendCallback); + defaultMQProducer->send(*message, sendCallback); return OK; } @@ -343,7 +343,7 @@ int SendAsync(CProducer* producer, auto* defaultMQProducer = reinterpret_cast(producer); auto* message = reinterpret_cast(msg); auto* sendCallback = new COnSendCallback(sendSuccessCallback, sendExceptionCallback, msg, userData); - defaultMQProducer->send(message, sendCallback); + defaultMQProducer->send(*message, sendCallback); return OK; } @@ -354,7 +354,7 @@ int SendMessageOneway(CProducer* producer, CMessage* msg) { auto* defaultMQProducer = reinterpret_cast(producer); auto* message = reinterpret_cast(msg); try { - defaultMQProducer->sendOneway(message); + defaultMQProducer->sendOneway(*message); } catch (std::exception& e) { return PRODUCER_SEND_ONEWAY_FAILED; } @@ -369,7 +369,7 @@ int SendMessageOnewayOrderly(CProducer* producer, CMessage* msg, QueueSelectorCa auto* message = reinterpret_cast(msg); try { SelectMessageQueue selectMessageQueue(selector); - defaultMQProducer->sendOneway(message, &selectMessageQueue, arg); + defaultMQProducer->sendOneway(*message, &selectMessageQueue, arg); } catch (std::exception& e) { MQClientErrorContainer::setErr(std::string(e.what())); return PRODUCER_SEND_ONEWAY_FAILED; @@ -392,7 +392,7 @@ int SendMessageOrderlyAsync(CProducer* producer, auto* cSendCallback = new CSendCallback(sendSuccessCallback, sendExceptionCallback); // Constructing SelectMessageQueue objects through function pointer callback SelectMessageQueue selectMessageQueue(selectorCallback); - defaultMQProducer->send(message, &selectMessageQueue, arg, cSendCallback); + defaultMQProducer->send(*message, &selectMessageQueue, arg, cSendCallback); return OK; } @@ -410,7 +410,7 @@ int SendMessageOrderly(CProducer* producer, try { // Constructing SelectMessageQueue objects through function pointer callback SelectMessageQueue selectMessageQueue(selectorCallback); - SendResult sendResult = defaultMQProducer->send(message, &selectMessageQueue, arg); + SendResult sendResult = defaultMQProducer->send(*message, &selectMessageQueue, arg); // Convert SendStatus to CSendStatus result->sendStatus = CSendStatus((int)sendResult.getSendStatus()); result->offset = sendResult.getQueueOffset(); @@ -433,7 +433,7 @@ int SendMessageOrderlyByShardingKey(CProducer* producer, CMessage* msg, const ch // Constructing SelectMessageQueue objects through function pointer callback int retryTimes = 3; SelectMessageQueueInner selectMessageQueue; - SendResult sendResult = defaultMQProducer->send(message, &selectMessageQueue, (void*)shardingKey, retryTimes); + SendResult sendResult = defaultMQProducer->send(*message, &selectMessageQueue, (void*)shardingKey, retryTimes); // Convert SendStatus to CSendStatus result->sendStatus = CSendStatus((int)sendResult.getSendStatus()); result->offset = sendResult.getQueueOffset(); @@ -458,7 +458,7 @@ int SendMessageTransaction(CProducer* producer, auto* transactionMQProducer = reinterpret_cast(producer); auto* message = reinterpret_cast(msg); LocalTransactionExecutorInner executorInner(callback, msg, userData); - auto sendResult = transactionMQProducer->sendMessageInTransaction(message, &executorInner); + auto sendResult = transactionMQProducer->sendMessageInTransaction(*message, &executorInner); result->sendStatus = CSendStatus((int)sendResult.getSendStatus()); result->offset = sendResult.getQueueOffset(); strncpy(result->msgId, sendResult.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1); diff --git a/src/extern/CPullConsumer.cpp b/src/extern/CPullConsumer.cpp index 61210a382..f3fe10356 100644 --- a/src/extern/CPullConsumer.cpp +++ b/src/extern/CPullConsumer.cpp @@ -187,27 +187,27 @@ CPullResult Pull(CPullConsumer* consumer, reinterpret_cast(consumer)->pull(messageQueue, subExpression, offset, maxNums); } catch (std::exception& e) { MQClientErrorContainer::setErr(std::string(e.what())); - cppPullResult.pullStatus = BROKER_TIMEOUT; + cppPullResult.set_pull_status(BROKER_TIMEOUT); } - if (cppPullResult.pullStatus != BROKER_TIMEOUT) { - pullResult.maxOffset = cppPullResult.maxOffset; - pullResult.minOffset = cppPullResult.minOffset; - pullResult.nextBeginOffset = cppPullResult.nextBeginOffset; + if (cppPullResult.pull_status() != BROKER_TIMEOUT) { + pullResult.maxOffset = cppPullResult.max_offset(); + pullResult.minOffset = cppPullResult.min_offset(); + pullResult.nextBeginOffset = cppPullResult.next_begin_offset(); } - switch (cppPullResult.pullStatus) { + switch (cppPullResult.pull_status()) { case FOUND: { pullResult.pullStatus = E_FOUND; - pullResult.size = cppPullResult.msgFoundList.size(); + pullResult.size = cppPullResult.msg_found_list().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 = tmpPullResult->msgFoundList[i].get(); - pullResult.msgFoundList[i] = (CMessageExt*)(msg); + for (size_t i = 0; i < cppPullResult.msg_found_list().size(); i++) { + auto msg = tmpPullResult->msg_found_list()[i]; + pullResult.msgFoundList[i] = reinterpret_cast(&msg); } break; } diff --git a/src/extern/CPushConsumer.cpp b/src/extern/CPushConsumer.cpp index 40fbd2b93..b93a94fcc 100644 --- a/src/extern/CPushConsumer.cpp +++ b/src/extern/CPushConsumer.cpp @@ -16,7 +16,7 @@ */ #include "c/CPushConsumer.h" -#include +#include // std::map #include "ClientRPCHook.h" #include "DefaultMQPushConsumer.h" @@ -32,13 +32,13 @@ class MessageListenerInner : public MessageListenerConcurrently { ~MessageListenerInner() = default; - ConsumeStatus consumeMessage(const std::vector& msgs) override { + ConsumeStatus consumeMessage(const std::vector& msgs) override { // to do user call back if (m_msgReceivedCallback == nullptr) { return RECONSUME_LATER; } for (auto msg : msgs) { - auto* message = reinterpret_cast(msg); + auto* message = reinterpret_cast(&msg); if (m_msgReceivedCallback(m_consumer, message) != E_CONSUME_SUCCESS) { return RECONSUME_LATER; } @@ -56,12 +56,12 @@ class MessageListenerOrderlyInner : public MessageListenerOrderly { MessageListenerOrderlyInner(CPushConsumer* consumer, MessageCallBack callback) : m_consumer(consumer), m_msgReceivedCallback(callback) {} - ConsumeStatus consumeMessage(const std::vector& msgs) { + ConsumeStatus consumeMessage(const std::vector& msgs) override { if (m_msgReceivedCallback == nullptr) { return RECONSUME_LATER; } for (auto msg : msgs) { - auto* message = reinterpret_cast(msg); + auto* message = reinterpret_cast(&msg); if (m_msgReceivedCallback(m_consumer, message) != E_CONSUME_SUCCESS) { return RECONSUME_LATER; } diff --git a/src/message/MQMessage.cpp b/src/message/MQMessage.cpp index 3f2a29ce4..71f8a3019 100644 --- a/src/message/MQMessage.cpp +++ b/src/message/MQMessage.cpp @@ -16,55 +16,16 @@ */ #include "MQMessage.h" -#include "MessageSysFlag.h" -#include "UtilAll.h" +#include // std::move -namespace rocketmq { +#include "UtilAll.h" // null +#include "MessageImpl.h" -const std::string MQMessageConst::PROPERTY_KEYS = "KEYS"; -const std::string MQMessageConst::PROPERTY_TAGS = "TAGS"; -const std::string MQMessageConst::PROPERTY_WAIT_STORE_MSG_OK = "WAIT"; -const std::string MQMessageConst::PROPERTY_DELAY_TIME_LEVEL = "DELAY"; -const std::string MQMessageConst::PROPERTY_RETRY_TOPIC = "RETRY_TOPIC"; -const std::string MQMessageConst::PROPERTY_REAL_TOPIC = "REAL_TOPIC"; -const std::string MQMessageConst::PROPERTY_REAL_QUEUE_ID = "REAL_QID"; -const std::string MQMessageConst::PROPERTY_TRANSACTION_PREPARED = "TRAN_MSG"; -const std::string MQMessageConst::PROPERTY_PRODUCER_GROUP = "PGROUP"; -const std::string MQMessageConst::PROPERTY_MIN_OFFSET = "MIN_OFFSET"; -const std::string MQMessageConst::PROPERTY_MAX_OFFSET = "MAX_OFFSET"; - -const std::string MQMessageConst::PROPERTY_BUYER_ID = "BUYER_ID"; -const std::string MQMessageConst::PROPERTY_ORIGIN_MESSAGE_ID = "ORIGIN_MESSAGE_ID"; -const std::string MQMessageConst::PROPERTY_TRANSFER_FLAG = "TRANSFER_FLAG"; -const std::string MQMessageConst::PROPERTY_CORRECTION_FLAG = "CORRECTION_FLAG"; -const std::string MQMessageConst::PROPERTY_MQ2_FLAG = "MQ2_FLAG"; -const std::string MQMessageConst::PROPERTY_RECONSUME_TIME = "RECONSUME_TIME"; -const std::string MQMessageConst::PROPERTY_MSG_REGION = "MSG_REGION"; -const std::string MQMessageConst::PROPERTY_TRACE_SWITCH = "TRACE_ON"; -const std::string MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX = "UNIQ_KEY"; -const std::string MQMessageConst::PROPERTY_MAX_RECONSUME_TIMES = "MAX_RECONSUME_TIMES"; -const std::string MQMessageConst::PROPERTY_CONSUME_START_TIMESTAMP = "CONSUME_START_TIME"; -const std::string MQMessageConst::PROPERTY_TRANSACTION_PREPARED_QUEUE_OFFSET = "TRAN_PREPARED_QUEUE_OFFSET"; -const std::string MQMessageConst::PROPERTY_TRANSACTION_CHECK_TIMES = "TRANSACTION_CHECK_TIMES"; -const std::string MQMessageConst::PROPERTY_CHECK_IMMUNITY_TIME_IN_SECONDS = "CHECK_IMMUNITY_TIME_IN_SECONDS"; -const std::string MQMessageConst::PROPERTY_INSTANCE_ID = "INSTANCE_ID"; -const std::string MQMessageConst::PROPERTY_CORRELATION_ID = "CORRELATION_ID"; -const std::string MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT = "REPLY_TO_CLIENT"; -const std::string MQMessageConst::PROPERTY_MESSAGE_TTL = "TTL"; -const std::string MQMessageConst::PROPERTY_REPLY_MESSAGE_ARRIVE_TIME = "ARRIVE_TIME"; -const std::string MQMessageConst::PROPERTY_PUSH_REPLY_TIME = "PUSH_REPLY_TIME"; -const std::string MQMessageConst::PROPERTY_CLUSTER = "CLUSTER"; -const std::string MQMessageConst::PROPERTY_MESSAGE_TYPE = "MSG_TYPE"; - -const std::string MQMessageConst::PROPERTY_ALREADY_COMPRESSED_FLAG = "__ALREADY_COMPRESSED__"; - -const std::string MQMessageConst::KEY_SEPARATOR = " "; - -static const std::string EMPTY_STRING = ""; +namespace rocketmq { MQMessage::MQMessage() : MQMessage(null, null) {} -MQMessage::MQMessage(const std::string& topic, const std::string& body) : MQMessage(topic, "", body) {} +MQMessage::MQMessage(const std::string& topic, const std::string& body) : MQMessage(topic, null, body) {} MQMessage::MQMessage(const std::string& topic, const std::string& tags, const std::string& body) : MQMessage(topic, tags, null, body) {} @@ -78,168 +39,127 @@ MQMessage::MQMessage(const std::string& topic, MQMessage::MQMessage(const std::string& topic, const std::string& tags, const std::string& keys, - const int flag, + int32_t flag, const std::string& body, bool waitStoreMsgOK) - : m_topic(topic), m_flag(flag), m_body(body) { - if (tags.length() > 0) { - setTags(tags); - } - - if (keys.length() > 0) { - setKeys(keys); - } - - setWaitStoreMsgOK(waitStoreMsgOK); -} - -MQMessage::MQMessage(const MQMessage& other) { - m_topic = other.m_topic; - m_flag = other.m_flag; - m_properties = other.m_properties; - m_body = other.m_body; -} - -MQMessage& MQMessage::operator=(const MQMessage& other) { - if (this != &other) { - m_topic = other.m_topic; - m_flag = other.m_flag; - m_properties = other.m_properties; - m_body = other.m_body; - } - return *this; -} + : message_impl_(std::make_shared(topic, tags, keys, flag, body, waitStoreMsgOK)) {} MQMessage::~MQMessage() = default; const std::string& MQMessage::getProperty(const std::string& name) const { - const auto& it = m_properties.find(name); - if (it != m_properties.end()) { - return it->second; - } - return EMPTY_STRING; + return message_impl_->getProperty(name); } void MQMessage::putProperty(const std::string& name, const std::string& value) { - m_properties[name] = value; + message_impl_->putProperty(name, value); } void MQMessage::clearProperty(const std::string& name) { - m_properties.erase(name); + message_impl_->clearProperty(name); } const std::string& MQMessage::getTopic() const { - return m_topic; + return message_impl_->getTopic(); } void MQMessage::setTopic(const std::string& topic) { - m_topic = topic; + message_impl_->setTopic(topic); } void MQMessage::setTopic(const char* body, int len) { - m_topic.clear(); - m_topic.append(body, len); + message_impl_->setTopic(body, len); } const std::string& MQMessage::getTags() const { - return getProperty(MQMessageConst::PROPERTY_TAGS); + return message_impl_->getTags(); } void MQMessage::setTags(const std::string& tags) { - putProperty(MQMessageConst::PROPERTY_TAGS, tags); + message_impl_->setTags(tags); } const std::string& MQMessage::getKeys() const { - return getProperty(MQMessageConst::PROPERTY_KEYS); + return message_impl_->getKeys(); } void MQMessage::setKeys(const std::string& keys) { - putProperty(MQMessageConst::PROPERTY_KEYS, keys); + message_impl_->setKeys(keys); } void MQMessage::setKeys(const std::vector& keys) { - if (keys.empty()) { - return; - } - - std::vector::const_iterator it = keys.begin(); - std::string str; - str += *it; - it++; - - for (; it != keys.end(); it++) { - str += MQMessageConst::KEY_SEPARATOR; - str += *it; - } - - setKeys(str); + message_impl_->setKeys(keys); } int MQMessage::getDelayTimeLevel() const { - std::string tmp = getProperty(MQMessageConst::PROPERTY_DELAY_TIME_LEVEL); - if (!tmp.empty()) { - return atoi(tmp.c_str()); - } - return 0; + return message_impl_->getDelayTimeLevel(); } void MQMessage::setDelayTimeLevel(int level) { - putProperty(MQMessageConst::PROPERTY_DELAY_TIME_LEVEL, UtilAll::to_string(level)); + message_impl_->setDelayTimeLevel(level); } bool MQMessage::isWaitStoreMsgOK() const { - std::string tmp = getProperty(MQMessageConst::PROPERTY_WAIT_STORE_MSG_OK); - return tmp.empty() || UtilAll::stob(tmp); + return message_impl_->isWaitStoreMsgOK(); } void MQMessage::setWaitStoreMsgOK(bool waitStoreMsgOK) { - putProperty(MQMessageConst::PROPERTY_WAIT_STORE_MSG_OK, UtilAll::to_string(waitStoreMsgOK)); + message_impl_->setWaitStoreMsgOK(waitStoreMsgOK); } -int MQMessage::getFlag() const { - return m_flag; +int32_t MQMessage::getFlag() const { + return message_impl_->getFlag(); } -void MQMessage::setFlag(int flag) { - m_flag = flag; +void MQMessage::setFlag(int32_t flag) { + message_impl_->setFlag(flag); } const std::string& MQMessage::getBody() const { - // TODO: return MemoryBlockPtr2 - return m_body; + return message_impl_->getBody(); } void MQMessage::setBody(const char* body, int len) { - m_body.clear(); - m_body.append(body, len); + message_impl_->setBody(body, len); } void MQMessage::setBody(const std::string& body) { - m_body = body; + message_impl_->setBody(body); } void MQMessage::setBody(std::string&& body) { - m_body = std::forward(body); + message_impl_->setBody(std::move(body)); } const std::string& MQMessage::getTransactionId() const { - return m_transactionId; + return message_impl_->getTransactionId(); } void MQMessage::setTransactionId(const std::string& transactionId) { - m_transactionId = transactionId; + message_impl_->setTransactionId(transactionId); } const std::map& MQMessage::getProperties() const { - return m_properties; + return message_impl_->getProperties(); } void MQMessage::setProperties(const std::map& properties) { - m_properties = properties; + message_impl_->setProperties(properties); } void MQMessage::setProperties(std::map&& properties) { - m_properties = std::forward>(properties); + message_impl_->setProperties(std::move(properties)); +} + +bool MQMessage::isBatch() const { + return message_impl_->isBatch(); +} + +std::string MQMessage::toString() const { + return message_impl_->toString(); +} + +MessagePtr MQMessage::getMessageImpl() { + return message_impl_; } } // namespace rocketmq diff --git a/src/message/MQMessageConst.cpp b/src/message/MQMessageConst.cpp new file mode 100644 index 000000000..bf5e90ff4 --- /dev/null +++ b/src/message/MQMessageConst.cpp @@ -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. + */ +#include "MQMessageConst.h" + +namespace rocketmq { + +const std::string MQMessageConst::PROPERTY_KEYS = "KEYS"; +const std::string MQMessageConst::PROPERTY_TAGS = "TAGS"; +const std::string MQMessageConst::PROPERTY_WAIT_STORE_MSG_OK = "WAIT"; +const std::string MQMessageConst::PROPERTY_DELAY_TIME_LEVEL = "DELAY"; +const std::string MQMessageConst::PROPERTY_RETRY_TOPIC = "RETRY_TOPIC"; +const std::string MQMessageConst::PROPERTY_REAL_TOPIC = "REAL_TOPIC"; +const std::string MQMessageConst::PROPERTY_REAL_QUEUE_ID = "REAL_QID"; +const std::string MQMessageConst::PROPERTY_TRANSACTION_PREPARED = "TRAN_MSG"; +const std::string MQMessageConst::PROPERTY_PRODUCER_GROUP = "PGROUP"; +const std::string MQMessageConst::PROPERTY_MIN_OFFSET = "MIN_OFFSET"; +const std::string MQMessageConst::PROPERTY_MAX_OFFSET = "MAX_OFFSET"; + +const std::string MQMessageConst::PROPERTY_BUYER_ID = "BUYER_ID"; +const std::string MQMessageConst::PROPERTY_ORIGIN_MESSAGE_ID = "ORIGIN_MESSAGE_ID"; +const std::string MQMessageConst::PROPERTY_TRANSFER_FLAG = "TRANSFER_FLAG"; +const std::string MQMessageConst::PROPERTY_CORRECTION_FLAG = "CORRECTION_FLAG"; +const std::string MQMessageConst::PROPERTY_MQ2_FLAG = "MQ2_FLAG"; +const std::string MQMessageConst::PROPERTY_RECONSUME_TIME = "RECONSUME_TIME"; +const std::string MQMessageConst::PROPERTY_MSG_REGION = "MSG_REGION"; +const std::string MQMessageConst::PROPERTY_TRACE_SWITCH = "TRACE_ON"; +const std::string MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX = "UNIQ_KEY"; +const std::string MQMessageConst::PROPERTY_MAX_RECONSUME_TIMES = "MAX_RECONSUME_TIMES"; +const std::string MQMessageConst::PROPERTY_CONSUME_START_TIMESTAMP = "CONSUME_START_TIME"; +const std::string MQMessageConst::PROPERTY_TRANSACTION_PREPARED_QUEUE_OFFSET = "TRAN_PREPARED_QUEUE_OFFSET"; +const std::string MQMessageConst::PROPERTY_TRANSACTION_CHECK_TIMES = "TRANSACTION_CHECK_TIMES"; +const std::string MQMessageConst::PROPERTY_CHECK_IMMUNITY_TIME_IN_SECONDS = "CHECK_IMMUNITY_TIME_IN_SECONDS"; +const std::string MQMessageConst::PROPERTY_INSTANCE_ID = "INSTANCE_ID"; +const std::string MQMessageConst::PROPERTY_CORRELATION_ID = "CORRELATION_ID"; +const std::string MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT = "REPLY_TO_CLIENT"; +const std::string MQMessageConst::PROPERTY_MESSAGE_TTL = "TTL"; +const std::string MQMessageConst::PROPERTY_REPLY_MESSAGE_ARRIVE_TIME = "ARRIVE_TIME"; +const std::string MQMessageConst::PROPERTY_PUSH_REPLY_TIME = "PUSH_REPLY_TIME"; +const std::string MQMessageConst::PROPERTY_CLUSTER = "CLUSTER"; +const std::string MQMessageConst::PROPERTY_MESSAGE_TYPE = "MSG_TYPE"; + +const std::string MQMessageConst::PROPERTY_ALREADY_COMPRESSED_FLAG = "__ALREADY_COMPRESSED__"; + +const std::string MQMessageConst::KEY_SEPARATOR = " "; + +} // namespace rocketmq diff --git a/src/message/MQMessageExt.cpp b/src/message/MQMessageExt.cpp index e76a84423..09b7e2c2a 100644 --- a/src/message/MQMessageExt.cpp +++ b/src/message/MQMessageExt.cpp @@ -16,184 +16,133 @@ */ #include "MQMessageExt.h" -#include - -#include "MessageClientIDSetter.h" -#include "MessageSysFlag.h" -#include "SocketUtil.h" -#include "TopicFilterType.h" +#include "MessageExtImpl.h" +#include "UtilAll.h" // null namespace rocketmq { -MQMessageExt::MQMessageExt() : MQMessageExt(0, 0, nullptr, 0, nullptr, "") {} +MQMessageExt::MQMessageExt() : MQMessageExt(0, 0, nullptr, 0, nullptr, null) {} MQMessageExt::MQMessageExt(int queueId, int64_t bornTimestamp, const struct sockaddr* bornHost, int64_t storeTimestamp, const struct sockaddr* storeHost, - std::string msgId) - : m_storeSize(0), - m_bodyCRC(0), - m_queueId(queueId), - m_queueOffset(0), - m_commitLogOffset(0), - m_sysFlag(0), - m_bornTimestamp(bornTimestamp), - m_bornHost(nullptr), - m_storeTimestamp(storeTimestamp), - m_storeHost(nullptr), - m_reconsumeTimes(3), - m_preparedTransactionOffset(0), - m_msgId(msgId) { - m_bornHost = copySocketAddress(m_bornHost, bornHost); - m_storeHost = copySocketAddress(m_storeHost, storeHost); -} - -MQMessageExt::~MQMessageExt() { - free(m_bornHost); - free(m_storeHost); -} - -TopicFilterType MQMessageExt::parseTopicFilterType(int32_t sysFlag) { - if ((sysFlag & MessageSysFlag::MultiTagsFlag) == MessageSysFlag::MultiTagsFlag) { - return MULTI_TAG; - } - return SINGLE_TAG; -} + const std::string& msgId) + : MQMessage(std::make_shared(queueId, bornTimestamp, bornHost, storeTimestamp, storeHost, msgId)) {} + +MQMessageExt::~MQMessageExt() = default; int32_t MQMessageExt::getStoreSize() const { - return m_storeSize; + return std::dynamic_pointer_cast(message_impl_)->getStoreSize(); } void MQMessageExt::setStoreSize(int32_t storeSize) { - m_storeSize = storeSize; + std::dynamic_pointer_cast(message_impl_)->setStoreSize(storeSize); } int32_t MQMessageExt::getBodyCRC() const { - return m_bodyCRC; + return std::dynamic_pointer_cast(message_impl_)->getBodyCRC(); } void MQMessageExt::setBodyCRC(int32_t bodyCRC) { - m_bodyCRC = bodyCRC; + std::dynamic_pointer_cast(message_impl_)->setBodyCRC(bodyCRC); } int32_t MQMessageExt::getQueueId() const { - return m_queueId; + return std::dynamic_pointer_cast(message_impl_)->getQueueId(); } void MQMessageExt::setQueueId(int32_t queueId) { - m_queueId = queueId; + std::dynamic_pointer_cast(message_impl_)->setQueueId(queueId); } int64_t MQMessageExt::getQueueOffset() const { - return m_queueOffset; + return std::dynamic_pointer_cast(message_impl_)->getQueueOffset(); } void MQMessageExt::setQueueOffset(int64_t queueOffset) { - m_queueOffset = queueOffset; + std::dynamic_pointer_cast(message_impl_)->setQueueOffset(queueOffset); } int64_t MQMessageExt::getCommitLogOffset() const { - return m_commitLogOffset; + return std::dynamic_pointer_cast(message_impl_)->getCommitLogOffset(); } void MQMessageExt::setCommitLogOffset(int64_t physicOffset) { - m_commitLogOffset = physicOffset; + std::dynamic_pointer_cast(message_impl_)->setCommitLogOffset(physicOffset); } int32_t MQMessageExt::getSysFlag() const { - return m_sysFlag; + return std::dynamic_pointer_cast(message_impl_)->getSysFlag(); } void MQMessageExt::setSysFlag(int32_t sysFlag) { - m_sysFlag = sysFlag; + std::dynamic_pointer_cast(message_impl_)->setSysFlag(sysFlag); } int64_t MQMessageExt::getBornTimestamp() const { - return m_bornTimestamp; + return std::dynamic_pointer_cast(message_impl_)->getBornTimestamp(); } void MQMessageExt::setBornTimestamp(int64_t bornTimestamp) { - m_bornTimestamp = bornTimestamp; + std::dynamic_pointer_cast(message_impl_)->setBornTimestamp(bornTimestamp); } -const struct sockaddr* MQMessageExt::getBornHost() const { - return m_bornHost; +std::string MQMessageExt::getBornHostString() const { + return std::dynamic_pointer_cast(message_impl_)->getBornHostString(); } -std::string MQMessageExt::getBornHostString() const { - return socketAddress2String(m_bornHost); +const struct sockaddr* MQMessageExt::getBornHost() const { + return std::dynamic_pointer_cast(message_impl_)->getBornHost(); } void MQMessageExt::setBornHost(const struct sockaddr* bornHost) { - m_bornHost = copySocketAddress(m_bornHost, bornHost); + std::dynamic_pointer_cast(message_impl_)->setBornHost(bornHost); } int64_t MQMessageExt::getStoreTimestamp() const { - return m_storeTimestamp; + return std::dynamic_pointer_cast(message_impl_)->getStoreTimestamp(); } void MQMessageExt::setStoreTimestamp(int64_t storeTimestamp) { - m_storeTimestamp = storeTimestamp; -} - -const struct sockaddr* MQMessageExt::getStoreHost() const { - return m_storeHost; + std::dynamic_pointer_cast(message_impl_)->setStoreTimestamp(storeTimestamp); } std::string MQMessageExt::getStoreHostString() const { - return socketAddress2String(m_storeHost); + return std::dynamic_pointer_cast(message_impl_)->getStoreHostString(); } -void MQMessageExt::setStoreHost(const struct sockaddr* storeHost) { - m_storeHost = copySocketAddress(m_storeHost, storeHost); -} - -const std::string& MQMessageExt::getMsgId() const { - return m_msgId; +const struct sockaddr* MQMessageExt::getStoreHost() const { + return std::dynamic_pointer_cast(message_impl_)->getStoreHost(); } -void MQMessageExt::setMsgId(const std::string& msgId) { - m_msgId = msgId; +void MQMessageExt::setStoreHost(const struct sockaddr* storeHost) { + std::dynamic_pointer_cast(message_impl_)->setStoreHost(storeHost); } int32_t MQMessageExt::getReconsumeTimes() const { - return m_reconsumeTimes; + return std::dynamic_pointer_cast(message_impl_)->getReconsumeTimes(); } void MQMessageExt::setReconsumeTimes(int32_t reconsumeTimes) { - m_reconsumeTimes = reconsumeTimes; + std::dynamic_pointer_cast(message_impl_)->setReconsumeTimes(reconsumeTimes); } int64_t MQMessageExt::getPreparedTransactionOffset() const { - return m_preparedTransactionOffset; + return std::dynamic_pointer_cast(message_impl_)->getPreparedTransactionOffset(); } void MQMessageExt::setPreparedTransactionOffset(int64_t preparedTransactionOffset) { - m_preparedTransactionOffset = preparedTransactionOffset; + std::dynamic_pointer_cast(message_impl_)->setPreparedTransactionOffset(preparedTransactionOffset); } -const std::string& MQMessageClientExt::getOffsetMsgId() const { - return MQMessageExt::getMsgId(); -} - -void MQMessageClientExt::setOffsetMsgId(const std::string& offsetMsgId) { - return MQMessageExt::setMsgId(offsetMsgId); -} - -const std::string& MQMessageClientExt::getMsgId() const { - const auto& uniqID = MessageClientIDSetter::getUniqID(*this); - if (uniqID.empty()) { - return getOffsetMsgId(); - } else { - return uniqID; - } +const std::string& MQMessageExt::getMsgId() const { + return std::dynamic_pointer_cast(message_impl_)->getMsgId(); } -void MQMessageClientExt::setMsgId(const std::string& msgId) { - // DO NOTHING - // MessageClientIDSetter::setUniqID(*this); +void MQMessageExt::setMsgId(const std::string& msgId) { + std::dynamic_pointer_cast(message_impl_)->setMsgId(msgId); } } // namespace rocketmq diff --git a/src/message/MQMessageId.h b/src/message/MQMessageId.h deleted file mode 100644 index 2e31e7838..000000000 --- a/src/message/MQMessageId.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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_ID_H__ -#define __MESSAGE_ID_H__ - -#include "SocketUtil.h" -#include "UtilAll.h" - -namespace rocketmq { - -class MQMessageId { - public: - MQMessageId() : MQMessageId(nullptr, 0) {} - MQMessageId(struct sockaddr* address, int64_t offset) : m_address(nullptr), m_offset(offset) { setAddress(address); } - ~MQMessageId() { free(m_address); } - - MQMessageId& operator=(const MQMessageId& id) { - if (&id == this) { - return *this; - } - setAddress(id.m_address); - this->m_offset = id.m_offset; - return *this; - } - - const struct sockaddr* getAddress() const { return m_address; } - - void setAddress(struct sockaddr* address) { m_address = copySocketAddress(m_address, address); } - - int64_t getOffset() const { return m_offset; } - - void setOffset(int64_t offset) { m_offset = offset; } - - private: - struct sockaddr* m_address; - int64_t m_offset; -}; - -} // namespace rocketmq - -#endif // __MESSAGE_ID_H__ diff --git a/src/message/MessageAccessor.h b/src/message/MessageAccessor.h index c9bf2bd0c..ea6f6a24d 100644 --- a/src/message/MessageAccessor.h +++ b/src/message/MessageAccessor.h @@ -17,31 +17,33 @@ #ifndef __MESSAGE_ACCESSOR_H__ #define __MESSAGE_ACCESSOR_H__ -#include "MQMessage.h" +#include + +#include "Message.h" namespace rocketmq { class MessageAccessor { public: - static inline void clearProperty(MQMessage& msg, const std::string& name) { msg.clearProperty(name); } + static inline void clearProperty(Message& msg, const std::string& name) { msg.clearProperty(name); } - static inline void setProperties(MQMessage& msg, std::map&& properties) { - msg.setProperties(std::forward>(properties)); + static inline void setProperties(Message& msg, std::map&& properties) { + msg.setProperties(std::move(properties)); } - static inline void putProperty(MQMessage& msg, const std::string& name, const std::string& value) { + static inline void putProperty(Message& msg, const std::string& name, const std::string& value) { msg.putProperty(name, value); } - static inline const std::string& getReconsumeTime(MQMessage& msg) { + static inline const std::string& getReconsumeTime(Message& msg) { return msg.getProperty(MQMessageConst::PROPERTY_RECONSUME_TIME); } - static inline const std::string& getMaxReconsumeTimes(MQMessage& msg) { + static inline const std::string& getMaxReconsumeTimes(Message& msg) { return msg.getProperty(MQMessageConst::PROPERTY_MAX_RECONSUME_TIMES); } - static inline void setConsumeStartTimeStamp(MQMessage& msg, const std::string& propertyConsumeStartTimeStamp) { + static inline void setConsumeStartTimeStamp(Message& msg, const std::string& propertyConsumeStartTimeStamp) { putProperty(msg, MQMessageConst::PROPERTY_CONSUME_START_TIMESTAMP, propertyConsumeStartTimeStamp); } }; diff --git a/src/message/MessageBatch.cpp b/src/message/MessageBatch.cpp index 40ecee32e..ab49b7469 100644 --- a/src/message/MessageBatch.cpp +++ b/src/message/MessageBatch.cpp @@ -16,48 +16,47 @@ */ #include "MessageBatch.h" -#include - -#include "MQDecoder.h" +#include "MessageDecoder.h" #include "MessageClientIDSetter.h" namespace rocketmq { -std::string MessageBatch::encode() { - return MQDecoder::encodeMessages(m_messages); -} - -MessageBatch* MessageBatch::generateFromList(std::vector& messages) { - bool isFirst = true; +std::shared_ptr MessageBatch::generateFromList(std::vector& messages) { + bool is_first = true; std::string topic; - bool waitStoreMsgOK = false; + bool wait_store_msg_ok = true; + // check messages for (auto& message : messages) { - if (message->getDelayTimeLevel() > 0) { + if (message.getDelayTimeLevel() > 0) { THROW_MQEXCEPTION(MQClientException, "TimeDelayLevel in not supported for batching", -1); } - if (isFirst) { - isFirst = false; - topic = message->getTopic(); - waitStoreMsgOK = message->isWaitStoreMsgOK(); + if (is_first) { + is_first = false; + topic = message.getTopic(); + wait_store_msg_ok = message.isWaitStoreMsgOK(); if (UtilAll::isRetryTopic(topic)) { THROW_MQEXCEPTION(MQClientException, "Retry Group is not supported for batching", -1); } } else { - if (message->getTopic() != topic) { + if (message.getTopic() != topic) { THROW_MQEXCEPTION(MQClientException, "The topic of the messages in one batch should be the same", -1); } - if (message->isWaitStoreMsgOK() != waitStoreMsgOK) { + if (message.isWaitStoreMsgOK() != wait_store_msg_ok) { THROW_MQEXCEPTION(MQClientException, "The waitStoreMsgOK of the messages in one batch should the same", -2); } } } - MessageBatch* batchMessage = new MessageBatch(messages); + auto batchMessage = std::make_shared(messages); batchMessage->setTopic(topic); - batchMessage->setWaitStoreMsgOK(waitStoreMsgOK); + batchMessage->setWaitStoreMsgOK(wait_store_msg_ok); return batchMessage; } +std::string MessageBatch::encode() { + return MessageDecoder::encodeMessages(m_messages); +} + } // namespace rocketmq diff --git a/src/message/MessageBatch.h b/src/message/MessageBatch.h index 644d28726..1495f72d7 100644 --- a/src/message/MessageBatch.h +++ b/src/message/MessageBatch.h @@ -17,28 +17,28 @@ #ifndef __MESSAGE_BATCH_H__ #define __MESSAGE_BATCH_H__ -#include -#include - #include "MQMessage.h" +#include "MessageImpl.h" namespace rocketmq { -class MessageBatch : public MQMessage { +class MessageBatch : public MessageImpl { public: - static MessageBatch* generateFromList(std::vector& messages); + static std::shared_ptr generateFromList(std::vector& messages); public: - MessageBatch(std::vector& messages) : m_messages(messages) {} + MessageBatch(std::vector& messages) : MessageImpl(), m_messages(messages) {} - std::string encode(); + public: // Message + bool isBatch() const override final { return true; } - const std::vector& getMessages() const { return m_messages; } + public: + std::string encode(); - bool isBatch() override final { return true; } + const std::vector& getMessages() const { return m_messages; } protected: - std::vector m_messages; + std::vector m_messages; }; } // namespace rocketmq diff --git a/src/message/MessageClientIDSetter.h b/src/message/MessageClientIDSetter.h index 9af959e89..90f2ec52c 100644 --- a/src/message/MessageClientIDSetter.h +++ b/src/message/MessageClientIDSetter.h @@ -43,13 +43,13 @@ class MessageClientIDSetter { */ static std::string createUniqID() { return getInstance().createUniqueID(); } - static void setUniqID(MQMessage& msg) { + static void setUniqID(Message& msg) { if (msg.getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX).empty()) { MessageAccessor::putProperty(msg, MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX, createUniqID()); } } - static const std::string& getUniqID(const MQMessage& msg) { + static const std::string& getUniqID(const Message& msg) { return msg.getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX); } diff --git a/src/message/MQDecoder.cpp b/src/message/MessageDecoder.cpp similarity index 66% rename from src/message/MQDecoder.cpp rename to src/message/MessageDecoder.cpp index 863fa41e0..e7e4e596d 100644 --- a/src/message/MQDecoder.cpp +++ b/src/message/MessageDecoder.cpp @@ -14,83 +14,96 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "MQDecoder.h" +#include "MessageDecoder.h" -#include +#include // std::memcpy + +#include // std::move +#include // std::stringstream #ifndef WIN32 -#include +#include // htons, htonl +#include // struct sockaddr, sockaddr_in, sockaddr_in6 #endif #include "ByteOrder.h" #include "Logging.h" #include "MemoryOutputStream.h" +#include "MessageExtImpl.h" #include "MessageAccessor.h" #include "MessageSysFlag.h" #include "UtilAll.h" namespace rocketmq { -const int MQDecoder::MSG_ID_LENGTH = 8 + 8; - -const char MQDecoder::NAME_VALUE_SEPARATOR = 1; -const char MQDecoder::PROPERTY_SEPARATOR = 2; +const int MessageDecoder::MSG_ID_LENGTH = 8 + 8; -int MQDecoder::MessageMagicCodePostion = 4; -int MQDecoder::MessageFlagPostion = 16; -int MQDecoder::MessagePhysicOffsetPostion = 28; -int MQDecoder::MessageStoreTimestampPostion = 56; +const char MessageDecoder::NAME_VALUE_SEPARATOR = 1; +const char MessageDecoder::PROPERTY_SEPARATOR = 2; -std::string MQDecoder::createMessageId(const struct sockaddr* sa, int64_t offset) { - const struct sockaddr_in* sin = (struct sockaddr_in*)sa; +int MessageDecoder::MessageMagicCodePostion = 4; +int MessageDecoder::MessageFlagPostion = 16; +int MessageDecoder::MessagePhysicOffsetPostion = 28; +int MessageDecoder::MessageStoreTimestampPostion = 56; - MemoryOutputStream outputmen(MSG_ID_LENGTH); - outputmen.writeIntBigEndian(sin->sin_addr.s_addr); - outputmen.writeRepeatedByte(0, 2); - outputmen.write(&(sin->sin_port), 2); - outputmen.writeInt64BigEndian(offset); +std::string MessageDecoder::createMessageId(const struct sockaddr* sa, int64_t offset) { + MemoryOutputStream mos(sa->sa_family == AF_INET ? 16 : 28); + if (sa->sa_family == AF_INET) { + const struct sockaddr_in* sin = (struct sockaddr_in*)sa; + mos.write(&sin->sin_addr.s_addr, 4); + mos.writeRepeatedByte(0, 2); + mos.write(&sin->sin_port, 2); + mos.writeInt64BigEndian(offset); + } else { + const struct sockaddr_in6* sin6 = (struct sockaddr_in6*)sa; + mos.write(&sin6->sin6_addr, 16); + mos.writeRepeatedByte(0, 2); + mos.write(&sin6->sin6_port, 2); + mos.writeInt64BigEndian(offset); + } - const char* bytes = static_cast(outputmen.getData()); - int len = outputmen.getDataSize(); + const char* bytes = static_cast(mos.getData()); + int len = mos.getDataSize(); return UtilAll::bytes2string(bytes, len); } -MQMessageId MQDecoder::decodeMessageId(const std::string& msgId) { - std::string ipStr = msgId.substr(0, 8); - std::string portStr = msgId.substr(8, 8); - std::string offsetStr = msgId.substr(16); - - size_t pos; - int ipInt = std::stoul(ipStr, &pos, 16); - int portInt = std::stoul(portStr, &pos, 16); +MessageId MessageDecoder::decodeMessageId(const std::string& msgId) { + size_t ip_length = msgId.length() == 32 ? 4 * 2 : 16 * 2; - uint64_t offset = UtilAll::hexstr2ull(offsetStr.c_str()); + std::string ip = msgId.substr(0, ip_length); + std::string port = msgId.substr(ip_length, 8); + std::string offset = msgId.substr(ip_length + 8); - struct sockaddr_in sin; - sin.sin_family = AF_INET; - sin.sin_port = htons(portInt); - sin.sin_addr.s_addr = htonl(ipInt); + uint16_t portInt = (uint16_t)std::stoul(port, nullptr, 16); + uint64_t offsetInt = std::stoull(offset, nullptr, 16); - return MQMessageId((struct sockaddr*)&sin, offset); + if (ip_length == 32) { + int32_t ipInt = std::stoul(ip, nullptr, 16); + struct sockaddr_in sin; + sin.sin_family = AF_INET; + sin.sin_port = htons(portInt); + sin.sin_addr.s_addr = htonl(ipInt); + return MessageId((struct sockaddr*)&sin, offsetInt); + } else { + struct sockaddr_in6 sin6; + sin6.sin6_family = AF_INET6; + sin6.sin6_port = htons(portInt); + UtilAll::string2bytes((char*)&sin6.sin6_addr, ip); + return MessageId((struct sockaddr*)&sin6, offsetInt); + } } -MQMessageExtPtr MQDecoder::clientDecode(MemoryInputStream& byteBuffer, bool readBody) { +MessageExtPtr MessageDecoder::clientDecode(MemoryInputStream& byteBuffer, bool readBody) { return decode(byteBuffer, readBody, true, true); } -MQMessageExtPtr MQDecoder::decode(MemoryInputStream& byteBuffer, bool readBody) { +MessageExtPtr MessageDecoder::decode(MemoryInputStream& byteBuffer, bool readBody) { return decode(byteBuffer, readBody, true, false); } -MQMessageExtPtr MQDecoder::decode(MemoryInputStream& byteBuffer, bool readBody, bool deCompressBody, bool isClient) { - MQMessageExtPtr msgExt; - - if (isClient) { - msgExt = new MQMessageClientExt(); - } else { - msgExt = new MQMessageExt(); - } +MessageExtPtr MessageDecoder::decode(MemoryInputStream& byteBuffer, bool readBody, bool deCompressBody, bool isClient) { + auto msgExt = isClient ? std::make_shared() : std::make_shared(); // 1 TOTALSIZE int32_t storeSize = byteBuffer.readIntBigEndian(); @@ -194,7 +207,7 @@ MQMessageExtPtr MQDecoder::decode(MemoryInputStream& byteBuffer, bool readBody, // 18 msg ID std::string msgId = createMessageId(msgExt->getStoreHost(), (int64_t)msgExt->getCommitLogOffset()); - msgExt->MQMessageExt::setMsgId(msgId); + msgExt->MessageExtImpl::setMsgId(msgId); if (uncompress_failed) { LOG_WARN_NEW("can not uncompress message, id:{}", msgExt->getMsgId()); @@ -203,35 +216,33 @@ MQMessageExtPtr MQDecoder::decode(MemoryInputStream& byteBuffer, bool readBody, return msgExt; } -MQMessageExtPtr2 MQDecoder::decode(MemoryBlock& mem) { +MessageExtPtr MessageDecoder::decode(MemoryBlock& mem) { return decode(mem, true); } -MQMessageExtPtr2 MQDecoder::decode(MemoryBlock& mem, bool readBody) { +MessageExtPtr MessageDecoder::decode(MemoryBlock& mem, bool readBody) { MemoryInputStream rawInput(mem, true); - MQMessageExtPtr2 message(decode(rawInput, readBody)); - return message; + return decode(rawInput, readBody); } -std::vector MQDecoder::decodes(MemoryBlock& mem) { +std::vector MessageDecoder::decodes(MemoryBlock& mem) { return decodes(mem, true); } -std::vector MQDecoder::decodes(MemoryBlock& mem, bool readBody) { - std::vector msgExts; +std::vector MessageDecoder::decodes(MemoryBlock& mem, bool readBody) { + std::vector msgExts; MemoryInputStream rawInput(mem, true); while (rawInput.getNumBytesRemaining() > 0) { - auto* msgExt = clientDecode(rawInput, readBody); - if (msgExt != nullptr) { - msgExts.emplace_back(msgExt); - } else { + auto msgExt = clientDecode(rawInput, readBody); + if (nullptr == msgExt) { break; } + msgExts.emplace_back(msgExt); } return msgExts; } -std::string MQDecoder::messageProperties2String(const std::map& properties) { +std::string MessageDecoder::messageProperties2String(const std::map& properties) { std::string os; for (const auto& it : properties) { @@ -252,7 +263,7 @@ std::string MQDecoder::messageProperties2String(const std::map MQDecoder::string2messageProperties(const std::string& properties) { +std::map MessageDecoder::string2messageProperties(const std::string& properties) { std::vector out; UtilAll::Split(out, properties, PROPERTY_SEPARATOR); @@ -268,10 +279,10 @@ std::map MQDecoder::string2messageProperties(const std return map; } -std::string MQDecoder::encodeMessage(MQMessage& message) { +std::string MessageDecoder::encodeMessage(Message& message) { const std::string& body = message.getBody(); uint32_t bodyLen = body.length(); - std::string properties = MQDecoder::messageProperties2String(message.getProperties()); + std::string properties = MessageDecoder::messageProperties2String(message.getProperties()); uint16_t propertiesLength = (int16_t)properties.length(); uint32_t storeSize = 4 // 1 TOTALSIZE + 4 // 2 MAGICCODE @@ -315,10 +326,10 @@ std::string MQDecoder::encodeMessage(MQMessage& message) { return encodeMsg; } -std::string MQDecoder::encodeMessages(std::vector& msgs) { +std::string MessageDecoder::encodeMessages(std::vector& msgs) { std::string encodedBody; - for (auto* message : msgs) { - encodedBody.append(encodeMessage(*message)); + for (auto msg : msgs) { + encodedBody.append(encodeMessage(msg)); } return encodedBody; } diff --git a/src/message/MQDecoder.h b/src/message/MessageDecoder.h similarity index 62% rename from src/message/MQDecoder.h rename to src/message/MessageDecoder.h index 8b9eea3f5..2bc935a75 100644 --- a/src/message/MQDecoder.h +++ b/src/message/MessageDecoder.h @@ -14,46 +14,44 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MESSAGE_DECODER_H__ -#define __MESSAGE_DECODER_H__ - -#include -#include -#include +#ifndef ROCKETMQ_MESSAGE_MESSAGEDECODER_H_ +#define ROCKETMQ_MESSAGE_MESSAGEDECODER_H_ #include "MQClientException.h" #include "MQMessageExt.h" -#include "MQMessageId.h" +#include "MessageId.h" #include "MemoryInputStream.h" namespace rocketmq { -class MQDecoder { +class MessageDecoder { public: static std::string createMessageId(const struct sockaddr* sa, int64_t offset); - static MQMessageId decodeMessageId(const std::string& msgId); + static MessageId decodeMessageId(const std::string& msgId); - static MQMessageExtPtr2 decode(MemoryBlock& mem); - static MQMessageExtPtr2 decode(MemoryBlock& mem, bool readBody); + static MessageExtPtr decode(MemoryBlock& mem); + static MessageExtPtr decode(MemoryBlock& mem, bool readBody); - static std::vector decodes(MemoryBlock& mem); - static std::vector decodes(MemoryBlock& mem, bool readBody); + static std::vector decodes(MemoryBlock& mem); + static std::vector decodes(MemoryBlock& mem, bool readBody); static std::string messageProperties2String(const std::map& properties); static std::map string2messageProperties(const std::string& properties); - static std::string encodeMessage(MQMessage& message); - static std::string encodeMessages(std::vector& msgs); + static std::string encodeMessage(Message& message); + static std::string encodeMessages(std::vector& msgs); private: - static MQMessageExtPtr clientDecode(MemoryInputStream& byteBuffer, bool readBody); - static MQMessageExtPtr decode(MemoryInputStream& byteBuffer, bool readBody); - static MQMessageExtPtr decode(MemoryInputStream& byteBuffer, bool readBody, bool deCompressBody, bool isClient); + static MessageExtPtr clientDecode(MemoryInputStream& byteBuffer, bool readBody); + + static MessageExtPtr decode(MemoryInputStream& byteBuffer, bool readBody); + static MessageExtPtr decode(MemoryInputStream& byteBuffer, bool readBody, bool deCompressBody, bool isClient); public: static const char NAME_VALUE_SEPARATOR; static const char PROPERTY_SEPARATOR; static const int MSG_ID_LENGTH; + static int MessageMagicCodePostion; static int MessageFlagPostion; static int MessagePhysicOffsetPostion; @@ -62,4 +60,4 @@ class MQDecoder { } // namespace rocketmq -#endif // __MESSAGE_DECODER_H__ +#endif // ROCKETMQ_MESSAGE_MESSAGEDECODER_H_ diff --git a/src/message/MessageExtImpl.cpp b/src/message/MessageExtImpl.cpp new file mode 100644 index 000000000..ea36b3580 --- /dev/null +++ b/src/message/MessageExtImpl.cpp @@ -0,0 +1,214 @@ +/* + * 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 "MessageExtImpl.h" + +#include // std::stringstream + +#include "MessageClientIDSetter.h" +#include "MessageSysFlag.h" +#include "SocketUtil.h" +#include "UtilAll.h" + +namespace rocketmq { + +// ============================ +// MessageExtImpl +// ============================ + +MessageExtImpl::MessageExtImpl() : MessageExtImpl(0, 0, nullptr, 0, nullptr, null) {} + +MessageExtImpl::MessageExtImpl(int queueId, + int64_t bornTimestamp, + const struct sockaddr* bornHost, + int64_t storeTimestamp, + const struct sockaddr* storeHost, + const std::string& msgId) + : store_size_(0), + body_crc_(0), + queue_id_(queueId), + queue_offset_(0), + commit_log_offset_(0), + sys_flag_(0), + born_timestamp_(bornTimestamp), + born_host_(nullptr), + store_timestamp_(storeTimestamp), + store_host_(nullptr), + reconsume_times_(3), + prepared_transaction_offset_(0), + msg_id_(msgId) { + born_host_ = copySocketAddress(born_host_, bornHost); + store_host_ = copySocketAddress(store_host_, storeHost); +} + +MessageExtImpl::~MessageExtImpl() { + free(born_host_); + free(store_host_); +} + +TopicFilterType MessageExtImpl::parseTopicFilterType(int32_t sysFlag) { + if ((sysFlag & MessageSysFlag::MultiTagsFlag) == MessageSysFlag::MultiTagsFlag) { + return MULTI_TAG; + } + return SINGLE_TAG; +} + +int32_t MessageExtImpl::getStoreSize() const { + return store_size_; +} + +void MessageExtImpl::setStoreSize(int32_t storeSize) { + store_size_ = storeSize; +} + +int32_t MessageExtImpl::getBodyCRC() const { + return body_crc_; +} + +void MessageExtImpl::setBodyCRC(int32_t bodyCRC) { + body_crc_ = bodyCRC; +} + +int32_t MessageExtImpl::getQueueId() const { + return queue_id_; +} + +void MessageExtImpl::setQueueId(int32_t queueId) { + queue_id_ = queueId; +} + +int64_t MessageExtImpl::getQueueOffset() const { + return queue_offset_; +} + +void MessageExtImpl::setQueueOffset(int64_t queueOffset) { + queue_offset_ = queueOffset; +} + +int64_t MessageExtImpl::getCommitLogOffset() const { + return commit_log_offset_; +} + +void MessageExtImpl::setCommitLogOffset(int64_t physicOffset) { + commit_log_offset_ = physicOffset; +} + +int32_t MessageExtImpl::getSysFlag() const { + return sys_flag_; +} + +void MessageExtImpl::setSysFlag(int32_t sysFlag) { + sys_flag_ = sysFlag; +} + +int64_t MessageExtImpl::getBornTimestamp() const { + return born_timestamp_; +} + +void MessageExtImpl::setBornTimestamp(int64_t bornTimestamp) { + born_timestamp_ = bornTimestamp; +} + +const struct sockaddr* MessageExtImpl::getBornHost() const { + return born_host_; +} + +std::string MessageExtImpl::getBornHostString() const { + return socketAddress2String(born_host_); +} + +void MessageExtImpl::setBornHost(const struct sockaddr* bornHost) { + born_host_ = copySocketAddress(born_host_, bornHost); +} + +int64_t MessageExtImpl::getStoreTimestamp() const { + return store_timestamp_; +} + +void MessageExtImpl::setStoreTimestamp(int64_t storeTimestamp) { + store_timestamp_ = storeTimestamp; +} + +const struct sockaddr* MessageExtImpl::getStoreHost() const { + return store_host_; +} + +std::string MessageExtImpl::getStoreHostString() const { + return socketAddress2String(store_host_); +} + +void MessageExtImpl::setStoreHost(const struct sockaddr* storeHost) { + store_host_ = copySocketAddress(store_host_, storeHost); +} + +const std::string& MessageExtImpl::getMsgId() const { + return msg_id_; +} + +void MessageExtImpl::setMsgId(const std::string& msgId) { + msg_id_ = msgId; +} + +int32_t MessageExtImpl::getReconsumeTimes() const { + return reconsume_times_; +} + +void MessageExtImpl::setReconsumeTimes(int32_t reconsumeTimes) { + reconsume_times_ = reconsumeTimes; +} + +int64_t MessageExtImpl::getPreparedTransactionOffset() const { + return prepared_transaction_offset_; +} + +void MessageExtImpl::setPreparedTransactionOffset(int64_t preparedTransactionOffset) { + prepared_transaction_offset_ = preparedTransactionOffset; +} + +std::string MessageExtImpl::toString() const { + std::stringstream ss; + ss << "MessageExt [queueId=" << queue_id_ << ", storeSize=" << store_size_ << ", queueOffset=" << queue_offset_ + << ", sysFlag=" << sys_flag_ << ", bornTimestamp=" << born_timestamp_ << ", bornHost=" << getBornHostString() + << ", storeTimestamp=" << store_timestamp_ << ", storeHost=" << getStoreHostString() << ", msgId=" << getMsgId() + << ", commitLogOffset=" << commit_log_offset_ << ", bodyCRC=" << body_crc_ + << ", reconsumeTimes=" << reconsume_times_ << ", preparedTransactionOffset=" << prepared_transaction_offset_ + << ", toString()=" << MessageImpl::toString() << "]"; + return ss.str(); +} + +// ============================ +// MessageClientExtImpl +// ============================ + +const std::string& MessageClientExtImpl::getMsgId() const { + const auto& unique_id = MessageClientIDSetter::getUniqID(*this); + return unique_id.empty() ? getOffsetMsgId() : unique_id; +} + +void MessageClientExtImpl::setMsgId(const std::string& msgId) { + // DO NOTHING + // MessageClientIDSetter::setUniqID(*this); +} + +const std::string& MessageClientExtImpl::getOffsetMsgId() const { + return MessageExtImpl::getMsgId(); +} + +void MessageClientExtImpl::setOffsetMsgId(const std::string& offsetMsgId) { + return MessageExtImpl::setMsgId(offsetMsgId); +} + +} // namespace rocketmq diff --git a/src/message/MessageExtImpl.h b/src/message/MessageExtImpl.h new file mode 100644 index 000000000..af9e1ff7f --- /dev/null +++ b/src/message/MessageExtImpl.h @@ -0,0 +1,117 @@ +/* + * 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_MESSAGE_MESSAGEEXT_H_ +#define ROCKETMQ_MESSAGE_MESSAGEEXT_H_ + +#include "MessageExt.h" +#include "MessageImpl.h" +#include "TopicFilterType.h" + +namespace rocketmq { + +/** + * MessageExtImpl - MessageExt implement + */ +class MessageExtImpl : public MessageImpl, // base + virtual public MessageExt // interface +{ + public: + MessageExtImpl(); + MessageExtImpl(int queueId, + int64_t bornTimestamp, + const struct sockaddr* bornHost, + int64_t storeTimestamp, + const struct sockaddr* storeHost, + const std::string& msgId); + + virtual ~MessageExtImpl(); + + static TopicFilterType parseTopicFilterType(int32_t sysFlag); + + public: // MessageExt + int32_t getStoreSize() const override; + void setStoreSize(int32_t storeSize) override; + + int32_t getBodyCRC() const override; + void setBodyCRC(int32_t bodyCRC) override; + + int32_t getQueueId() const override; + void setQueueId(int32_t queueId) override; + + int64_t getQueueOffset() const override; + void setQueueOffset(int64_t queueOffset) override; + + int64_t getCommitLogOffset() const override; + void setCommitLogOffset(int64_t physicOffset) override; + + int32_t getSysFlag() const override; + void setSysFlag(int32_t sysFlag) override; + + int64_t getBornTimestamp() const override; + void setBornTimestamp(int64_t bornTimestamp) override; + + const struct sockaddr* getBornHost() const override; + std::string getBornHostString() const override; + void setBornHost(const struct sockaddr* bornHost) override; + + int64_t getStoreTimestamp() const override; + void setStoreTimestamp(int64_t storeTimestamp) override; + + const struct sockaddr* getStoreHost() const override; + std::string getStoreHostString() const override; + void setStoreHost(const struct sockaddr* storeHost) override; + + int32_t getReconsumeTimes() const override; + void setReconsumeTimes(int32_t reconsumeTimes) override; + + int64_t getPreparedTransactionOffset() const override; + void setPreparedTransactionOffset(int64_t preparedTransactionOffset) override; + + const std::string& getMsgId() const override; + void setMsgId(const std::string& msgId) override; + + std::string toString() const override; + + private: + int32_t store_size_; + int32_t body_crc_; + int32_t queue_id_; + int64_t queue_offset_; + int64_t commit_log_offset_; + int32_t sys_flag_; + int64_t born_timestamp_; + struct sockaddr* born_host_; + int64_t store_timestamp_; + struct sockaddr* store_host_; + int32_t reconsume_times_; + int64_t prepared_transaction_offset_; + std::string msg_id_; +}; + +class MessageClientExtImpl : public MessageExtImpl { + public: // MessageExt + const std::string& getMsgId() const override; + void setMsgId(const std::string& msgId) override; + + public: + const std::string& getOffsetMsgId() const; + void setOffsetMsgId(const std::string& offsetMsgId); +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_MESSAGE_MESSAGEEXT_H_ diff --git a/src/message/MessageId.h b/src/message/MessageId.h new file mode 100644 index 000000000..64e460380 --- /dev/null +++ b/src/message/MessageId.h @@ -0,0 +1,58 @@ +/* + * 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_MESSAGE_MESSAGEID_H_ +#define ROCKETMQ_MESSAGE_MESSAGEID_H_ + +#include + +#include "SocketUtil.h" +#include "UtilAll.h" + +namespace rocketmq { + +class MessageId { + public: + MessageId() : MessageId(nullptr, 0) {} + MessageId(struct sockaddr* address, int64_t offset) : address_(nullptr), offset_(offset) { setAddress(address); } + + MessageId(const MessageId& other) : MessageId(other.address_, other.offset_) {} + MessageId(MessageId&& other) : address_(other.address_), offset_(other.offset_) { other.address_ = nullptr; } + + virtual ~MessageId() { std::free(address_); } + + MessageId& operator=(const MessageId& other) { + if (&other != this) { + setAddress(other.address_); + this->offset_ = other.offset_; + } + return *this; + } + + const struct sockaddr* getAddress() const { return address_; } + void setAddress(struct sockaddr* address) { address_ = copySocketAddress(address_, address); } + + int64_t getOffset() const { return offset_; } + void setOffset(int64_t offset) { offset_ = offset; } + + private: + struct sockaddr* address_; + int64_t offset_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_MESSAGE_MESSAGEID_H_ diff --git a/src/message/MessageImpl.cpp b/src/message/MessageImpl.cpp new file mode 100644 index 000000000..f3f9def3b --- /dev/null +++ b/src/message/MessageImpl.cpp @@ -0,0 +1,187 @@ +/* + * 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 "MessageImpl.h" + +#include // std::move +#include // std::stringstream + +#include "MQMessageConst.h" +#include "MessageSysFlag.h" +#include "UtilAll.h" + +namespace rocketmq { + +MessageImpl::MessageImpl() : MessageImpl(null, null) {} + +MessageImpl::MessageImpl(const std::string& topic, const std::string& body) + : MessageImpl(topic, null, null, 0, body, true) {} + +MessageImpl::MessageImpl(const std::string& topic, + const std::string& tags, + const std::string& keys, + int32_t flag, + const std::string& body, + bool waitStoreMsgOK) + : topic_(topic), flag_(flag), body_(body) { + if (tags.length() > 0) { + setTags(tags); + } + + if (keys.length() > 0) { + setKeys(keys); + } + + setWaitStoreMsgOK(waitStoreMsgOK); +} + +MessageImpl::~MessageImpl() = default; + +const std::string& MessageImpl::getProperty(const std::string& name) const { + const auto& it = properties_.find(name); + if (it != properties_.end()) { + return it->second; + } + return null; +} + +void MessageImpl::putProperty(const std::string& name, const std::string& value) { + properties_[name] = value; +} + +void MessageImpl::clearProperty(const std::string& name) { + properties_.erase(name); +} + +const std::string& MessageImpl::getTopic() const { + return topic_; +} + +void MessageImpl::setTopic(const std::string& topic) { + topic_ = topic; +} + +void MessageImpl::setTopic(const char* body, int len) { + topic_.clear(); + topic_.append(body, len); +} + +const std::string& MessageImpl::getTags() const { + return getProperty(MQMessageConst::PROPERTY_TAGS); +} + +void MessageImpl::setTags(const std::string& tags) { + putProperty(MQMessageConst::PROPERTY_TAGS, tags); +} + +const std::string& MessageImpl::getKeys() const { + return getProperty(MQMessageConst::PROPERTY_KEYS); +} + +void MessageImpl::setKeys(const std::string& keys) { + putProperty(MQMessageConst::PROPERTY_KEYS, keys); +} + +void MessageImpl::setKeys(const std::vector& keys) { + if (keys.empty()) { + return; + } + + std::string strKeys; + auto it = keys.begin(); + strKeys += *it; + for (it++; it != keys.end(); it++) { + strKeys += MQMessageConst::KEY_SEPARATOR; + strKeys += *it; + } + + setKeys(strKeys); +} + +int MessageImpl::getDelayTimeLevel() const { + std::string tmp = getProperty(MQMessageConst::PROPERTY_DELAY_TIME_LEVEL); + if (!tmp.empty()) { + return atoi(tmp.c_str()); + } + return 0; +} + +void MessageImpl::setDelayTimeLevel(int level) { + putProperty(MQMessageConst::PROPERTY_DELAY_TIME_LEVEL, UtilAll::to_string(level)); +} + +bool MessageImpl::isWaitStoreMsgOK() const { + std::string tmp = getProperty(MQMessageConst::PROPERTY_WAIT_STORE_MSG_OK); + return tmp.empty() || UtilAll::stob(tmp); +} + +void MessageImpl::setWaitStoreMsgOK(bool waitStoreMsgOK) { + putProperty(MQMessageConst::PROPERTY_WAIT_STORE_MSG_OK, UtilAll::to_string(waitStoreMsgOK)); +} + +int32_t MessageImpl::getFlag() const { + return flag_; +} + +void MessageImpl::setFlag(int32_t flag) { + flag_ = flag; +} + +const std::string& MessageImpl::getBody() const { + return body_; +} + +void MessageImpl::setBody(const char* body, int len) { + body_.clear(); + body_.append(body, len); +} + +void MessageImpl::setBody(const std::string& body) { + body_ = body; +} + +void MessageImpl::setBody(std::string&& body) { + body_ = std::move(body); +} + +const std::string& MessageImpl::getTransactionId() const { + return transaction_id_; +} + +void MessageImpl::setTransactionId(const std::string& transactionId) { + transaction_id_ = transactionId; +} + +const std::map& MessageImpl::getProperties() const { + return properties_; +} + +void MessageImpl::setProperties(const std::map& properties) { + properties_ = properties; +} + +void MessageImpl::setProperties(std::map&& properties) { + properties_ = std::move(properties); +} + +std::string MessageImpl::toString() const { + std::stringstream ss; + ss << "Message [topic=" << topic_ << ", flag=" << flag_ << ", tag=" << getTags() << ", transactionId='" + << transaction_id_ + "']"; + return ss.str(); +} + +} // namespace rocketmq diff --git a/src/message/MessageImpl.h b/src/message/MessageImpl.h new file mode 100644 index 000000000..bc4424f34 --- /dev/null +++ b/src/message/MessageImpl.h @@ -0,0 +1,91 @@ +/* + * 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_MESSAGE_MESSAGEIMPL_H_ +#define ROCKETMQ_MESSAGE_MESSAGEIMPL_H_ + +#include "Message.h" +#include "noncopyable.h" + +namespace rocketmq { + +/** + * MessageImpl - Default Message implement + */ +class MessageImpl : public noncopyable, // base + virtual public Message // interface +{ + public: + MessageImpl(); + MessageImpl(const std::string& topic, const std::string& body); + MessageImpl(const std::string& topic, + const std::string& tags, + const std::string& keys, + int32_t flag, + const std::string& body, + bool waitStoreMsgOK); + + virtual ~MessageImpl(); + + const std::string& getProperty(const std::string& name) const override; + void putProperty(const std::string& name, const std::string& value) override; + void clearProperty(const std::string& name) override; + + const std::string& getTopic() const override; + void setTopic(const std::string& topic) override; + void setTopic(const char* body, int len) override; + + const std::string& getTags() const override; + void setTags(const std::string& tags) override; + + const std::string& getKeys() const override; + void setKeys(const std::string& keys) override; + void setKeys(const std::vector& keys) override; + + int getDelayTimeLevel() const override; + void setDelayTimeLevel(int level) override; + + bool isWaitStoreMsgOK() const override; + void setWaitStoreMsgOK(bool waitStoreMsgOK) override; + + int32_t getFlag() const override; + void setFlag(int32_t flag) override; + + const std::string& getBody() const override; + void setBody(const char* body, int len) override; + void setBody(const std::string& body) override; + void setBody(std::string&& body) override; + + const std::string& getTransactionId() const override; + void setTransactionId(const std::string& transactionId) override; + + const std::map& getProperties() const override; + void setProperties(const std::map& properties) override; + void setProperties(std::map&& properties) override; + + std::string toString() const override; + + protected: + std::string topic_; + int32_t flag_; + std::map properties_; + std::string body_; + std::string transaction_id_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_MESSAGE_MESSAGEIMPL_H_ diff --git a/src/message/MessageUtil.cpp b/src/message/MessageUtil.cpp index c5d283281..dc7e0a02e 100644 --- a/src/message/MessageUtil.cpp +++ b/src/message/MessageUtil.cpp @@ -16,45 +16,37 @@ */ #include "MessageUtil.h" -#include - #include "ClientErrorCode.h" -#include "MQMessageConst.h" +#include "MessageImpl.h" #include "MessageAccessor.h" +#include "MQMessageConst.h" #include "UtilAll.h" namespace rocketmq { -MQMessagePtr MessageUtil::createReplyMessage(const MQMessagePtr requestMessage, - const std::string& body) throw(MQClientException) { - if (requestMessage != nullptr) { - std::unique_ptr replyMessage(new MQMessage()); - const auto& cluster = requestMessage->getProperty(MQMessageConst::PROPERTY_CLUSTER); - const auto& replyTo = requestMessage->getProperty(MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT); - const auto& correlationId = requestMessage->getProperty(MQMessageConst::PROPERTY_CORRELATION_ID); - const auto& ttl = requestMessage->getProperty(MQMessageConst::PROPERTY_MESSAGE_TTL); - replyMessage->setBody(body); - if (!cluster.empty()) { - auto replyTopic = UtilAll::getReplyTopic(cluster); - replyMessage->setTopic(replyTopic); - MessageAccessor::putProperty(*replyMessage, MQMessageConst::PROPERTY_MESSAGE_TYPE, REPLY_MESSAGE_FLAG); - MessageAccessor::putProperty(*replyMessage, MQMessageConst::PROPERTY_CORRELATION_ID, correlationId); - MessageAccessor::putProperty(*replyMessage, MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT, replyTo); - MessageAccessor::putProperty(*replyMessage, MQMessageConst::PROPERTY_MESSAGE_TTL, ttl); - - return replyMessage.release(); - } else { - THROW_MQEXCEPTION(MQClientException, "create reply message fail, requestMessage error, property[" + - MQMessageConst::PROPERTY_CLUSTER + "] is null.", - ClientErrorCode::CREATE_REPLY_MESSAGE_EXCEPTION); - } +MQMessage MessageUtil::createReplyMessage(const Message& requestMessage, + const std::string& body) throw(MQClientException) { + const auto& cluster = requestMessage.getProperty(MQMessageConst::PROPERTY_CLUSTER); + if (!cluster.empty()) { + auto replyMessage = std::make_shared(UtilAll::getReplyTopic(cluster), body); + // set properties + MessageAccessor::putProperty(*replyMessage, MQMessageConst::PROPERTY_MESSAGE_TYPE, REPLY_MESSAGE_FLAG); + const auto& correlationId = requestMessage.getProperty(MQMessageConst::PROPERTY_CORRELATION_ID); + MessageAccessor::putProperty(*replyMessage, MQMessageConst::PROPERTY_CORRELATION_ID, correlationId); + const auto& replyTo = requestMessage.getProperty(MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT); + MessageAccessor::putProperty(*replyMessage, MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT, replyTo); + const auto& ttl = requestMessage.getProperty(MQMessageConst::PROPERTY_MESSAGE_TTL); + MessageAccessor::putProperty(*replyMessage, MQMessageConst::PROPERTY_MESSAGE_TTL, ttl); + return MQMessage(replyMessage); + } else { + THROW_MQEXCEPTION(MQClientException, "create reply message fail, requestMessage error, property[" + + MQMessageConst::PROPERTY_CLUSTER + "] is null.", + ClientErrorCode::CREATE_REPLY_MESSAGE_EXCEPTION); } - THROW_MQEXCEPTION(MQClientException, "create reply message fail, requestMessage cannot be null.", - ClientErrorCode::CREATE_REPLY_MESSAGE_EXCEPTION); } -const std::string& MessageUtil::getReplyToClient(const MQMessagePtr msg) { - return msg->getProperty(MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT); +const std::string& MessageUtil::getReplyToClient(const Message& msg) { + return msg.getProperty(MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT); } } // namespace rocketmq diff --git a/src/producer/DefaultMQProducer.cpp b/src/producer/DefaultMQProducer.cpp index ce7e1a56b..bf1c7ab81 100644 --- a/src/producer/DefaultMQProducer.cpp +++ b/src/producer/DefaultMQProducer.cpp @@ -51,65 +51,65 @@ void DefaultMQProducer::shutdown() { m_producerDelegate->shutdown(); } -SendResult DefaultMQProducer::send(MQMessagePtr msg) { +SendResult DefaultMQProducer::send(MQMessage& msg) { return m_producerDelegate->send(msg); } -SendResult DefaultMQProducer::send(MQMessagePtr msg, long timeout) { +SendResult DefaultMQProducer::send(MQMessage& msg, long timeout) { return m_producerDelegate->send(msg, timeout); } -SendResult DefaultMQProducer::send(MQMessagePtr msg, const MQMessageQueue& mq) { +SendResult DefaultMQProducer::send(MQMessage& msg, const MQMessageQueue& mq) { return m_producerDelegate->send(msg, mq); } -SendResult DefaultMQProducer::send(MQMessagePtr msg, const MQMessageQueue& mq, long timeout) { +SendResult DefaultMQProducer::send(MQMessage& msg, const MQMessageQueue& mq, long timeout) { return m_producerDelegate->send(msg, mq, timeout); } -void DefaultMQProducer::send(MQMessagePtr msg, SendCallback* sendCallback) noexcept { +void DefaultMQProducer::send(MQMessage& msg, SendCallback* sendCallback) noexcept { m_producerDelegate->send(msg, sendCallback, getSendMsgTimeout()); } -void DefaultMQProducer::send(MQMessagePtr msg, SendCallback* sendCallback, long timeout) noexcept { +void DefaultMQProducer::send(MQMessage& msg, SendCallback* sendCallback, long timeout) noexcept { m_producerDelegate->send(msg, sendCallback, timeout); } -void DefaultMQProducer::send(MQMessagePtr msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept { +void DefaultMQProducer::send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept { return m_producerDelegate->send(msg, mq, sendCallback); } -void DefaultMQProducer::send(MQMessagePtr msg, +void DefaultMQProducer::send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) noexcept { m_producerDelegate->send(msg, mq, sendCallback, timeout); } -void DefaultMQProducer::sendOneway(MQMessagePtr msg) { +void DefaultMQProducer::sendOneway(MQMessage& msg) { m_producerDelegate->sendOneway(msg); } -void DefaultMQProducer::sendOneway(MQMessagePtr msg, const MQMessageQueue& mq) { +void DefaultMQProducer::sendOneway(MQMessage& msg, const MQMessageQueue& mq) { m_producerDelegate->sendOneway(msg, mq); } -SendResult DefaultMQProducer::send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) { +SendResult DefaultMQProducer::send(MQMessage& msg, MessageQueueSelector* selector, void* arg) { return m_producerDelegate->send(msg, selector, arg); } -SendResult DefaultMQProducer::send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg, long timeout) { +SendResult DefaultMQProducer::send(MQMessage& msg, MessageQueueSelector* selector, void* arg, long timeout) { return m_producerDelegate->send(msg, selector, arg, timeout); } -void DefaultMQProducer::send(MQMessagePtr msg, +void DefaultMQProducer::send(MQMessage& msg, MessageQueueSelector* selector, void* arg, SendCallback* sendCallback) noexcept { return m_producerDelegate->send(msg, selector, arg, sendCallback); } -void DefaultMQProducer::send(MQMessagePtr msg, +void DefaultMQProducer::send(MQMessage& msg, MessageQueueSelector* selector, void* arg, SendCallback* sendCallback, @@ -117,32 +117,32 @@ void DefaultMQProducer::send(MQMessagePtr msg, m_producerDelegate->send(msg, selector, arg, sendCallback, timeout); } -void DefaultMQProducer::sendOneway(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) { +void DefaultMQProducer::sendOneway(MQMessage& msg, MessageQueueSelector* selector, void* arg) { m_producerDelegate->sendOneway(msg, selector, arg); } -TransactionSendResult DefaultMQProducer::sendMessageInTransaction(MQMessagePtr msg, void* arg) { +TransactionSendResult DefaultMQProducer::sendMessageInTransaction(MQMessage& msg, void* arg) { THROW_MQEXCEPTION(MQClientException, "sendMessageInTransaction not implement, please use TransactionMQProducer class", -1); } -SendResult DefaultMQProducer::send(std::vector& msgs) { +SendResult DefaultMQProducer::send(std::vector& msgs) { return m_producerDelegate->send(msgs); } -SendResult DefaultMQProducer::send(std::vector& msgs, long timeout) { +SendResult DefaultMQProducer::send(std::vector& msgs, long timeout) { return m_producerDelegate->send(msgs, timeout); } -SendResult DefaultMQProducer::send(std::vector& msgs, const MQMessageQueue& mq) { +SendResult DefaultMQProducer::send(std::vector& msgs, const MQMessageQueue& mq) { return m_producerDelegate->send(msgs, mq); } -SendResult DefaultMQProducer::send(std::vector& msgs, const MQMessageQueue& mq, long timeout) { +SendResult DefaultMQProducer::send(std::vector& msgs, const MQMessageQueue& mq, long timeout) { return m_producerDelegate->send(msgs, mq, timeout); } -MQMessagePtr DefaultMQProducer::request(MQMessagePtr msg, long timeout) { +MQMessage DefaultMQProducer::request(MQMessage& msg, long timeout) { return m_producerDelegate->request(msg, timeout); } diff --git a/src/producer/DefaultMQProducerImpl.cpp b/src/producer/DefaultMQProducerImpl.cpp index 3baa27614..4fea984ea 100644 --- a/src/producer/DefaultMQProducerImpl.cpp +++ b/src/producer/DefaultMQProducerImpl.cpp @@ -31,7 +31,7 @@ #include "MQClientException.h" #include "MQClientInstance.h" #include "MQClientManager.h" -#include "MQDecoder.h" +#include "MessageDecoder.h" #include "MQFaultStrategy.h" #include "MQProtos.h" #include "MessageBatch.h" @@ -79,9 +79,8 @@ void DefaultMQProducerImpl::start() { bool registerOK = m_clientInstance->registerProducer(m_producerConfig->getGroupName(), this); if (!registerOK) { m_serviceState = CREATE_JUST; - THROW_MQEXCEPTION(MQClientException, - "The producer group[" + m_producerConfig->getGroupName() + - "] has been created before, specify another name please.", + THROW_MQEXCEPTION(MQClientException, "The producer group[" + m_producerConfig->getGroupName() + + "] has been created before, specify another name please.", -1); } @@ -130,13 +129,13 @@ void DefaultMQProducerImpl::destroyTransactionEnv() { m_checkTransactionExecutor->shutdown(); } -SendResult DefaultMQProducerImpl::send(MQMessagePtr msg) { +SendResult DefaultMQProducerImpl::send(MQMessage& msg) { return send(msg, m_producerConfig->getSendMsgTimeout()); } -SendResult DefaultMQProducerImpl::send(MQMessagePtr msg, long timeout) { +SendResult DefaultMQProducerImpl::send(MQMessage& msg, long timeout) { try { - std::unique_ptr sendResult(sendDefaultImpl(msg, ComMode_SYNC, nullptr, timeout)); + std::unique_ptr sendResult(sendDefaultImpl(msg.getMessageImpl(), ComMode_SYNC, nullptr, timeout)); return *sendResult; } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); @@ -144,19 +143,20 @@ SendResult DefaultMQProducerImpl::send(MQMessagePtr msg, long timeout) { } } -SendResult DefaultMQProducerImpl::send(MQMessagePtr msg, const MQMessageQueue& mq) { +SendResult DefaultMQProducerImpl::send(MQMessage& msg, const MQMessageQueue& mq) { return send(msg, mq, m_producerConfig->getSendMsgTimeout()); } -SendResult DefaultMQProducerImpl::send(MQMessagePtr msg, const MQMessageQueue& mq, long timeout) { - Validators::checkMessage(*msg, m_producerConfig->getMaxMessageSize()); +SendResult DefaultMQProducerImpl::send(MQMessage& msg, const MQMessageQueue& mq, long timeout) { + Validators::checkMessage(msg, m_producerConfig->getMaxMessageSize()); - if (msg->getTopic() != mq.getTopic()) { + if (msg.getTopic() != mq.getTopic()) { THROW_MQEXCEPTION(MQClientException, "message's topic not equal mq's topic", -1); } try { - std::unique_ptr sendResult(sendKernelImpl(msg, mq, ComMode_SYNC, nullptr, nullptr, timeout)); + std::unique_ptr sendResult( + sendKernelImpl(msg.getMessageImpl(), mq, ComMode_SYNC, nullptr, nullptr, timeout)); return *sendResult; } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); @@ -164,13 +164,13 @@ SendResult DefaultMQProducerImpl::send(MQMessagePtr msg, const MQMessageQueue& m } } -void DefaultMQProducerImpl::send(MQMessagePtr msg, SendCallback* sendCallback) noexcept { +void DefaultMQProducerImpl::send(MQMessage& msg, SendCallback* sendCallback) noexcept { return send(msg, sendCallback, m_producerConfig->getSendMsgTimeout()); } -void DefaultMQProducerImpl::send(MQMessagePtr msg, SendCallback* sendCallback, long timeout) noexcept { +void DefaultMQProducerImpl::send(MQMessage& msg, SendCallback* sendCallback, long timeout) noexcept { try { - (void)sendDefaultImpl(msg, ComMode_ASYNC, sendCallback, timeout); + (void)sendDefaultImpl(msg.getMessageImpl(), ComMode_ASYNC, sendCallback, timeout); } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); sendCallback->onException(e); @@ -183,23 +183,23 @@ void DefaultMQProducerImpl::send(MQMessagePtr msg, SendCallback* sendCallback, l } } -void DefaultMQProducerImpl::send(MQMessagePtr msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept { +void DefaultMQProducerImpl::send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept { return send(msg, mq, sendCallback, m_producerConfig->getSendMsgTimeout()); } -void DefaultMQProducerImpl::send(MQMessagePtr msg, +void DefaultMQProducerImpl::send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) noexcept { try { - Validators::checkMessage(*msg, m_producerConfig->getMaxMessageSize()); + Validators::checkMessage(msg, m_producerConfig->getMaxMessageSize()); - if (msg->getTopic() != mq.getTopic()) { + if (msg.getTopic() != mq.getTopic()) { THROW_MQEXCEPTION(MQClientException, "message's topic not equal mq's topic", -1); } try { - sendKernelImpl(msg, mq, ComMode_ASYNC, sendCallback, nullptr, timeout); + sendKernelImpl(msg.getMessageImpl(), mq, ComMode_ASYNC, sendCallback, nullptr, timeout); } catch (MQBrokerException& e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); @@ -216,37 +216,38 @@ void DefaultMQProducerImpl::send(MQMessagePtr msg, } } -void DefaultMQProducerImpl::sendOneway(MQMessagePtr msg) { +void DefaultMQProducerImpl::sendOneway(MQMessage& msg) { try { - sendDefaultImpl(msg, ComMode_ONEWAY, nullptr, m_producerConfig->getSendMsgTimeout()); + sendDefaultImpl(msg.getMessageImpl(), ComMode_ONEWAY, nullptr, m_producerConfig->getSendMsgTimeout()); } catch (MQBrokerException e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); } } -void DefaultMQProducerImpl::sendOneway(MQMessagePtr msg, const MQMessageQueue& mq) { - Validators::checkMessage(*msg, m_producerConfig->getMaxMessageSize()); +void DefaultMQProducerImpl::sendOneway(MQMessage& msg, const MQMessageQueue& mq) { + Validators::checkMessage(msg, m_producerConfig->getMaxMessageSize()); - if (msg->getTopic() != mq.getTopic()) { + if (msg.getTopic() != mq.getTopic()) { THROW_MQEXCEPTION(MQClientException, "message's topic not equal mq's topic", -1); } try { - sendKernelImpl(msg, mq, ComMode_ONEWAY, nullptr, nullptr, m_producerConfig->getSendMsgTimeout()); + sendKernelImpl(msg.getMessageImpl(), mq, ComMode_ONEWAY, nullptr, nullptr, m_producerConfig->getSendMsgTimeout()); } catch (MQBrokerException e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); } } -SendResult DefaultMQProducerImpl::send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) { +SendResult DefaultMQProducerImpl::send(MQMessage& msg, MessageQueueSelector* selector, void* arg) { return send(msg, selector, arg, m_producerConfig->getSendMsgTimeout()); } -SendResult DefaultMQProducerImpl::send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg, long timeout) { +SendResult DefaultMQProducerImpl::send(MQMessage& msg, MessageQueueSelector* selector, void* arg, long timeout) { try { - std::unique_ptr result(sendSelectImpl(msg, selector, arg, ComMode_SYNC, nullptr, timeout)); + std::unique_ptr result( + sendSelectImpl(msg.getMessageImpl(), selector, arg, ComMode_SYNC, nullptr, timeout)); return *result.get(); } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); @@ -254,21 +255,21 @@ SendResult DefaultMQProducerImpl::send(MQMessagePtr msg, MessageQueueSelector* s } } -void DefaultMQProducerImpl::send(MQMessagePtr msg, +void DefaultMQProducerImpl::send(MQMessage& msg, MessageQueueSelector* selector, void* arg, SendCallback* sendCallback) noexcept { return send(msg, selector, arg, sendCallback, m_producerConfig->getSendMsgTimeout()); } -void DefaultMQProducerImpl::send(MQMessagePtr msg, +void DefaultMQProducerImpl::send(MQMessage& msg, MessageQueueSelector* selector, void* arg, SendCallback* sendCallback, long timeout) noexcept { try { try { - sendSelectImpl(msg, selector, arg, ComMode_ASYNC, sendCallback, timeout); + sendSelectImpl(msg.getMessageImpl(), selector, arg, ComMode_ASYNC, sendCallback, timeout); } catch (MQBrokerException& e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); @@ -285,19 +286,19 @@ void DefaultMQProducerImpl::send(MQMessagePtr msg, } } -void DefaultMQProducerImpl::sendOneway(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) { +void DefaultMQProducerImpl::sendOneway(MQMessage& msg, MessageQueueSelector* selector, void* arg) { try { - sendSelectImpl(msg, selector, arg, ComMode_ONEWAY, nullptr, m_producerConfig->getSendMsgTimeout()); + sendSelectImpl(msg.getMessageImpl(), selector, arg, ComMode_ONEWAY, nullptr, m_producerConfig->getSendMsgTimeout()); } catch (MQBrokerException e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); } } -TransactionSendResult DefaultMQProducerImpl::sendMessageInTransaction(MQMessagePtr msg, void* arg) { +TransactionSendResult DefaultMQProducerImpl::sendMessageInTransaction(MQMessage& msg, void* arg) { try { std::unique_ptr sendResult( - sendMessageInTransactionImpl(msg, arg, m_producerConfig->getSendMsgTimeout())); + sendMessageInTransactionImpl(msg.getMessageImpl(), arg, m_producerConfig->getSendMsgTimeout())); return *sendResult; } catch (MQException& e) { LOG_ERROR_NEW("sendMessageInTransaction failed, exception:{}", e.what()); @@ -305,39 +306,39 @@ TransactionSendResult DefaultMQProducerImpl::sendMessageInTransaction(MQMessageP } } -SendResult DefaultMQProducerImpl::send(std::vector& msgs) { - std::unique_ptr batchMessage(batch(msgs)); - return send(batchMessage.get()); +SendResult DefaultMQProducerImpl::send(std::vector& msgs) { + MQMessage batchMessage(batch(msgs)); + return send(batchMessage); } -SendResult DefaultMQProducerImpl::send(std::vector& msgs, long timeout) { - std::unique_ptr batchMessage(batch(msgs)); - return send(batchMessage.get(), timeout); +SendResult DefaultMQProducerImpl::send(std::vector& msgs, long timeout) { + MQMessage batchMessage(batch(msgs)); + return send(batchMessage, timeout); } -SendResult DefaultMQProducerImpl::send(std::vector& msgs, const MQMessageQueue& mq) { - std::unique_ptr batchMessage(batch(msgs)); - return send(batchMessage.get(), mq); +SendResult DefaultMQProducerImpl::send(std::vector& msgs, const MQMessageQueue& mq) { + MQMessage batchMessage(batch(msgs)); + return send(batchMessage, mq); } -SendResult DefaultMQProducerImpl::send(std::vector& msgs, const MQMessageQueue& mq, long timeout) { - std::unique_ptr batchMessage(batch(msgs)); - return send(batchMessage.get(), mq, timeout); +SendResult DefaultMQProducerImpl::send(std::vector& msgs, const MQMessageQueue& mq, long timeout) { + MQMessage batchMessage(batch(msgs)); + return send(batchMessage, mq, timeout); } -MessageBatch* DefaultMQProducerImpl::batch(std::vector& msgs) { +MessagePtr DefaultMQProducerImpl::batch(std::vector& msgs) { if (msgs.size() < 1) { THROW_MQEXCEPTION(MQClientException, "msgs need one message at least", -1); } try { - std::unique_ptr msgBatch(MessageBatch::generateFromList(msgs)); - for (auto& message : msgBatch->getMessages()) { - Validators::checkMessage(*message, m_producerConfig->getMaxMessageSize()); - MessageClientIDSetter::setUniqID(*message); + auto messageBatch = MessageBatch::generateFromList(msgs); + for (auto& message : messageBatch->getMessages()) { + Validators::checkMessage(message, m_producerConfig->getMaxMessageSize()); + MessageClientIDSetter::setUniqID(const_cast(message)); } - msgBatch->setBody(msgBatch->encode()); - return msgBatch.release(); + messageBatch->setBody(messageBatch->encode()); + return messageBatch; } catch (std::exception& e) { THROW_MQEXCEPTION(MQClientException, "Failed to initiate the MessageBatch", -1); } @@ -359,29 +360,29 @@ class RequestSendCallback : public AutoDeleteSendCallback { std::shared_ptr m_requestFuture; }; -MQMessagePtr DefaultMQProducerImpl::request(MQMessagePtr msg, long timeout) { +MQMessage DefaultMQProducerImpl::request(MQMessage& msg, long timeout) { auto beginTimestamp = UtilAll::currentTimeMillis(); prepareSendRequest(msg, timeout); - const auto& correlationId = msg->getProperty(MQMessageConst::PROPERTY_CORRELATION_ID); + const auto& correlationId = msg.getProperty(MQMessageConst::PROPERTY_CORRELATION_ID); std::exception_ptr eptr = nullptr; - std::unique_ptr responseMessage; + MessagePtr responseMessage; try { auto requestResponseFuture = std::make_shared(correlationId, timeout, nullptr); RequestFutureTable::putRequestFuture(correlationId, requestResponseFuture); auto cost = UtilAll::currentTimeMillis() - beginTimestamp; - sendDefaultImpl(msg, CommunicationMode::ComMode_ASYNC, new RequestSendCallback(requestResponseFuture), - timeout - cost); + sendDefaultImpl(msg.getMessageImpl(), CommunicationMode::ComMode_ASYNC, + new RequestSendCallback(requestResponseFuture), timeout - cost); - responseMessage.reset(requestResponseFuture->waitResponseMessage(timeout - cost)); + responseMessage = requestResponseFuture->waitResponseMessage(timeout - cost); if (responseMessage == nullptr) { if (requestResponseFuture->isSendRequestOk()) { - std::string info = "send request message to <" + msg->getTopic() + "> OK, but wait reply message timeout, " + + std::string info = "send request message to <" + msg.getTopic() + "> OK, but wait reply message timeout, " + UtilAll::to_string(timeout) + " ms."; THROW_MQEXCEPTION(RequestTimeoutException, info, ClientErrorCode::REQUEST_TIMEOUT_EXCEPTION); } else { - std::string info = "send request message to <" + msg->getTopic() + "> fail"; + std::string info = "send request message to <" + msg.getTopic() + "> fail"; THROW_MQEXCEPTION2(MQClientException, info, -1, requestResponseFuture->getCause()); } } @@ -396,24 +397,24 @@ MQMessagePtr DefaultMQProducerImpl::request(MQMessagePtr msg, long timeout) { std::rethrow_exception(eptr); } - return responseMessage.release(); + return MQMessage(responseMessage); } -void DefaultMQProducerImpl::prepareSendRequest(MQMessagePtr msg, long timeout) { +void DefaultMQProducerImpl::prepareSendRequest(Message& msg, long timeout) { const auto correlationId = CorrelationIdUtil::createCorrelationId(); const auto& requestClientId = m_clientInstance->getClientId(); - MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_CORRELATION_ID, correlationId); - MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT, requestClientId); - MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_MESSAGE_TTL, UtilAll::to_string(timeout)); + MessageAccessor::putProperty(msg, MQMessageConst::PROPERTY_CORRELATION_ID, correlationId); + MessageAccessor::putProperty(msg, MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT, requestClientId); + MessageAccessor::putProperty(msg, MQMessageConst::PROPERTY_MESSAGE_TTL, UtilAll::to_string(timeout)); - auto hasRouteData = m_clientInstance->getTopicRouteData(msg->getTopic()) != nullptr; + auto hasRouteData = m_clientInstance->getTopicRouteData(msg.getTopic()) != nullptr; if (!hasRouteData) { auto beginTimestamp = UtilAll::currentTimeMillis(); - m_clientInstance->tryToFindTopicPublishInfo(msg->getTopic()); + m_clientInstance->tryToFindTopicPublishInfo(msg.getTopic()); m_clientInstance->sendHeartbeatToAllBrokerWithLock(); auto cost = UtilAll::currentTimeMillis() - beginTimestamp; if (cost > 500) { - LOG_WARN_NEW("prepare send request for <{}> cost {} ms", msg->getTopic(), cost); + LOG_WARN_NEW("prepare send request for <{}> cost {} ms", msg.getTopic(), cost); } } } @@ -427,7 +428,7 @@ void DefaultMQProducerImpl::updateFaultItem(const std::string& brokerName, const m_mqFaultStrategy->updateFaultItem(brokerName, currentLatency, isolation); } -SendResult* DefaultMQProducerImpl::sendDefaultImpl(MQMessagePtr msg, +SendResult* DefaultMQProducerImpl::sendDefaultImpl(MessagePtr msg, CommunicationMode communicationMode, SendCallback* sendCallback, long timeout) { @@ -495,15 +496,15 @@ SendResult* DefaultMQProducerImpl::sendDefaultImpl(MQMessagePtr msg, } std::string info = "Send [" + UtilAll::to_string(times) + "] times, still failed, cost [" + - UtilAll::to_string(UtilAll::currentTimeMillis() - beginTimestampFirst) + - "]ms, Topic: " + msg->getTopic(); + UtilAll::to_string(UtilAll::currentTimeMillis() - beginTimestampFirst) + "]ms, Topic: " + + msg->getTopic(); THROW_MQEXCEPTION(MQClientException, info, -1); } THROW_MQEXCEPTION(MQClientException, "No route info of this topic: " + msg->getTopic(), -1); } -SendResult* DefaultMQProducerImpl::sendKernelImpl(MQMessagePtr msg, +SendResult* DefaultMQProducerImpl::sendKernelImpl(MessagePtr msg, const MQMessageQueue& mq, CommunicationMode communicationMode, SendCallback* sendCallback, @@ -547,7 +548,7 @@ SendResult* DefaultMQProducerImpl::sendKernelImpl(MQMessagePtr msg, requestHeader->sysFlag = sysFlag; requestHeader->bornTimestamp = UtilAll::currentTimeMillis(); requestHeader->flag = msg->getFlag(); - requestHeader->properties = MQDecoder::messageProperties2String(msg->getProperties()); + requestHeader->properties = MessageDecoder::messageProperties2String(msg->getProperties()); requestHeader->reconsumeTimes = 0; requestHeader->unitMode = false; requestHeader->batch = msg->isBatch(); @@ -601,7 +602,7 @@ SendResult* DefaultMQProducerImpl::sendKernelImpl(MQMessagePtr msg, THROW_MQEXCEPTION(MQClientException, "The broker[" + mq.getBrokerName() + "] not exist", -1); } -SendResult* DefaultMQProducerImpl::sendSelectImpl(MQMessagePtr msg, +SendResult* DefaultMQProducerImpl::sendSelectImpl(MessagePtr msg, MessageQueueSelector* selector, void* arg, CommunicationMode communicationMode, @@ -612,7 +613,7 @@ SendResult* DefaultMQProducerImpl::sendSelectImpl(MQMessagePtr msg, TopicPublishInfoPtr topicPublishInfo = m_clientInstance->tryToFindTopicPublishInfo(msg->getTopic()); if (topicPublishInfo != nullptr && topicPublishInfo->ok()) { - MQMessageQueue mq = selector->select(topicPublishInfo->getMessageQueueList(), *msg, arg); + MQMessageQueue mq = selector->select(topicPublishInfo->getMessageQueueList(), MQMessage(msg), arg); auto costTime = UtilAll::currentTimeMillis() - beginStartTime; if (timeout < costTime) { @@ -626,7 +627,7 @@ SendResult* DefaultMQProducerImpl::sendSelectImpl(MQMessagePtr msg, THROW_MQEXCEPTION(MQClientException, info, -1); } -TransactionSendResult* DefaultMQProducerImpl::sendMessageInTransactionImpl(MQMessagePtr msg, void* arg, long timeout) { +TransactionSendResult* DefaultMQProducerImpl::sendMessageInTransactionImpl(MessagePtr msg, void* arg, long timeout) { auto* transactionListener = getCheckListener(); if (nullptr == transactionListener) { THROW_MQEXCEPTION(MQClientException, "transactionListener is null", -1); @@ -653,7 +654,7 @@ TransactionSendResult* DefaultMQProducerImpl::sendMessageInTransactionImpl(MQMes if (!transactionId.empty()) { msg->setTransactionId(transactionId); } - localTransactionState = transactionListener->executeLocalTransaction(*msg, arg); + localTransactionState = transactionListener->executeLocalTransaction(MQMessage(msg), arg); if (localTransactionState != LocalTransactionState::COMMIT_MESSAGE) { LOG_INFO_NEW("executeLocalTransaction return not COMMIT_MESSAGE, msg:{}", msg->toString()); } @@ -695,7 +696,7 @@ TransactionListener* DefaultMQProducerImpl::getCheckListener() { }; void DefaultMQProducerImpl::checkTransactionState(const std::string& addr, - MQMessageExtPtr2 msg, + MessageExtPtr msg, CheckTransactionStateRequestHeader* checkRequestHeader) { long tranStateTableOffset = checkRequestHeader->tranStateTableOffset; long commitLogOffset = checkRequestHeader->commitLogOffset; @@ -709,7 +710,7 @@ void DefaultMQProducerImpl::checkTransactionState(const std::string& addr, } void DefaultMQProducerImpl::checkTransactionStateImpl(const std::string& addr, - MQMessageExtPtr2 message, + MessageExtPtr message, long tranStateTableOffset, long commitLogOffset, const std::string& msgId, @@ -725,7 +726,7 @@ void DefaultMQProducerImpl::checkTransactionStateImpl(const std::string& addr, LocalTransactionState localTransactionState = UNKNOWN; std::exception_ptr exception = nullptr; try { - localTransactionState = transactionCheckListener->checkLocalTransaction(*message); + localTransactionState = transactionCheckListener->checkLocalTransaction(MQMessageExt(message)); } catch (MQException& e) { LOG_ERROR_NEW("Broker call checkTransactionState, but checkLocalTransactionState exception, {}", e.what()); exception = std::current_exception(); @@ -775,12 +776,8 @@ void DefaultMQProducerImpl::checkTransactionStateImpl(const std::string& addr, void DefaultMQProducerImpl::endTransaction(SendResult& sendResult, LocalTransactionState localTransactionState, std::exception_ptr& localException) { - MQMessageId id; - if (!sendResult.getOffsetMsgId().empty()) { - id = MQDecoder::decodeMessageId(sendResult.getOffsetMsgId()); - } else { - id = MQDecoder::decodeMessageId(sendResult.getMsgId()); - } + const auto& msg_id = !sendResult.getOffsetMsgId().empty() ? sendResult.getOffsetMsgId() : sendResult.getMsgId(); + auto id = MessageDecoder::decodeMessageId(msg_id); const auto& transactionId = sendResult.getTransactionId(); std::string brokerAddr = m_clientInstance->findBrokerAddressInPublish(sendResult.getMessageQueue().getBrokerName()); EndTransactionRequestHeader* requestHeader = new EndTransactionRequestHeader(); @@ -810,7 +807,7 @@ void DefaultMQProducerImpl::endTransaction(SendResult& sendResult, m_clientInstance->getMQClientAPIImpl()->endTransactionOneway(brokerAddr, requestHeader, remark); } -bool DefaultMQProducerImpl::tryToCompressMessage(MQMessage& msg) { +bool DefaultMQProducerImpl::tryToCompressMessage(Message& msg) { if (msg.isBatch()) { // batch dose not support compressing right now return false; diff --git a/src/producer/DefaultMQProducerImpl.h b/src/producer/DefaultMQProducerImpl.h index 4a2f27385..0b1a93a9a 100644 --- a/src/producer/DefaultMQProducerImpl.h +++ b/src/producer/DefaultMQProducerImpl.h @@ -57,48 +57,48 @@ class DefaultMQProducerImpl : public std::enable_shared_from_this& msgs) override; - SendResult send(std::vector& msgs, long timeout) override; - SendResult send(std::vector& msgs, const MQMessageQueue& mq) override; - SendResult send(std::vector& msgs, const MQMessageQueue& mq, long timeout) override; + SendResult send(std::vector& msgs) override; + SendResult send(std::vector& msgs, long timeout) override; + SendResult send(std::vector& msgs, const MQMessageQueue& mq) override; + SendResult send(std::vector& msgs, const MQMessageQueue& mq, long timeout) override; - MQMessagePtr request(MQMessagePtr msg, long timeout) override; + MQMessage request(MQMessage& msg, long timeout) override; public: // MQProducerInner TransactionListener* getCheckListener() override; void checkTransactionState(const std::string& addr, - MQMessageExtPtr2 msg, + MessageExtPtr msg, CheckTransactionStateRequestHeader* checkRequestHeader) override; public: @@ -116,37 +116,37 @@ class DefaultMQProducerImpl : public std::enable_shared_from_this topicPublishInfo, long timeout); - SendResult* sendSelectImpl(MQMessagePtr msg, + SendResult* sendSelectImpl(MessagePtr msg, MessageQueueSelector* selector, void* arg, CommunicationMode communicationMode, SendCallback* sendCallback, long timeout); - TransactionSendResult* sendMessageInTransactionImpl(MQMessagePtr msg, void* arg, long timeout); + TransactionSendResult* sendMessageInTransactionImpl(MessagePtr msg, void* arg, long timeout); void checkTransactionStateImpl(const std::string& addr, - MQMessageExtPtr2 message, + MessageExtPtr message, long tranStateTableOffset, long commitLogOffset, const std::string& msgId, const std::string& transactionId, const std::string& offsetMsgId); - bool tryToCompressMessage(MQMessage& msg); + bool tryToCompressMessage(Message& msg); - MessageBatch* batch(std::vector& msgs); + MessagePtr batch(std::vector& msgs); - void prepareSendRequest(MQMessagePtr msg, long timeout); + void prepareSendRequest(Message& msg, long timeout); private: DefaultMQProducerConfigPtr m_producerConfig; diff --git a/src/producer/MQProducerInner.h b/src/producer/MQProducerInner.h index 6e3bede6c..c0538c33a 100644 --- a/src/producer/MQProducerInner.h +++ b/src/producer/MQProducerInner.h @@ -31,7 +31,7 @@ class MQProducerInner { virtual TransactionListener* getCheckListener() = 0; virtual void checkTransactionState(const std::string& addr, - MQMessageExtPtr2 msg, + MessageExtPtr msg, CheckTransactionStateRequestHeader* checkRequestHeader) = 0; // virtual std::vector getPublishTopicList() = 0; diff --git a/src/producer/RequestResponseFuture.cpp b/src/producer/RequestResponseFuture.cpp index 92e86a403..c3b28f935 100644 --- a/src/producer/RequestResponseFuture.cpp +++ b/src/producer/RequestResponseFuture.cpp @@ -68,17 +68,17 @@ bool RequestResponseFuture::isTimeout() { return diff > m_timeoutMillis; } -MQMessagePtr RequestResponseFuture::waitResponseMessage(int64_t timeout) { +MessagePtr RequestResponseFuture::waitResponseMessage(int64_t timeout) { if (m_countDownLatch != nullptr) { if (timeout < 0) { timeout = 0; } m_countDownLatch->wait(timeout, time_unit::milliseconds); } - return m_responseMsg.release(); + return m_responseMsg; } -void RequestResponseFuture::putResponseMessage(MQMessagePtr3 responseMsg) { +void RequestResponseFuture::putResponseMessage(MessagePtr responseMsg) { m_responseMsg = std::move(responseMsg); if (m_countDownLatch != nullptr) { m_countDownLatch->count_down(); diff --git a/src/producer/RequestResponseFuture.h b/src/producer/RequestResponseFuture.h index 0ebb2351d..d4e3e6825 100644 --- a/src/producer/RequestResponseFuture.h +++ b/src/producer/RequestResponseFuture.h @@ -20,7 +20,7 @@ #include #include -#include "MQMessage.h" +#include "Message.h" #include "RequestCallback.h" #include "concurrent/latch.hpp" @@ -34,8 +34,8 @@ class RequestResponseFuture { bool isTimeout(); - MQMessagePtr waitResponseMessage(int64_t timeout); - void putResponseMessage(MQMessagePtr3 responseMsg); + MessagePtr waitResponseMessage(int64_t timeout); + void putResponseMessage(MessagePtr responseMsg); bool isSendRequestOk(); void setSendRequestOk(bool sendRequestOk); @@ -47,10 +47,10 @@ class RequestResponseFuture { std::string m_correlationId; RequestCallback* m_requestCallback; uint64_t m_beginTimestamp; - MQMessagePtr m_requestMsg; + MessagePtr m_requestMsg; long m_timeoutMillis; std::unique_ptr m_countDownLatch; // use for synchronization rpc - MQMessagePtr3 m_responseMsg; + MessagePtr m_responseMsg; bool m_sendRequestOk; std::exception_ptr m_cause; }; diff --git a/src/producer/TransactionMQProducer.cpp b/src/producer/TransactionMQProducer.cpp index b258dadd0..cd2e6a770 100644 --- a/src/producer/TransactionMQProducer.cpp +++ b/src/producer/TransactionMQProducer.cpp @@ -54,7 +54,7 @@ void TransactionMQProducer::shutdown() { std::dynamic_pointer_cast(m_producerDelegate)->destroyTransactionEnv(); } -TransactionSendResult TransactionMQProducer::sendMessageInTransaction(MQMessagePtr msg, void* arg) { +TransactionSendResult TransactionMQProducer::sendMessageInTransaction(MQMessage& msg, void* arg) { return m_producerDelegate->sendMessageInTransaction(msg, arg); } diff --git a/src/transport/SocketUtil.cpp b/src/transport/SocketUtil.cpp index e114128b6..e4810d8d5 100644 --- a/src/transport/SocketUtil.cpp +++ b/src/transport/SocketUtil.cpp @@ -16,12 +16,14 @@ */ #include "SocketUtil.h" -#include +#include // std::realloc +#include // std::memset, std::memcpy -#include #include #include +#include + #ifndef WIN32 #include #include @@ -113,7 +115,7 @@ struct sockaddr* lookupNameServers(const std::string& hostname) { struct evutil_addrinfo* answer = NULL; /* Build the hints to tell getaddrinfo how to act. */ - memset(&hints, 0, sizeof(hints)); + std::memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; /* v4 or v6 is fine. */ hints.ai_socktype = SOCK_STREAM; /* We want stream socket*/ hints.ai_protocol = IPPROTO_TCP; /* We want a TCP socket */ @@ -134,7 +136,7 @@ struct sockaddr* lookupNameServers(const std::string& hostname) { continue; } sin = (struct sockaddr*)&sin_buf; - memcpy(sin, ai_addr, sockaddr_size(ai_addr)); + std::memcpy(sin, ai_addr, sockaddr_size(ai_addr)); break; } @@ -146,9 +148,9 @@ struct sockaddr* lookupNameServers(const std::string& hostname) { struct sockaddr* copySocketAddress(struct sockaddr* dst, const struct sockaddr* src) { if (src != nullptr) { if (dst == nullptr || dst->sa_family != src->sa_family) { - dst = (struct sockaddr*)realloc(dst, sizeof(union sockaddr_union)); + dst = (struct sockaddr*)std::realloc(dst, sizeof(union sockaddr_union)); } - memcpy(dst, src, sockaddr_size(src)); + std::memcpy(dst, src, sockaddr_size(src)); } else { free(dst); dst = nullptr; diff --git a/test/src/message/MessageBatchTest.cpp b/test/src/message/MessageBatchTest.cpp index f7ba0f3e6..7d84592d3 100644 --- a/test/src/message/MessageBatchTest.cpp +++ b/test/src/message/MessageBatchTest.cpp @@ -19,7 +19,7 @@ #include -#include "MQDecoder.h" +#include "MessageDecoder.h" #include "MQMessage.h" #include "MessageBatch.h" @@ -28,30 +28,26 @@ using testing::InitGoogleTest; using testing::Return; using rocketmq::MessageBatch; -using rocketmq::MQDecoder; +using rocketmq::MessageDecoder; using rocketmq::MQMessage; TEST(MessageBatchTest, Encode) { - std::vector msgs; - msgs.push_back(new MQMessage("topic", "*", "test1")); - std::unique_ptr msgBatch(MessageBatch::generateFromList(msgs)); + std::vector msgs; + msgs.push_back(MQMessage("topic", "*", "test1")); + auto msgBatch = MessageBatch::generateFromList(msgs); auto encodeMessage = msgBatch->encode(); - auto encodeMessage2 = MQDecoder::encodeMessages(msgs); + auto encodeMessage2 = MessageDecoder::encodeMessages(msgs); EXPECT_EQ(encodeMessage, encodeMessage2); // 20 + bodyLen(test1) + 2 + propertiesLength(TAGS:*;WAIT:true;); EXPECT_EQ(encodeMessage.size(), 44); - msgs.push_back(new MQMessage("topic", "*", "test2")); - msgs.push_back(new MQMessage("topic", "*", "test3")); - msgBatch.reset(MessageBatch::generateFromList(msgs)); + msgs.push_back(MQMessage("topic", "*", "test2")); + msgs.push_back(MQMessage("topic", "*", "test3")); + msgBatch = MessageBatch::generateFromList(msgs); encodeMessage = msgBatch->encode(); - encodeMessage2 = MQDecoder::encodeMessages(msgs); + encodeMessage2 = MessageDecoder::encodeMessages(msgs); EXPECT_EQ(encodeMessage, encodeMessage2); EXPECT_EQ(encodeMessage.size(), 132); // 44 * 3 - - for (auto* msg : msgs) { - delete msg; - } } int main(int argc, char* argv[]) { diff --git a/test/src/message/MQDecoderTest.cpp b/test/src/message/MessageDecoderTest.cpp similarity index 87% rename from test/src/message/MQDecoderTest.cpp rename to test/src/message/MessageDecoderTest.cpp index 2d43ac6a4..5acfc8148 100644 --- a/test/src/message/MQDecoderTest.cpp +++ b/test/src/message/MessageDecoderTest.cpp @@ -22,11 +22,11 @@ #include #include -#include "MQDecoder.h" +#include "MessageDecoder.h" #include "MQMessage.h" #include "MQMessageConst.h" #include "MQMessageExt.h" -#include "MQMessageId.h" +#include "MessageId.h" #include "MemoryInputStream.h" #include "MemoryOutputStream.h" #include "MessageSysFlag.h" @@ -42,21 +42,21 @@ using rocketmq::MemoryBlock; using rocketmq::MemoryInputStream; using rocketmq::MemoryOutputStream; using rocketmq::MessageSysFlag; -using rocketmq::MQDecoder; +using rocketmq::MessageDecoder; using rocketmq::MQMessage; using rocketmq::MQMessageConst; using rocketmq::MQMessageExt; -using rocketmq::MQMessageId; +using rocketmq::MessageId; using rocketmq::RemotingCommand; using rocketmq::SendMessageRequestHeader; using rocketmq::UtilAll; // TODO TEST(MessageDecoderTest, MessageId) { - std::string strMsgId = MQDecoder::createMessageId(rocketmq::string2SocketAddress("127.0.0.1:10091"), 1024LL); + std::string strMsgId = MessageDecoder::createMessageId(rocketmq::string2SocketAddress("127.0.0.1:10091"), 1024LL); EXPECT_EQ(strMsgId, "0100007F0000276B0000000000000400"); - MQMessageId msgId = MQDecoder::decodeMessageId(strMsgId); + MessageId msgId = MessageDecoder::decodeMessageId(strMsgId); EXPECT_EQ(msgId.getOffset(), 1024); } @@ -136,17 +136,17 @@ TEST(MessageDecoderTest, Decode) { // 17 PROPERTIES 111=109+2 memoryOut->writeShortBigEndian(0); - msgExt.setMsgId(MQDecoder::createMessageId(msgExt.getStoreHost(), (int64_t)msgExt.getCommitLogOffset())); + msgExt.setMsgId(MessageDecoder::createMessageId(msgExt.getStoreHost(), (int64_t)msgExt.getCommitLogOffset())); auto block = memoryOut->getMemoryBlock(); - auto msgs = MQDecoder::decodes(*static_cast(&block)); + auto msgs = MessageDecoder::decodes(*static_cast(&block)); EXPECT_EQ(msgs.size(), 1); std::cout << msgs[0]->toString() << std::endl; std::cout << msgExt.toString() << std::endl; EXPECT_EQ(msgs[0]->toString(), msgExt.toString()); - msgs = MQDecoder::decodes(*static_cast(&block), false); + msgs = MessageDecoder::decodes(*static_cast(&block), false); EXPECT_EQ(msgs[0]->getBody().size(), 0); //=============================================================== @@ -173,7 +173,7 @@ TEST(MessageDecoderTest, Decode) { std::map properties; properties["RocketMQ"] = "cpp-client"; properties[MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX] = "123456"; - std::string props = MQDecoder::messageProperties2String(properties); + std::string props = MessageDecoder::messageProperties2String(properties); memoryOut->writeShortBigEndian(props.size()); memoryOut->write(props.data(), props.size()); msgExt.setProperties(properties); @@ -184,17 +184,17 @@ TEST(MessageDecoderTest, Decode) { msgExt.setStoreSize(memoryOut->getDataSize()); block = memoryOut->getMemoryBlock(); - msgs = MQDecoder::decodes(*static_cast(&block)); + msgs = MessageDecoder::decodes(*static_cast(&block)); EXPECT_EQ(msgs[0]->toString(), msgExt.toString()); } TEST(MessageDecoderTest, MessagePropertiesAndToString) { std::map properties; properties["RocketMQ"] = "cpp-client"; - std::string props = MQDecoder::messageProperties2String(properties); + std::string props = MessageDecoder::messageProperties2String(properties); EXPECT_EQ(props, "RocketMQ\001cpp-client\002"); - auto properties2 = MQDecoder::string2messageProperties(props); + auto properties2 = MessageDecoder::string2messageProperties(props); EXPECT_EQ(properties, properties2); } diff --git a/test/src/message/MQMessageIdTest.cpp b/test/src/message/MessageIdTest.cpp similarity index 92% rename from test/src/message/MQMessageIdTest.cpp rename to test/src/message/MessageIdTest.cpp index 2fd77796e..aa0900670 100644 --- a/test/src/message/MQMessageIdTest.cpp +++ b/test/src/message/MessageIdTest.cpp @@ -17,17 +17,17 @@ #include #include -#include "MQMessageId.h" +#include "MessageId.h" using namespace std; using testing::InitGoogleMock; using testing::InitGoogleTest; using testing::Return; -using rocketmq::MQMessageId; +using rocketmq::MessageId; TEST(MessageIdTest, MessageId) { - MQMessageId msgId(rocketmq::string2SocketAddress("127.0.0.1:10091"), 1024); + MessageId msgId(rocketmq::string2SocketAddress("127.0.0.1:10091"), 1024); EXPECT_EQ(rocketmq::socketAddress2String(msgId.getAddress()), "127.0.0.1:10091"); EXPECT_EQ(msgId.getOffset(), 1024); From f0cce4417da99d7274ba44301409e37deb2ac8c4 Mon Sep 17 00:00:00 2001 From: James Yin Date: Mon, 20 Jul 2020 10:57:17 +0800 Subject: [PATCH 09/62] refactor: replace MemoryBlock with ByteArray --- example/AsyncProducer.cpp | 11 +- example/BatchProducer.cpp | 8 +- example/CMakeLists.txt | 2 +- example/OrderlyProducer.cpp | 2 +- example/OrderlyPushConsumer.cpp | 5 +- example/PullConsumer.cpp | 11 +- example/PushConsumer.cpp | 13 +- example/RequestReply.cpp | 14 +- example/SendDelayMsg.cpp | 2 +- example/SyncProducer.cpp | 2 +- example/TransactionProducer.cpp | 2 +- example/common.h | 4 +- include/AllocateMQStrategy.h | 11 +- include/Array.h | 85 +++++ include/ByteArray.h | 41 +++ include/ClientRPCHook.h | 12 +- include/CommandCustomHeader.h | 12 +- include/DataBlock.h | 219 ------------ include/DefaultMQProducer.h | 2 +- include/DefaultMQPushConsumer.h | 2 +- include/MQMessage.h | 9 +- include/MQMessageExt.h | 1 + include/MQMessageQueue.h | 43 ++- include/Message.h | 1 - include/RPCHook.h | 10 +- include/RemotingCommand.h | 107 +++--- include/RocketMQClient.h | 2 + src/ClientRemotingProcessor.cpp | 44 +-- src/MQClientAPIImpl.cpp | 108 +++--- src/common/ByteOrder.h | 319 +++++++----------- src/common/ClientRPCHook.cpp | 21 +- src/common/DataBlock.cpp | 239 ------------- src/common/FilterAPI.h | 2 +- src/common/InputStream.cpp | 114 ------- src/common/InputStream.h | 197 ----------- src/common/MemoryInputStream.cpp | 82 ----- src/common/MemoryInputStream.h | 98 ------ src/common/MemoryOutputStream.cpp | 173 ---------- src/common/MemoryOutputStream.h | 132 -------- src/common/MessageSysFlag.cpp | 22 +- src/common/MessageSysFlag.h | 24 +- src/common/OutputStream.cpp | 107 ------ src/common/OutputStream.h | 150 -------- src/common/SendCallbackWrap.cpp | 2 +- src/common/UtilAll.cpp | 40 +-- src/common/UtilAll.h | 32 +- src/common/Validators.cpp | 2 +- src/common/big_endian.cpp | 96 ------ src/common/big_endian.h | 101 ------ src/consumer/DefaultMQPushConsumer.cpp | 30 +- src/consumer/PullAPIWrapper.cpp | 6 +- src/consumer/PullRequest.cpp | 9 + src/consumer/PullRequest.h | 7 +- src/consumer/PullResultExt.h | 17 +- src/extern/CMessage.cpp | 5 +- src/io/Buffer.hpp | 193 +++++++++++ src/io/ByteArray.cpp | 82 +++++ src/io/ByteBuffer.cpp | 40 +++ src/io/ByteBuffer.hpp | 184 ++++++++++ src/io/DefaultByteBuffer.hpp | 222 ++++++++++++ src/message/MQMessage.cpp | 8 +- src/message/MQMessageQueue.cpp | 78 ++--- src/message/MessageClientIDSetter.cpp | 10 +- src/message/MessageDecoder.cpp | 183 +++++----- src/message/MessageDecoder.h | 18 +- src/message/MessageExtImpl.cpp | 2 +- src/message/MessageImpl.cpp | 5 - src/message/MessageImpl.h | 1 - src/message/MessageUtil.cpp | 1 + src/producer/DefaultMQProducer.cpp | 55 ++- src/producer/DefaultMQProducerImpl.cpp | 24 +- src/producer/TransactionMQProducer.cpp | 6 +- src/protocol/RemotingCommand.cpp | 218 ++++++------ src/protocol/RemotingSerializable.cpp | 6 +- src/protocol/RemotingSerializable.h | 4 +- src/protocol/TopicList.h | 10 +- src/protocol/TopicRouteData.h | 6 +- src/protocol/body/LockBatchBody.cpp | 4 +- src/protocol/body/LockBatchBody.h | 3 +- src/protocol/body/ResetOffsetBody.cpp | 8 +- src/protocol/body/ResetOffsetBody.h | 8 +- src/protocol/header/CommandHeader.cpp | 4 +- src/protocol/header/CommandHeader.h | 4 +- src/transport/SocketUtil.cpp | 25 +- src/transport/SocketUtil.h | 5 +- src/transport/TcpRemotingClient.cpp | 36 +- src/transport/TcpRemotingClient.h | 4 +- src/transport/TcpTransport.cpp | 10 +- src/transport/TcpTransport.h | 6 +- test/src/common/BigEndianTest.cpp | 85 ----- test/src/common/ClientRPCHookTest.cpp | 2 +- test/src/common/MemoryBlockTest.cpp | 150 -------- test/src/common/MemoryOutputStreamTest.cpp | 197 ----------- test/src/extern/CProducerTest.cpp | 8 +- test/src/extern/CPullConsumerTest.cpp | 9 +- test/src/message/MQMessageExtTest.cpp | 12 +- test/src/message/MQMessageTest.cpp | 4 - test/src/message/MessageBatchTest.cpp | 1 + test/src/message/MessageDecoderTest.cpp | 109 +++--- test/src/protocol/CommandHeaderTest.cpp | 9 +- test/src/protocol/LockBatchBodyTest.cpp | 10 +- test/src/protocol/RemotingCommandTest.cpp | 105 +++--- test/src/protocol/TopicRouteDataTest.cpp | 10 +- .../transport/ClientRemotingProcessorTest.cpp | 4 +- test/src/transport/ResponseFutureTest.cpp | 2 +- test/src/transport/SocketUtilTest.cpp | 5 +- 106 files changed, 1796 insertions(+), 3211 deletions(-) create mode 100644 include/Array.h create mode 100644 include/ByteArray.h delete mode 100644 include/DataBlock.h delete mode 100644 src/common/DataBlock.cpp delete mode 100644 src/common/InputStream.cpp delete mode 100644 src/common/InputStream.h delete mode 100644 src/common/MemoryInputStream.cpp delete mode 100644 src/common/MemoryInputStream.h delete mode 100644 src/common/MemoryOutputStream.cpp delete mode 100644 src/common/MemoryOutputStream.h delete mode 100644 src/common/OutputStream.cpp delete mode 100644 src/common/OutputStream.h delete mode 100644 src/common/big_endian.cpp delete mode 100644 src/common/big_endian.h create mode 100644 src/io/Buffer.hpp create mode 100644 src/io/ByteArray.cpp create mode 100644 src/io/ByteBuffer.cpp create mode 100644 src/io/ByteBuffer.hpp create mode 100644 src/io/DefaultByteBuffer.hpp delete mode 100644 test/src/common/BigEndianTest.cpp delete mode 100644 test/src/common/MemoryBlockTest.cpp delete mode 100644 test/src/common/MemoryOutputStreamTest.cpp diff --git a/example/AsyncProducer.cpp b/example/AsyncProducer.cpp index 8f6c05f3e..87e7368d5 100644 --- a/example/AsyncProducer.cpp +++ b/example/AsyncProducer.cpp @@ -27,8 +27,7 @@ std::atomic g_failed(0); class MyAutoDeleteSendCallback : public AutoDeleteSendCallback { public: - MyAutoDeleteSendCallback(MQMessage* msg) : m_msg(msg) {} - virtual ~MyAutoDeleteSendCallback() { delete m_msg; } + MyAutoDeleteSendCallback(MQMessage msg) : m_msg(std::move(msg)) {} void onSuccess(SendResult& sendResult) override { g_success++; @@ -43,14 +42,14 @@ class MyAutoDeleteSendCallback : public AutoDeleteSendCallback { } private: - MQMessage* m_msg; + MQMessage m_msg; }; void AsyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) { while (g_msgCount.fetch_sub(1) > 0) { - auto* msg = new MQMessage(info->topic, // topic - "*", // tag - info->body); // body + MQMessage msg(info->topic, // topic + "*", // tag + info->body); // body SendCallback* callback = new MyAutoDeleteSendCallback(msg); diff --git a/example/BatchProducer.cpp b/example/BatchProducer.cpp index 4055d8a88..e698b6643 100644 --- a/example/BatchProducer.cpp +++ b/example/BatchProducer.cpp @@ -22,7 +22,7 @@ TpsReportService g_tps; void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) { while (g_msgCount.fetch_sub(1) > 0) { - std::vector msgs; + std::vector msgs; MQMessage msg1(info->topic, "*", info->body); msg1.putProperty("property1", "value1"); MQMessage msg2(info->topic, "*", info->body); @@ -32,9 +32,9 @@ void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* pr msg3.putProperty("property1", "value1"); msg3.putProperty("property2", "value2"); msg3.putProperty("property3", "value3"); - msgs.push_back(&msg1); - msgs.push_back(&msg2); - msgs.push_back(&msg3); + msgs.push_back(std::move(msg1)); + msgs.push_back(std::move(msg2)); + msgs.push_back(std::move(msg3)); try { auto start = std::chrono::system_clock::now(); diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 8e445b17a..cf75d060f 100755 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -17,7 +17,7 @@ project(example) set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin) -file(GLOB files RELATIVE "${PROJECT_SOURCE_DIR}" "*.c*") +file(GLOB files RELATIVE "${PROJECT_SOURCE_DIR}" "*.c" "*.cpp") list(REMOVE_ITEM files "ArgHelper.cpp") foreach(file ${files}) get_filename_component(basename ${file} NAME_WE) diff --git a/example/OrderlyProducer.cpp b/example/OrderlyProducer.cpp index d50542e22..f2ce9f6e5 100644 --- a/example/OrderlyProducer.cpp +++ b/example/OrderlyProducer.cpp @@ -39,7 +39,7 @@ void ProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* produc try { auto start = std::chrono::system_clock::now(); int orderId = 1; - SendResult sendResult = producer->send(&msg, &g_mySelector, static_cast(&orderId), info->retrytimes); + SendResult sendResult = producer->send(msg, &g_mySelector, static_cast(&orderId), info->retrytimes); auto end = std::chrono::system_clock::now(); g_tps.Increment(); diff --git a/example/OrderlyPushConsumer.cpp b/example/OrderlyPushConsumer.cpp index 2d8a54120..62959f1f5 100644 --- a/example/OrderlyPushConsumer.cpp +++ b/example/OrderlyPushConsumer.cpp @@ -27,13 +27,12 @@ class MyMsgListener : public MessageListenerOrderly { MyMsgListener() {} virtual ~MyMsgListener() {} - virtual ConsumeStatus consumeMessage(const std::vector& msgs) { + virtual ConsumeStatus consumeMessage(const std::vector& msgs) override { auto old = g_msgCount.fetch_sub(msgs.size()); if (old > 0) { for (size_t i = 0; i < msgs.size(); ++i) { g_tps.Increment(); - // std::cout << msgs[i]->getMsgId() << std::endl; - // std::cout << "msg body: " << msgs[i].getBody() << std::endl; + std::cout << msgs[i].getMsgId() << ", body: " << msgs[i].getBody() << std::endl; } if (old <= msgs.size()) { g_finished.count_down(); diff --git a/example/PullConsumer.cpp b/example/PullConsumer.cpp index e7472b331..d1eab5ea9 100644 --- a/example/PullConsumer.cpp +++ b/example/PullConsumer.cpp @@ -24,6 +24,7 @@ #include #include "common.h" +#include "DefaultMQPullConsumer.h" using namespace rocketmq; @@ -77,18 +78,18 @@ int main(int argc, char* argv[]) { do { try { PullResult result = consumer.pull(mq, "*", getMessageQueueOffset(mq), 32); - g_msgCount += result.msg_found_list_.size(); - std::cout << result.msg_found_list_.size() << std::endl; + g_msgCount += result.msg_found_list().size(); + std::cout << result.msg_found_list().size() << std::endl; // if pull request timeout or received NULL response, pullStatus will be // setted to BROKER_TIMEOUT, // And nextBeginOffset/minOffset/MaxOffset will be setted to 0 - if (result.pull_status_ != BROKER_TIMEOUT) { - putMessageQueueOffset(mq, result.next_begin_offset_); + if (result.pull_status() != BROKER_TIMEOUT) { + putMessageQueueOffset(mq, result.next_begin_offset()); PrintPullResult(&result); } else { std::cout << "broker timeout occur" << std::endl; } - switch (result.pull_status_) { + switch (result.pull_status()) { case FOUND: case NO_MATCHED_MSG: case OFFSET_ILLEGAL: diff --git a/example/PushConsumer.cpp b/example/PushConsumer.cpp index 9f1797921..0e7ccc902 100644 --- a/example/PushConsumer.cpp +++ b/example/PushConsumer.cpp @@ -16,6 +16,7 @@ */ #include "common.h" #include "concurrent/latch.hpp" +#include "UtilAll.h" using namespace rocketmq; @@ -24,16 +25,18 @@ latch g_finished(1); class MyMsgListener : public MessageListenerConcurrently { public: - MyMsgListener() {} - virtual ~MyMsgListener() {} + virtual ~MyMsgListener() = default; - virtual ConsumeStatus consumeMessage(const std::vector& msgs) { + ConsumeStatus consumeMessage(const std::vector& msgs) override { auto old = g_msgCount.fetch_sub(msgs.size()); if (old > 0) { for (size_t i = 0; i < msgs.size(); ++i) { g_tps.Increment(); - // std::cout << msgs[i]->getMsgId() << std::endl; - // std::cout << "msg body: " << msgs[i].getBody() << std::endl; + if (msgs[i] == nullptr) { + std::cout << "error!!!" << std::endl; + } else { + std::cout << msgs[i].getMsgId() << ", body: " << msgs[i].getBody() << std::endl; + } } if (old <= msgs.size()) { g_finished.count_down(); diff --git a/example/RequestReply.cpp b/example/RequestReply.cpp index 1ba3af811..ebb52e32f 100644 --- a/example/RequestReply.cpp +++ b/example/RequestReply.cpp @@ -17,7 +17,7 @@ #include #include "../src/common/UtilAll.h" -#include "../src/log/Logging.h" +#include "common.h" #include "MessageUtil.h" #include "common.h" @@ -28,17 +28,17 @@ class MyResponseMessageListener : public MessageListenerConcurrently { MyResponseMessageListener(DefaultMQProducer* replyProducer) : m_replyProducer(replyProducer) {} virtual ~MyResponseMessageListener() = default; - ConsumeStatus consumeMessage(const std::vector& msgs) override { + ConsumeStatus consumeMessage(const std::vector& msgs) override { for (const auto& msg : msgs) { try { - std::cout << "handle message: " << msg->toString() << std::endl; + std::cout << "handle message: " << msg.toString() << std::endl; const auto& replyTo = MessageUtil::getReplyToClient(msg); // create reply message with given util, do not create reply message by yourself - std::unique_ptr replyMessage(MessageUtil::createReplyMessage(msg, "reply message contents.")); + MQMessage replyMessage = MessageUtil::createReplyMessage(msg, "reply message contents."); // send reply message with producer - SendResult replyResult = m_replyProducer->send(replyMessage.get(), 10000); + SendResult replyResult = m_replyProducer->send(replyMessage, 10000); std::cout << "reply to " << replyTo << ", " << replyResult.toString() << std::endl; } catch (const std::exception& e) { std::cout << e.what() << std::endl; @@ -98,10 +98,10 @@ int main(int argc, char* argv[]) { MQMessage msg(info.topic, "Hello world"); auto begin = UtilAll::currentTimeMillis(); - std::unique_ptr retMsg(producer.request(&msg, 10000)); + MQMessage retMsg = producer.request(msg, 10000); auto cost = UtilAll::currentTimeMillis() - begin; std::cout << count << " >>> request to <" << info.topic << "> cost: " << cost - << " replyMessage: " << retMsg->toString() << std::endl; + << " replyMessage: " << retMsg.toString() << std::endl; } catch (const std::exception& e) { std::cout << count << " >>> " << e.what() << std::endl; } diff --git a/example/SendDelayMsg.cpp b/example/SendDelayMsg.cpp index 3a5b6ce20..a1ed15073 100644 --- a/example/SendDelayMsg.cpp +++ b/example/SendDelayMsg.cpp @@ -40,7 +40,7 @@ int main(int argc, char* argv[]) { // messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h msg.setDelayTimeLevel(5); // 1m try { - SendResult sendResult = producer->send(&msg); + SendResult sendResult = producer->send(msg); } catch (const MQException& e) { std::cout << "send failed: " << std::endl; } diff --git a/example/SyncProducer.cpp b/example/SyncProducer.cpp index 994a519d7..c5bbaf134 100644 --- a/example/SyncProducer.cpp +++ b/example/SyncProducer.cpp @@ -27,7 +27,7 @@ void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* pr info->body); // body try { auto start = std::chrono::system_clock::now(); - SendResult sendResult = producer->send(&msg); + SendResult sendResult = producer->send(msg); auto end = std::chrono::system_clock::now(); g_tps.Increment(); diff --git a/example/TransactionProducer.cpp b/example/TransactionProducer.cpp index 547a279c5..214d32125 100644 --- a/example/TransactionProducer.cpp +++ b/example/TransactionProducer.cpp @@ -43,7 +43,7 @@ void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, TransactionMQProducer try { auto start = std::chrono::system_clock::now(); intptr_t arg = old - 1; - TransactionSendResult sendResult = producer->sendMessageInTransaction(&msg, (void*)arg); + TransactionSendResult sendResult = producer->sendMessageInTransaction(msg, (void*)arg); auto end = std::chrono::system_clock::now(); g_tps.Increment(); diff --git a/example/common.h b/example/common.h index 90bff8e66..3de419954 100644 --- a/example/common.h +++ b/example/common.h @@ -114,9 +114,9 @@ static void PrintResult(rocketmq::SendResult* result) { void PrintPullResult(rocketmq::PullResult* result) { std::cout << result->toString() << std::endl; - if (result->pull_status_ == rocketmq::FOUND) { + if (result->pull_status() == rocketmq::FOUND) { std::cout << result->toString() << std::endl; - for (auto& msg : result->msg_found_list_) { + for (auto msg : result->msg_found_list()) { std::cout << "=======================================================" << std::endl << msg->toString() << std::endl; } diff --git a/include/AllocateMQStrategy.h b/include/AllocateMQStrategy.h index 03436541b..4f60b297c 100644 --- a/include/AllocateMQStrategy.h +++ b/include/AllocateMQStrategy.h @@ -14,16 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __ALLOCATE_MQ_STRATEGY_H__ -#define __ALLOCATE_MQ_STRATEGY_H__ +#ifndef ROCKETMQ_ALLOCATEMQSTRATEGY_H_ +#define ROCKETMQ_ALLOCATEMQSTRATEGY_H_ -#include -#include +#include // std::string +#include // std::vector #include "MQMessageQueue.h" namespace rocketmq { +/** + * AllocateMQStrategy - Interface of allocate MessageQueue + */ class ROCKETMQCLIENT_API AllocateMQStrategy { public: virtual ~AllocateMQStrategy() = default; diff --git a/include/Array.h b/include/Array.h new file mode 100644 index 000000000..daa48667e --- /dev/null +++ b/include/Array.h @@ -0,0 +1,85 @@ +/* + * 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_ARRAY_H_ +#define ROCKETMQ_ARRAY_H_ + +#include // std::calloc, std::free +#include // std::memcpy + +#include // std::bad_alloc +#include // std::enable_if, std::is_arithmetic, std::is_pointer, std::is_class + +#include "RocketMQClient.h" + +namespace rocketmq { + +template +struct array_traits {}; + +template +struct array_traits::value || std::is_pointer::value>::type> { + typedef T element_type; +}; // specialization for arithmetic and pointer types + +template +struct array_traits::value>::type> { + typedef T* element_type; +}; // specialization for class types + +template +using array_element_t = typename array_traits::element_type; + +template +class Array { + public: + using element_type = array_element_t; + + public: + Array(element_type* array, size_t size, bool auto_clean = false) + : array_(array), size_(size), auto_clean_(auto_clean) {} + Array(size_t size) : Array((element_type*)std::calloc(size, sizeof(element_type)), size, true) { + if (nullptr == array_) { + throw std::bad_alloc(); + } + } + + Array(const Array& other) : Array(other.size_) { std::memcpy(array_, other.array_, size_); } + Array(Array&& other) : Array(other.array_, other.size_, other.auto_clean_) { other.auto_clean_ = false; } + + virtual ~Array() { + if (auto_clean_) { + std::free(array_); + } + } + + element_type& operator[](size_t index) { return array_[index]; } + const element_type& operator[](size_t index) const { return array_[index]; } + + public: + inline T* array() { return array_; } + inline const T* array() const { return array_; } + inline size_t size() const { return size_; } + + protected: + element_type* array_; + size_t size_; + bool auto_clean_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_ARRAY_H_ diff --git a/include/ByteArray.h b/include/ByteArray.h new file mode 100644 index 000000000..5ce3aa0fc --- /dev/null +++ b/include/ByteArray.h @@ -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 ROCKETMQ_BYTEARRAY_H_ +#define ROCKETMQ_BYTEARRAY_H_ + +#include // std::shared_ptr + +#include "Array.h" + +namespace rocketmq { + +typedef Array ByteArray; +typedef std::shared_ptr> ByteArrayRef; + +ByteArrayRef slice(ByteArrayRef ba, size_t offset); +ByteArrayRef slice(ByteArrayRef ba, size_t offset, size_t size); + +ByteArrayRef stoba(const std::string& str); +ByteArrayRef stoba(std::string&& str); + +ByteArrayRef catoba(const char* str, size_t len); + +std::string batos(ByteArrayRef ba); + +} // namepace rocketmq + +#endif // ROCKETMQ_BYTEARRAY_H_ diff --git a/include/ClientRPCHook.h b/include/ClientRPCHook.h index e2a7d267a..e185b1fcc 100644 --- a/include/ClientRPCHook.h +++ b/include/ClientRPCHook.h @@ -14,8 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __CLIENT_RPC_HOOK_H__ -#define __CLIENT_RPC_HOOK_H__ +#ifndef ROCKETMQ_CLIENTRPCHOOK_H_ +#define ROCKETMQ_CLIENTRPCHOOK_H_ + +#include // std::string #include "RPCHook.h" #include "SessionCredentials.h" @@ -24,7 +26,7 @@ namespace rocketmq { class ROCKETMQCLIENT_API ClientRPCHook : public RPCHook { public: - ClientRPCHook(const SessionCredentials& sessionCredentials) : sessionCredentials_(sessionCredentials) {} + ClientRPCHook(const SessionCredentials& sessionCredentials) : session_credentials_(sessionCredentials) {} ~ClientRPCHook() override = default; void doBeforeRequest(const std::string& remoteAddr, RemotingCommand& request, bool toSent) override; @@ -37,9 +39,9 @@ class ROCKETMQCLIENT_API ClientRPCHook : public RPCHook { void signCommand(RemotingCommand& command); private: - SessionCredentials sessionCredentials_; + SessionCredentials session_credentials_; }; } // namespace rocketmq -#endif // __CLIENT_RPC_HOOK_H__ +#endif // ROCKETMQ_CLIENTRPCHOOK_H_ diff --git a/include/CommandCustomHeader.h b/include/CommandCustomHeader.h index 66c1b56ad..a088c21cf 100644 --- a/include/CommandCustomHeader.h +++ b/include/CommandCustomHeader.h @@ -14,15 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __COMMAND_CUSTOM_HEADER_H__ -#define __COMMAND_CUSTOM_HEADER_H__ +#ifndef ROCKETMQ_COMMANDCUSTOMHEADER_H_ +#define ROCKETMQ_COMMANDCUSTOMHEADER_H_ -#include -#include +#include // std::map +#include // std::string #include "RocketMQClient.h" -namespace Json { +namespace Json { // jsoncpp class Value; } @@ -40,4 +40,4 @@ class ROCKETMQCLIENT_API CommandCustomHeader { } // namespace rocketmq -#endif // __COMMAND_CUSTOM_HEADER_H__ +#endif // ROCKETMQ_COMMANDCUSTOMHEADER_H_ diff --git a/include/DataBlock.h b/include/DataBlock.h deleted file mode 100644 index 7976cd005..000000000 --- a/include/DataBlock.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - * 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 __DATA_BLOCK_H__ -#define __DATA_BLOCK_H__ - -#include -#include - -#include "RocketMQClient.h" - -namespace rocketmq { - -class MemoryBlock; -typedef std::unique_ptr MemoryBlockPtr; -typedef std::shared_ptr MemoryBlockPtr2; - -class ROCKETMQCLIENT_API MemoryBlock { - public: - MemoryBlock() : MemoryBlock(nullptr, 0) {} - explicit MemoryBlock(char* data, size_t size) : data_(data), size_(size) {} - virtual ~MemoryBlock() = default; - - /** Returns a void pointer to the data. - * - * Note that the pointer returned will probably become invalid when the block is resized. - */ - char* getData() { return data_; } - - const char* getData() const { return data_; } - - /** Returns the block's current allocated size, in bytes. */ - size_t getSize() const { return size_; } - - /** Returns a byte from the memory block. - * This returns a reference, so you can also use it to set a byte. - */ - template - char& operator[](const Type offset) { - return data_[offset]; - } - - template - const char& operator[](const Type offset) const { - return data_[offset]; - } - - operator std::string() { - if (size_ > 0) { - return std::string(data_, size_); - } else { - return ""; - } - } - - /** Frees all the blocks data, setting its size to 0. */ - virtual void reset() { reset(nullptr, 0); } - - virtual void reset(char* data, size_t size) { - data_ = data; - size_ = size; - } - - /** 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, ssize_t sourceOffset, size_t numBytes) const; - - protected: - char* data_; - size_t size_; -}; - -class ROCKETMQCLIENT_API MemoryPool : public MemoryBlock { - public: - /** Create an uninitialised block with 0 size. */ - MemoryPool(); - - /** 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 - */ - explicit MemoryPool(size_t 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 - */ - explicit MemoryPool(const void* dataToInitialiseFrom, size_t sizeInBytes); - - /** Creates a copy of another memory block. */ - MemoryPool(const MemoryPool&); - - MemoryPool(MemoryPool&&); - - /** Destructor. */ - ~MemoryPool(); - - /** Copies another memory block onto this one. - * This block will be resized and copied to exactly match the other one. - */ - MemoryPool& operator=(const MemoryPool&); - - MemoryPool& operator=(MemoryPool&&); - - /** Returns true if the data in this MemoryBlock matches the raw bytes passed-in. */ - bool matches(const void* data, size_t dataSize) const; - - /** Compares two memory blocks. - * @returns true only if the two blocks are the same size and have identical contents. - */ - bool operator==(const MemoryPool& other) const; - - /** Compares two memory blocks. - * @returns true if the two blocks are different sizes or have different contents. - */ - bool operator!=(const MemoryPool& other) const; - - void reset() override; - void reset(char* data, size_t size) override; - - /** 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(size_t 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(size_t minimumSize, bool initialiseNewSpaceToZero = false); - - /** 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 increasedaccordingly. - */ - void append(const void* data, size_t 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, size_t 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, size_t numBytesToInsert, size_t 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(size_t startByte, size_t 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, ssize_t destinationOffset, size_t numBytes); -}; - -class ROCKETMQCLIENT_API MemoryView : public MemoryBlock { - public: - MemoryView(MemoryBlockPtr2 origin, size_t offset) : MemoryView(origin, offset, origin->getSize() - offset) {} - MemoryView(MemoryBlockPtr2 origin, size_t offset, size_t size) - : MemoryBlock(origin->getData() + offset, size), origin_(origin) {} - - void reset() override; - void reset(char* data, size_t size) override; - - private: - MemoryBlockPtr2 origin_; -}; - -} // namespace rocketmq - -#endif // __DATA_BLOCK_H__ diff --git a/include/DefaultMQProducer.h b/include/DefaultMQProducer.h index 2219dfe2f..e34f94eaa 100644 --- a/include/DefaultMQProducer.h +++ b/include/DefaultMQProducer.h @@ -84,7 +84,7 @@ class ROCKETMQCLIENT_API DefaultMQProducer : public MQProducer, public DefaultMQ void setRPCHook(RPCHookPtr rpcHook); protected: - std::shared_ptr m_producerDelegate; + std::shared_ptr producer_impl_; }; } // namespace rocketmq diff --git a/include/DefaultMQPushConsumer.h b/include/DefaultMQPushConsumer.h index 83e473257..650571247 100755 --- a/include/DefaultMQPushConsumer.h +++ b/include/DefaultMQPushConsumer.h @@ -53,7 +53,7 @@ class ROCKETMQCLIENT_API DefaultMQPushConsumer : public MQPushConsumer, public D void setRPCHook(RPCHookPtr rpcHook); protected: - std::shared_ptr m_pushConsumerDelegate; + std::shared_ptr push_consumer_impl_; }; } // namespace rocketmq diff --git a/include/MQMessage.h b/include/MQMessage.h index 3016ec5a5..5fc577612 100644 --- a/include/MQMessage.h +++ b/include/MQMessage.h @@ -17,7 +17,7 @@ #ifndef ROCKETMQ_MQMESSAGE_H_ #define ROCKETMQ_MQMESSAGE_H_ -#include // std::nullptr_t +#include // std::move #include "Message.h" #include "MQMessageConst.h" @@ -47,6 +47,7 @@ class ROCKETMQCLIENT_API MQMessage : virtual public Message // interface // copy constructor MQMessage(const MQMessage& other) : message_impl_(other.message_impl_) {} + MQMessage(MQMessage&& other) : message_impl_(std::move(other.message_impl_)) {} // assign operator MQMessage& operator=(const MQMessage& other) { @@ -56,9 +57,8 @@ class ROCKETMQCLIENT_API MQMessage : virtual public Message // interface return *this; } - bool operator==(std::nullptr_t) noexcept { return nullptr == message_impl_; } - - friend bool operator==(std::nullptr_t, const MQMessage& message) noexcept { return nullptr == message.message_impl_; } + bool operator==(std::nullptr_t) const noexcept { return nullptr == message_impl_; } + friend bool operator==(std::nullptr_t, const MQMessage& message) noexcept; // convert to boolean operator bool() noexcept { return nullptr != message_impl_; } @@ -92,7 +92,6 @@ class ROCKETMQCLIENT_API MQMessage : virtual public Message // interface void setFlag(int32_t flag) override; const std::string& getBody() const override; - void setBody(const char* body, int len) override; void setBody(const std::string& body) override; void setBody(std::string&& body) override; diff --git a/include/MQMessageExt.h b/include/MQMessageExt.h index 0001f7032..a6d872328 100644 --- a/include/MQMessageExt.h +++ b/include/MQMessageExt.h @@ -43,6 +43,7 @@ class ROCKETMQCLIENT_API MQMessageExt : public MQMessage, // base // copy constructor MQMessageExt(const MQMessageExt& other) : MQMessage(other) {} + MQMessageExt(MQMessageExt&& other) : MQMessage(std::move(other)) {} // assign operator MQMessageExt& operator=(const MQMessageExt& other) { diff --git a/include/MQMessageQueue.h b/include/MQMessageQueue.h index 8fe594070..bfe9fb901 100644 --- a/include/MQMessageQueue.h +++ b/include/MQMessageQueue.h @@ -14,53 +14,50 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_MESSAGE_QUEUE_H__ -#define __MQ_MESSAGE_QUEUE_H__ +#ifndef ROCKETMQ_MQMESSAGEQUEUE_H_ +#define ROCKETMQ_MQMESSAGEQUEUE_H_ -#include -#include +#include // std::string #include "RocketMQClient.h" namespace rocketmq { /** - * MQ(T,B,ID) + * MessageQueue(Topic, BrokerName, QueueId) */ class ROCKETMQCLIENT_API MQMessageQueue { public: MQMessageQueue(); MQMessageQueue(const std::string& topic, const std::string& brokerName, int queueId); + MQMessageQueue(const MQMessageQueue& other); MQMessageQueue& operator=(const MQMessageQueue& other); - const std::string& getTopic() const; - void setTopic(const std::string& topic); - - const std::string& getBrokerName() const; - void setBrokerName(const std::string& brokerName); - - int getQueueId() const; - void setQueueId(int queueId); - bool operator==(const MQMessageQueue& mq) const; bool operator!=(const MQMessageQueue& mq) const { return !operator==(mq); } bool operator<(const MQMessageQueue& mq) const; int compareTo(const MQMessageQueue& mq) const; - std::string toString() const { - std::stringstream ss; - ss << "MessageQueue [topic=" << m_topic << ", brokerName=" << m_brokerName << ", queueId=" << m_queueId << "]"; - return ss.str(); - } + std::string toString() const; + + public: + inline const std::string& getTopic() const { return topic_; }; + inline void setTopic(const std::string& topic) { topic_ = topic; }; + + inline const std::string& getBrokerName() const { return broker_name_; }; + inline void setBrokerName(const std::string& broker_name) { broker_name_ = broker_name; }; + + inline int getQueueId() const { return queue_id_; }; + inline void setQueueId(int queue_id) { queue_id_ = queue_id; }; private: - std::string m_topic; - std::string m_brokerName; - int m_queueId; + std::string topic_; + std::string broker_name_; + int queue_id_; }; } // namespace rocketmq -#endif // __MQ_MESSAGE_QUEUE_H__ +#endif // ROCKETMQ_MQMESSAGEQUEUE_H_ diff --git a/include/Message.h b/include/Message.h index 0320c0ea9..e4f21c483 100644 --- a/include/Message.h +++ b/include/Message.h @@ -70,7 +70,6 @@ class ROCKETMQCLIENT_API Message { // body virtual const std::string& getBody() const = 0; - virtual void setBody(const char* body, int len) = 0; virtual void setBody(const std::string& body) = 0; virtual void setBody(std::string&& body) = 0; diff --git a/include/RPCHook.h b/include/RPCHook.h index 5ee88b6e3..515b2bc46 100644 --- a/include/RPCHook.h +++ b/include/RPCHook.h @@ -14,11 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __RPC_HOOK_H__ -#define __RPC_HOOK_H__ +#ifndef ROCKETMQ_RPCHOOK_H_ +#define ROCKETMQ_RPCHOOK_H_ -#include -#include +#include // std::shared_ptr +#include // std::string #include "RemotingCommand.h" @@ -41,4 +41,4 @@ class ROCKETMQCLIENT_API RPCHook { } // namespace rocketmq -#endif // __RPC_HOOK_H__ +#endif // ROCKETMQ_RPCHOOK_H_ diff --git a/include/RemotingCommand.h b/include/RemotingCommand.h index 2fa8a2745..6ad14e867 100644 --- a/include/RemotingCommand.h +++ b/include/RemotingCommand.h @@ -14,15 +14,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __REMOTING_COMMAND_H__ -#define __REMOTING_COMMAND_H__ +#ifndef ROCKETMQ_REMOTINGCOMMAND_H_ +#define ROCKETMQ_REMOTINGCOMMAND_H_ -#include -#include -#include +#include // std::exception +#include // std::map +#include // std::unique_ptr, std::shared_ptr +#include // std::string +#include // std::type_index +#include "ByteArray.h" #include "CommandCustomHeader.h" -#include "DataBlock.h" #include "MQClientException.h" namespace rocketmq { @@ -32,7 +34,7 @@ class ROCKETMQCLIENT_API RemotingCommand { static int32_t createNewRequestId(); public: - RemotingCommand() : m_code(0) {} + RemotingCommand() : code_(0) {} RemotingCommand(int32_t code, CommandCustomHeader* customHeader = nullptr); RemotingCommand(int32_t code, const std::string& remark, CommandCustomHeader* customHeader = nullptr); RemotingCommand(int32_t code, @@ -42,78 +44,77 @@ class ROCKETMQCLIENT_API RemotingCommand { int32_t flag, const std::string& remark, CommandCustomHeader* customHeader); + RemotingCommand(RemotingCommand&& command); virtual ~RemotingCommand(); - int32_t getCode() const; - void setCode(int32_t code); - - int32_t getVersion() const; - - int32_t getOpaque() const; - void setOpaque(int32_t opaque); - - int32_t getFlag() const; - - const std::string& getRemark() const; - void setRemark(const std::string& mark); - + public: bool isResponseType(); void markResponseType(); bool isOnewayRPC(); void markOnewayRPC(); - void addExtField(const std::string& key, const std::string& value); - CommandCustomHeader* readCustomHeader() const; - MemoryBlockPtr2 getBody() const; - void setBody(MemoryBlock* body); - void setBody(MemoryBlockPtr2 body); - void setBody(const std::string& body); - public: - MemoryBlockPtr encode() const; + ByteArrayRef encode() const; template - H* decodeCommandCustomHeader(bool useCache); + H* decodeCommandCustomHeader(bool useCache = true); - template - H* decodeCommandCustomHeader(); - - static RemotingCommand* Decode(MemoryBlockPtr2 package, bool havePackageLen = false); + static RemotingCommand* Decode(ByteArrayRef array, bool hasPackageLength = false); std::string toString() const; + public: + inline int32_t code() const { return code_; } + inline void set_code(int32_t code) { code_ = code; } + + inline int32_t version() const { return version_; } + + inline int32_t opaque() const { return opaque_; } + inline void set_opaque(int32_t opaque) { opaque_ = opaque; } + + inline int32_t flag() const { return flag_; } + + inline const std::string& remark() const { return remark_; } + inline void set_remark(const std::string& remark) { remark_ = remark; } + + inline void set_ext_field(const std::string& name, const std::string& value) { ext_fields_[name] = value; } + + inline ByteArrayRef body() const { return body_; } + inline void set_body(ByteArrayRef body) { body_ = std::move(body); } + inline void set_body(const std::string& body) { body_ = stoba(body); } + inline void set_body(std::string&& body) { body_ = stoba(std::move(body)); } + private: - int32_t m_code; - std::string m_language; - int32_t m_version; - int32_t m_opaque; - int32_t m_flag; - std::string m_remark; - std::map m_extFields; - std::unique_ptr m_customHeader; // transient - - MemoryBlockPtr2 m_body; // transient + int32_t code_; + std::string language_; + int32_t version_; + int32_t opaque_; + int32_t flag_; + std::string remark_; + std::map ext_fields_; + + std::unique_ptr custom_header_; // transient + + ByteArrayRef body_; // transient }; template H* RemotingCommand::decodeCommandCustomHeader(bool useCache) { - auto* cache = m_customHeader.get(); - if (cache != nullptr && useCache && std::type_index(typeid(*cache)) == std::type_index(typeid(H))) { - return static_cast(m_customHeader.get()); + if (useCache) { + auto* cache = custom_header_.get(); + if (cache != nullptr && std::type_index(typeid(*cache)) == std::type_index(typeid(H))) { + return static_cast(custom_header_.get()); + } } - return decodeCommandCustomHeader(); -} -template -H* RemotingCommand::decodeCommandCustomHeader() { try { - H* header = H::Decode(m_extFields); - m_customHeader.reset(header); + H* header = H::Decode(ext_fields_); + custom_header_.reset(header); return header; } catch (std::exception& e) { THROW_MQEXCEPTION(RemotingCommandException, e.what(), -1); @@ -122,4 +123,4 @@ H* RemotingCommand::decodeCommandCustomHeader() { } // namespace rocketmq -#endif // __REMOTING_COMMAND_H__ +#endif // ROCKETMQ_REMOTINGCOMMAND_H_ diff --git a/include/RocketMQClient.h b/include/RocketMQClient.h index d6247938f..39d5ccc39 100644 --- a/include/RocketMQClient.h +++ b/include/RocketMQClient.h @@ -19,8 +19,10 @@ #ifdef __cplusplus #include +#include #else #include +#include #endif #ifdef WIN32 diff --git a/src/ClientRemotingProcessor.cpp b/src/ClientRemotingProcessor.cpp index 97286a17a..63616280d 100644 --- a/src/ClientRemotingProcessor.cpp +++ b/src/ClientRemotingProcessor.cpp @@ -35,8 +35,8 @@ ClientRemotingProcessor::~ClientRemotingProcessor() = default; RemotingCommand* ClientRemotingProcessor::processRequest(TcpTransportPtr channel, RemotingCommand* request) { const auto& addr = channel->getPeerAddrAndPort(); - LOG_DEBUG_NEW("processRequest, code:{}, addr:{}", request->getCode(), addr); - switch (request->getCode()) { + LOG_DEBUG_NEW("processRequest, code:{}, addr:{}", request->code(), addr); + switch (request->code()) { case CHECK_TRANSACTION_STATE: return checkTransactionState(addr, request); case NOTIFY_CONSUMER_IDS_CHANGED: @@ -63,9 +63,10 @@ RemotingCommand* ClientRemotingProcessor::checkTransactionState(const std::strin auto* requestHeader = request->decodeCommandCustomHeader(); assert(requestHeader != nullptr); - auto requestBody = request->getBody(); - if (requestBody != nullptr && requestBody->getSize() > 0) { - MessageExtPtr messageExt = MessageDecoder::decode(*requestBody); + auto requestBody = request->body(); + if (requestBody != nullptr && requestBody->size() > 0) { + std::unique_ptr byteBuffer(ByteBuffer::wrap(requestBody)); + MessageExtPtr messageExt = MessageDecoder::decode(*byteBuffer); if (messageExt != nullptr) { const auto& transactionId = messageExt->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX); if (!transactionId.empty()) { @@ -101,8 +102,8 @@ RemotingCommand* ClientRemotingProcessor::notifyConsumerIdsChanged(RemotingComma RemotingCommand* ClientRemotingProcessor::resetOffset(RemotingCommand* request) { auto* responseHeader = request->decodeCommandCustomHeader(); - auto requestBody = request->getBody(); - if (requestBody != nullptr && requestBody->getSize() > 0) { + auto requestBody = request->body(); + if (requestBody != nullptr && requestBody->size() > 0) { std::unique_ptr body(ResetOffsetBody::Decode(*requestBody)); if (body != nullptr) { m_clientInstance->resetOffset(responseHeader->getGroup(), responseHeader->getTopic(), body->getOffsetTable()); @@ -127,12 +128,11 @@ RemotingCommand* ClientRemotingProcessor::getConsumerRunningInfo(const std::stri /*string jstack = UtilAll::jstack(); consumerRunningInfo->setJstack(jstack);*/ } - response->setCode(SUCCESS); - auto body = runningInfo->encode(); - response->setBody(body); + response->set_code(SUCCESS); + response->set_body(runningInfo->encode()); } else { - response->setCode(SYSTEM_ERROR); - response->setRemark("The Consumer Group not exist in this consumer"); + response->set_code(SYSTEM_ERROR); + response->set_remark("The Consumer Group not exist in this consumer"); } return response.release(); @@ -160,16 +160,16 @@ RemotingCommand* ClientRemotingProcessor::receiveReplyMessage(RemotingCommand* r msg->setStoreHost(string2SocketAddress(requestHeader->getStoreHost())); } - auto body = request->getBody(); - if ((requestHeader->getSysFlag() & MessageSysFlag::CompressedFlag) == MessageSysFlag::CompressedFlag) { - std::string outbody; - if (UtilAll::inflate(body->getData(), body->getSize(), outbody)) { - msg->setBody(std::move(outbody)); + auto body = request->body(); + if ((requestHeader->getSysFlag() & MessageSysFlag::COMPRESSED_FLAG) == MessageSysFlag::COMPRESSED_FLAG) { + std::string origin_body; + if (UtilAll::inflate(*body, origin_body)) { + msg->setBody(std::move(origin_body)); } else { LOG_WARN_NEW("err when uncompress constant"); } } else { - msg->setBody(body->getData(), body->getSize()); + msg->setBody(std::string(body->array(), body->size())); } msg->setFlag(requestHeader->getFlag()); @@ -182,12 +182,12 @@ RemotingCommand* ClientRemotingProcessor::receiveReplyMessage(RemotingCommand* r processReplyMessage(std::move(msg)); - response->setCode(MQResponseCode::SUCCESS); - response->setRemark(null); + response->set_code(MQResponseCode::SUCCESS); + response->set_remark(null); } catch (const std::exception& e) { LOG_WARN_NEW("unknown err when receiveReplyMsg, {}", e.what()); - response->setCode(MQResponseCode::SYSTEM_ERROR); - response->setRemark("process reply message fail"); + response->set_code(MQResponseCode::SYSTEM_ERROR); + response->set_remark("process reply message fail"); } return response.release(); diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index 1dcc163b9..a1868b614 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -74,7 +74,7 @@ void MQClientAPIImpl::createTopic(const std::string& addr, const std::string& de std::unique_ptr response(m_remotingClient->invokeSync(addr, request)); assert(response != nullptr); - switch (response->getCode()) { + switch (response->code()) { case SUCCESS: { return; } @@ -82,7 +82,7 @@ void MQClientAPIImpl::createTopic(const std::string& addr, const std::string& de break; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); } SendResult* MQClientAPIImpl::sendMessage(const std::string& addr, @@ -127,7 +127,7 @@ SendResult* MQClientAPIImpl::sendMessage(const std::string& addr, } RemotingCommand request(code, header.release()); - request.setBody(msg->getBody()); + request.set_body(msg->getBody()); switch (communicationMode) { case ComMode_ONEWAY: @@ -190,7 +190,7 @@ SendResult* MQClientAPIImpl::processSendResponse(const std::string& brokerName, const MessagePtr msg, RemotingCommand* response) { SendStatus sendStatus = SEND_OK; - switch (response->getCode()) { + switch (response->code()) { case FLUSH_DISK_TIMEOUT: sendStatus = SEND_FLUSH_DISK_TIMEOUT; break; @@ -204,7 +204,7 @@ SendResult* MQClientAPIImpl::processSendResponse(const std::string& brokerName, sendStatus = SEND_OK; break; default: - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); return nullptr; } @@ -278,7 +278,7 @@ PullResult* MQClientAPIImpl::pullMessageSync(const std::string& addr, RemotingCo PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* response) { PullStatus pullStatus = NO_NEW_MSG; - switch (response->getCode()) { + switch (response->code()) { case SUCCESS: pullStatus = FOUND; break; @@ -286,7 +286,7 @@ PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* response) { pullStatus = NO_NEW_MSG; break; case PULL_RETRY_IMMEDIATELY: - if ("OFFSET_OVERFLOW_BADLY" == response->getRemark()) { + if ("OFFSET_OVERFLOW_BADLY" == response->remark()) { pullStatus = NO_LATEST_MSG; } else { pullStatus = NO_MATCHED_MSG; @@ -296,7 +296,7 @@ PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* response) { pullStatus = OFFSET_ILLEGAL; break; default: - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); } // return of decodeCommandCustomHeader is non-null @@ -304,7 +304,7 @@ PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* response) { assert(responseHeader != nullptr); return new PullResultExt(pullStatus, responseHeader->nextBeginOffset, responseHeader->minOffset, - responseHeader->maxOffset, (int)responseHeader->suggestWhichBrokerId, response->getBody()); + responseHeader->maxOffset, (int)responseHeader->suggestWhichBrokerId, response->body()); } MQMessageExt MQClientAPIImpl::viewMessage(const std::string& addr, int64_t phyoffset, int timeoutMillis) { @@ -315,7 +315,7 @@ MQMessageExt MQClientAPIImpl::viewMessage(const std::string& addr, int64_t phyof std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); - switch (response->getCode()) { + switch (response->code()) { case SUCCESS: { // TODO: ... } @@ -323,7 +323,7 @@ MQMessageExt MQClientAPIImpl::viewMessage(const std::string& addr, int64_t phyof break; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); } int64_t MQClientAPIImpl::searchOffset(const std::string& addr, @@ -340,7 +340,7 @@ int64_t MQClientAPIImpl::searchOffset(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); - switch (response->getCode()) { + switch (response->code()) { case SUCCESS: { auto* responseHeader = response->decodeCommandCustomHeader(); assert(responseHeader != nullptr); @@ -350,7 +350,7 @@ int64_t MQClientAPIImpl::searchOffset(const std::string& addr, break; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); } int64_t MQClientAPIImpl::getMaxOffset(const std::string& addr, @@ -365,7 +365,7 @@ int64_t MQClientAPIImpl::getMaxOffset(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); - switch (response->getCode()) { + switch (response->code()) { case SUCCESS: { auto* responseHeader = response->decodeCommandCustomHeader(GET_MAX_OFFSET); return responseHeader->offset; @@ -374,7 +374,7 @@ int64_t MQClientAPIImpl::getMaxOffset(const std::string& addr, break; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); } int64_t MQClientAPIImpl::getMinOffset(const std::string& addr, @@ -389,7 +389,7 @@ int64_t MQClientAPIImpl::getMinOffset(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); - switch (response->getCode()) { + switch (response->code()) { case SUCCESS: { auto* responseHeader = response->decodeCommandCustomHeader(); assert(responseHeader != nullptr); @@ -399,7 +399,7 @@ int64_t MQClientAPIImpl::getMinOffset(const std::string& addr, break; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); } int64_t MQClientAPIImpl::getEarliestMsgStoretime(const std::string& addr, @@ -414,7 +414,7 @@ int64_t MQClientAPIImpl::getEarliestMsgStoretime(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); - switch (response->getCode()) { + switch (response->code()) { case SUCCESS: { auto* responseHeader = response->decodeCommandCustomHeader(); assert(responseHeader != nullptr); @@ -424,7 +424,7 @@ int64_t MQClientAPIImpl::getEarliestMsgStoretime(const std::string& addr, break; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); } void MQClientAPIImpl::getConsumerIdListByGroup(const std::string& addr, @@ -438,10 +438,10 @@ void MQClientAPIImpl::getConsumerIdListByGroup(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); - switch (response->getCode()) { + switch (response->code()) { case SUCCESS: { - auto responseBody = response->getBody(); - if (responseBody != nullptr && responseBody->getSize() > 0) { + auto responseBody = response->body(); + if (responseBody != nullptr && responseBody->size() > 0) { std::unique_ptr body( GetConsumerListByGroupResponseBody::Decode(*responseBody)); cids = std::move(body->consumerIdList); @@ -454,7 +454,7 @@ void MQClientAPIImpl::getConsumerIdListByGroup(const std::string& addr, break; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); } int64_t MQClientAPIImpl::queryConsumerOffset(const std::string& addr, @@ -464,7 +464,7 @@ int64_t MQClientAPIImpl::queryConsumerOffset(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); - switch (response->getCode()) { + switch (response->code()) { case SUCCESS: { auto* responseHeader = response->decodeCommandCustomHeader(); assert(responseHeader != nullptr); @@ -474,7 +474,7 @@ int64_t MQClientAPIImpl::queryConsumerOffset(const std::string& addr, break; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); } void MQClientAPIImpl::updateConsumerOffset(const std::string& addr, @@ -484,7 +484,7 @@ void MQClientAPIImpl::updateConsumerOffset(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); - switch (response->getCode()) { + switch (response->code()) { case SUCCESS: { return; } @@ -492,7 +492,7 @@ void MQClientAPIImpl::updateConsumerOffset(const std::string& addr, break; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); } void MQClientAPIImpl::updateConsumerOffsetOneway(const std::string& addr, @@ -505,11 +505,11 @@ void MQClientAPIImpl::updateConsumerOffsetOneway(const std::string& addr, void MQClientAPIImpl::sendHearbeat(const std::string& addr, HeartbeatData* heartbeatData, long timeoutMillis) { RemotingCommand request(HEART_BEAT, nullptr); - request.setBody(heartbeatData->encode()); + request.set_body(heartbeatData->encode()); std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); - switch (response->getCode()) { + switch (response->code()) { case SUCCESS: { LOG_DEBUG_NEW("sendHeartbeat to broker:{} success", addr); return; @@ -518,7 +518,7 @@ void MQClientAPIImpl::sendHearbeat(const std::string& addr, HeartbeatData* heart break; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); } void MQClientAPIImpl::unregisterClient(const std::string& addr, @@ -530,7 +530,7 @@ void MQClientAPIImpl::unregisterClient(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request)); assert(response != nullptr); - switch (response->getCode()) { + switch (response->code()) { case SUCCESS: LOG_INFO("unregisterClient to:%s success", addr.c_str()); return; @@ -538,15 +538,15 @@ void MQClientAPIImpl::unregisterClient(const std::string& addr, break; } - LOG_WARN("unregisterClient fail:%s, %d", response->getRemark().c_str(), response->getCode()); - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + LOG_WARN("unregisterClient fail:%s, %d", response->remark().c_str(), response->code()); + THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); } void MQClientAPIImpl::endTransactionOneway(const std::string& addr, EndTransactionRequestHeader* requestHeader, const std::string& remark) { RemotingCommand request(END_TRANSACTION, requestHeader); - request.setRemark(remark); + request.set_remark(remark); m_remotingClient->invokeOneway(addr, request); } @@ -569,7 +569,7 @@ void MQClientAPIImpl::consumerSendMessageBack(const std::string& addr, std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); - switch (response->getCode()) { + switch (response->code()) { case SUCCESS: { return; } @@ -577,7 +577,7 @@ void MQClientAPIImpl::consumerSendMessageBack(const std::string& addr, break; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); } void MQClientAPIImpl::lockBatchMQ(const std::string& addr, @@ -585,14 +585,14 @@ void MQClientAPIImpl::lockBatchMQ(const std::string& addr, std::vector& mqs, int timeoutMillis) { RemotingCommand request(LOCK_BATCH_MQ, nullptr); - request.setBody(requestBody->encode()); + request.set_body(requestBody->encode()); std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); - switch (response->getCode()) { + switch (response->code()) { case SUCCESS: { - auto requestBody = response->getBody(); - if (requestBody != nullptr && requestBody->getSize() > 0) { + auto requestBody = response->body(); + if (requestBody != nullptr && requestBody->size() > 0) { std::unique_ptr body(LockBatchResponseBody::Decode(*requestBody)); mqs = body->getLockOKMQSet(); } else { @@ -604,7 +604,7 @@ void MQClientAPIImpl::lockBatchMQ(const std::string& addr, break; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); } void MQClientAPIImpl::unlockBatchMQ(const std::string& addr, @@ -612,14 +612,14 @@ void MQClientAPIImpl::unlockBatchMQ(const std::string& addr, int timeoutMillis, bool oneway) { RemotingCommand request(UNLOCK_BATCH_MQ, nullptr); - request.setBody(requestBody->encode()); + request.set_body(requestBody->encode()); if (oneway) { m_remotingClient->invokeOneway(addr, request); } else { std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); - switch (response->getCode()) { + switch (response->code()) { case SUCCESS: { return; } break; @@ -627,7 +627,7 @@ void MQClientAPIImpl::unlockBatchMQ(const std::string& addr, break; } - THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); } } @@ -636,21 +636,19 @@ TopicRouteData* MQClientAPIImpl::getTopicRouteInfoFromNameServer(const std::stri std::unique_ptr response(m_remotingClient->invokeSync(null, request, timeoutMillis)); assert(response != nullptr); - switch (response->getCode()) { - case TOPIC_NOT_EXIST: { - break; - } + switch (response->code()) { case SUCCESS: { - auto responseBody = response->getBody(); - if (responseBody != nullptr && responseBody->getSize() > 0) { + auto responseBody = response->body(); + if (responseBody != nullptr && responseBody->size() > 0) { return TopicRouteData::Decode(*responseBody); } } + case TOPIC_NOT_EXIST: default: break; } - THROW_MQEXCEPTION(MQClientException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQClientException, response->remark(), response->code()); } TopicList* MQClientAPIImpl::getTopicListFromNameServer() { @@ -658,10 +656,10 @@ TopicList* MQClientAPIImpl::getTopicListFromNameServer() { std::unique_ptr response(m_remotingClient->invokeSync(null, request)); assert(response != nullptr); - switch (response->getCode()) { + switch (response->code()) { case SUCCESS: { - auto responseBody = response->getBody(); - if (responseBody != nullptr && responseBody->getSize() > 0) { + auto responseBody = response->body(); + if (responseBody != nullptr && responseBody->size() > 0) { return TopicList::Decode(*responseBody); } } @@ -669,7 +667,7 @@ TopicList* MQClientAPIImpl::getTopicListFromNameServer() { break; } - THROW_MQEXCEPTION(MQClientException, response->getRemark(), response->getCode()); + THROW_MQEXCEPTION(MQClientException, response->remark(), response->code()); } int MQClientAPIImpl::wipeWritePermOfBroker(const std::string& namesrvAddr, diff --git a/src/common/ByteOrder.h b/src/common/ByteOrder.h index cdc52a9e3..24744fa54 100644 --- a/src/common/ByteOrder.h +++ b/src/common/ByteOrder.h @@ -17,234 +17,163 @@ #ifndef ROCKETMQ_COMMON_BYTEORDER_H_ #define ROCKETMQ_COMMON_BYTEORDER_H_ -#include +#include // std::memcpy + +#include // std::enable_if, std::is_integral, std::make_unsigned, std::add_pointer + +#include "RocketMQClient.h" namespace rocketmq { +enum ByteOrder { BO_BIG_ENDIAN, BO_LITTLE_ENDIAN }; + /** * Contains static methods for converting the byte order between different endiannesses. */ -class ByteOrder { +class ByteOrderUtil { public: - //============================================================================== + static constexpr ByteOrder native_order() { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ // __BYTE_ORDER__ is defined by GCC + return ByteOrder::BO_LITTLE_ENDIAN; +#else + return ByteOrder::BO_BIG_ENDIAN; +#endif + } - /** Swaps the upper and lower bytes of a 16-bit integer. */ - static uint16_t swap(uint16_t value); - - /** Reverses the order of the 4 bytes in a 32-bit integer. */ - static uint32_t swap(uint32_t value); - - /** Reverses the order of the 8 bytes in a 64-bit integer. */ - static uint64_t swap(uint64_t value); + /** Returns true if the current CPU is big-endian. */ + static constexpr bool isBigEndian() { return native_order() == ByteOrder::BO_BIG_ENDIAN; } //============================================================================== - /** Swaps the byte order of a 16-bit int if the CPU is big-endian */ - static uint16_t swapIfBigEndian(uint16_t value); + template ::type = 0> + static inline T ReinterpretRawBits(F value) { + return *reinterpret_cast(&value); + } - /** Swaps the byte order of a 32-bit int if the CPU is big-endian */ - static uint32_t swapIfBigEndian(uint32_t value); + static inline uint8_t swap(uint8_t n) { return n; } - /** Swaps the byte order of a 64-bit int if the CPU is big-endian */ - static uint64_t swapIfBigEndian(uint64_t value); - - /** Swaps the byte order of a 16-bit int if the CPU is little-endian */ - static uint16_t swapIfLittleEndian(uint16_t value); + /** Swaps the upper and lower bytes of a 16-bit integer. */ + static inline uint16_t swap(uint16_t n) { return static_cast((n << 8) | (n >> 8)); } - /** Swaps the byte order of a 32-bit int if the CPU is little-endian */ - static uint32_t swapIfLittleEndian(uint32_t value); + /** Reverses the order of the 4 bytes in a 32-bit integer. */ + static inline uint32_t swap(uint32_t n) { + return (n << 24) | (n >> 24) | ((n & 0x0000ff00) << 8) | ((n & 0x00ff0000) >> 8); + } - /** Swaps the byte order of a 64-bit int if the CPU is little-endian */ - static uint64_t swapIfLittleEndian(uint64_t value); + /** Reverses the order of the 8 bytes in a 64-bit integer. */ + static inline uint64_t swap(uint64_t value) { + return (((uint64_t)swap((uint32_t)value)) << 32) | swap((uint32_t)(value >> 32)); + } //============================================================================== - /** Turns 4 bytes into a little-endian integer. */ - static uint32_t littleEndianInt(const void* bytes); + /** convert integer to little-endian */ + template ::value, int>::type = 0> + static inline typename std::make_unsigned::type NorminalLittleEndian(T value) { +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + return swap(static_cast::type>(value)); +#else + return static_cast::type>(value); +#endif + } + + /** convert integer to big-endian */ + template ::value, int>::type = 0> + static inline typename std::make_unsigned::type NorminalBigEndian(T value) { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + return swap(static_cast::type>(value)); +#else + return static_cast::type>(value); +#endif + } - /** Turns 8 bytes into a little-endian integer. */ - static uint64_t littleEndianInt64(const void* bytes); + //============================================================================== - /** Turns 2 bytes into a little-endian integer. */ - static uint16_t littleEndianShort(const void* bytes); + template + static inline T Read(const char* bytes) { + T value; + std::memcpy(&value, bytes, sizeof(T)); + return value; + } + + template ::value = 0> + static inline T Read(const char* bytes) { + T value; + for (size_t i = 0; i < sizeof(T); i++) { + ((char*)&value)[i] = bytes[i]; + } + return value; + } + + template + static inline void Read(T* value, const char* bytes) { + std::memcpy(value, bytes, sizeof(T)); + } + + template ::value = 0> + static inline void Read(T* value, const char* bytes) { + for (size_t i = 0; i < sizeof(T); i++) { + ((char*)value)[i] = bytes[i]; + } + } - /** Turns 4 bytes into a big-endian integer. */ - static uint32_t bigEndianInt(const void* bytes); + //============================================================================== - /** Turns 8 bytes into a big-endian integer. */ - static uint64_t bigEndianInt64(const void* bytes); + template + static inline void Write(char* bytes, T value) { + std::memcpy(bytes, &value, sizeof(T)); + } - /** Turns 2 bytes into a big-endian integer. */ - static uint16_t bigEndianShort(const void* bytes); + template ::value = 0> + static inline void Write(char* bytes, T value) { + for (size_t i = 0; i < sizeof(T); i++) { + bytes[i] = ((char*)&value)[i]; + } + } //============================================================================== - /** 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); + template ::value, int>::type = 0> + static inline T ReadLittleEndian(const char* bytes) { + auto value = Read(bytes); + return NorminalLittleEndian(value); + } - /** Copies a 24-bit number to 3 little-endian bytes. */ - static void littleEndian24BitToChars(int value, void* destBytes); + template ::value, int>::type = 0> + static inline T ReadBigEndian(const char* bytes) { + auto value = Read(bytes); + return NorminalBigEndian(value); + } - /** Copies a 24-bit number to 3 big-endian bytes. */ - static void bigEndian24BitToChars(int value, void* destBytes); + template ::value, int>::type = 0> + static inline T Read(const char* bytes, bool big_endian) { + return big_endian ? ReadBigEndian(bytes) : ReadLittleEndian(bytes); + } //============================================================================== - /** Returns true if the current CPU is big-endian. */ - static bool isBigEndian(); + template ::value, int>::type = 0> + static inline void WriteLittleEndian(char* bytes, T value) { + value = NorminalLittleEndian(value); + Write(bytes, value); + } + + template ::value, int>::type = 0> + static inline void WriteBigEndian(char* bytes, T value) { + value = NorminalBigEndian(value); + Write(bytes, value); + } + + template ::value, int>::type = 0> + static inline void Write(char* bytes, T value, bool big_endian) { + if (big_endian) { + WriteBigEndian(bytes, value); + } else { + WriteLittleEndian(bytes, value); + } + } }; -//============================================================================== - -inline uint16_t ByteOrder::swap(uint16_t n) { - return static_cast((n << 8) | (n >> 8)); -} - -inline uint32_t ByteOrder::swap(uint32_t n) { - return (n << 24) | (n >> 24) | ((n & 0xff00) << 8) | ((n & 0xff0000) >> 8); -} - -inline uint64_t ByteOrder::swap(uint64_t value) { - return (((uint64_t)swap((uint32_t)value)) << 32) | swap((uint32_t)(value >> 32)); -} - -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ //__BYTE_ORDER__ is defined by GCC - -inline uint16_t ByteOrder::swapIfBigEndian(const uint16_t v) { - return v; -} - -inline uint32_t ByteOrder::swapIfBigEndian(const uint32_t v) { - return v; -} - -inline uint64_t ByteOrder::swapIfBigEndian(const uint64_t v) { - return v; -} - -inline uint16_t ByteOrder::swapIfLittleEndian(const uint16_t v) { - return swap(v); -} - -inline uint32_t ByteOrder::swapIfLittleEndian(const uint32_t v) { - return swap(v); -} - -inline uint64_t ByteOrder::swapIfLittleEndian(const uint64_t v) { - return swap(v); -} - -inline uint32_t ByteOrder::littleEndianInt(const void* const bytes) { - return *static_cast(bytes); -} - -inline uint64_t ByteOrder::littleEndianInt64(const void* const bytes) { - return *static_cast(bytes); -} - -inline uint16_t ByteOrder::littleEndianShort(const void* const bytes) { - return *static_cast(bytes); -} - -inline uint32_t ByteOrder::bigEndianInt(const void* const bytes) { - return swap(*static_cast(bytes)); -} - -inline uint64_t ByteOrder::bigEndianInt64(const void* const bytes) { - return swap(*static_cast(bytes)); -} - -inline uint16_t ByteOrder::bigEndianShort(const void* const bytes) { - return swap(*static_cast(bytes)); -} - -inline bool ByteOrder::isBigEndian() { - return false; -} - -#else // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - -inline uint16_t ByteOrder::swapIfBigEndian(const uint16_t v) { - return swap(v); -} - -inline uint32_t ByteOrder::swapIfBigEndian(const uint32_t v) { - return swap(v); -} - -inline uint64_t ByteOrder::swapIfBigEndian(const uint64_t v) { - return swap(v); -} - -inline uint16_t ByteOrder::swapIfLittleEndian(const uint16_t v) { - return v; -} - -inline uint32_t ByteOrder::swapIfLittleEndian(const uint32_t v) { - return v; -} - -inline uint64_t ByteOrder::swapIfLittleEndian(const uint64_t v) { - return v; -} - -inline uint32_t ByteOrder::littleEndianInt(const void* const bytes) { - return swap(*static_cast(bytes)); -} - -inline uint64_t ByteOrder::littleEndianInt64(const void* const bytes) { - return swap(*static_cast(bytes)); -} - -inline uint16_t ByteOrder::littleEndianShort(const void* const bytes) { - return swap(*static_cast(bytes)); -} - -inline uint32_t ByteOrder::bigEndianInt(const void* const bytes) { - return *static_cast(bytes); -} - -inline uint64_t ByteOrder::bigEndianInt64(const void* const bytes) { - return *static_cast(bytes); -} - -inline uint16_t ByteOrder::bigEndianShort(const void* const bytes) { - return *static_cast(bytes); -} - -inline bool ByteOrder::isBigEndian() { - return true; -} - -#endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - -inline int ByteOrder::littleEndian24Bit(const void* const bytes) { - return (((int)static_cast(bytes)[2]) << 16) | (((int)static_cast(bytes)[1]) << 8) | - ((int)static_cast(bytes)[0]); -} - -inline int ByteOrder::bigEndian24Bit(const void* const bytes) { - return (((int)static_cast(bytes)[0]) << 16) | (((int)static_cast(bytes)[1]) << 8) | - ((int)static_cast(bytes)[2]); -} - -inline void ByteOrder::littleEndian24BitToChars(const int value, void* const destBytes) { - static_cast(destBytes)[0] = (uint8_t)value; - static_cast(destBytes)[1] = (uint8_t)(value >> 8); - static_cast(destBytes)[2] = (uint8_t)(value >> 16); -} - -inline void ByteOrder::bigEndian24BitToChars(const int value, void* const destBytes) { - static_cast(destBytes)[0] = (uint8_t)(value >> 16); - static_cast(destBytes)[1] = (uint8_t)(value >> 8); - static_cast(destBytes)[2] = (uint8_t)value; -} - } // namespace rocketmq #endif // ROCKETMQ_COMMON_BYTEORDER_H_ diff --git a/src/common/ClientRPCHook.cpp b/src/common/ClientRPCHook.cpp index 356b0cf83..6c348526f 100644 --- a/src/common/ClientRPCHook.cpp +++ b/src/common/ClientRPCHook.cpp @@ -18,7 +18,6 @@ #include -#include "DataBlock.h" #include "Logging.h" #include "RemotingCommand.h" #include "protocol/header/CommandHeader.h" @@ -51,8 +50,8 @@ void ClientRPCHook::doAfterResponse(const std::string& remoteAddr, void ClientRPCHook::signCommand(RemotingCommand& command) { std::map headerMap; - headerMap.insert(std::make_pair(SessionCredentials::AccessKey, sessionCredentials_.getAccessKey())); - headerMap.insert(std::make_pair(SessionCredentials::ONSChannelKey, sessionCredentials_.getAuthChannel())); + headerMap.insert(std::make_pair(SessionCredentials::AccessKey, session_credentials_.getAccessKey())); + headerMap.insert(std::make_pair(SessionCredentials::ONSChannelKey, session_credentials_.getAuthChannel())); LOG_DEBUG_NEW("before insert declared filed, MAP SIZE is:{}", headerMap.size()); auto* header = command.readCustomHeader(); @@ -65,20 +64,20 @@ void ClientRPCHook::signCommand(RemotingCommand& command) { for (const auto& it : headerMap) { totalMsg.append(it.second); } - auto body = command.getBody(); - if (body != nullptr && body->getSize() > 0) { - LOG_DEBUG_NEW("request have msgBody, length is:{}", body->getSize()); - totalMsg.append(body->getData(), body->getSize()); + auto body = command.body(); + if (body != nullptr && body->size() > 0) { + LOG_DEBUG_NEW("request have msgBody, length is:{}", body->size()); + totalMsg.append(body->array(), body->size()); } LOG_DEBUG_NEW("total msg info are:{}, size is:{}", totalMsg, totalMsg.size()); char* sign = - rocketmqSignature::spas_sign(totalMsg.c_str(), totalMsg.size(), sessionCredentials_.getSecretKey().c_str()); + rocketmqSignature::spas_sign(totalMsg.c_str(), totalMsg.size(), session_credentials_.getSecretKey().c_str()); if (sign != nullptr) { std::string signature(static_cast(sign)); - command.addExtField(SessionCredentials::Signature, signature); - command.addExtField(SessionCredentials::AccessKey, sessionCredentials_.getAccessKey()); - command.addExtField(SessionCredentials::ONSChannelKey, sessionCredentials_.getAuthChannel()); + command.set_ext_field(SessionCredentials::Signature, signature); + command.set_ext_field(SessionCredentials::AccessKey, session_credentials_.getAccessKey()); + command.set_ext_field(SessionCredentials::ONSChannelKey, session_credentials_.getAuthChannel()); rocketmqSignature::spas_mem_free(sign); } else { LOG_ERROR_NEW("signature for request failed"); diff --git a/src/common/DataBlock.cpp b/src/common/DataBlock.cpp deleted file mode 100644 index 6592b85fa..000000000 --- a/src/common/DataBlock.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * 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 -#include -#include - -namespace rocketmq { - -//###################################### -// MemoryBlock -//###################################### - -void MemoryBlock::copyTo(void* dst, ssize_t offset, size_t num) const { - char* d = static_cast(dst); - - if (offset < 0) { - memset(d, 0, -offset); - d += (-offset); - num -= (-offset); - offset = 0; - } - - if (offset + num > size_) { - size_t newNum = size_ - offset; - memset(d + newNum, 0, num - newNum); - num = newNum; - } - - if (num > 0) { - memcpy(d, data_ + offset, num); - } -} - -//###################################### -// MemoryPool -//###################################### - -MemoryPool::MemoryPool() : MemoryBlock() {} - -MemoryPool::MemoryPool(size_t initialSize, bool initialiseToZero) : MemoryBlock(nullptr, initialSize) { - if (size_ > 0) { - data_ = static_cast(initialiseToZero ? std::calloc(initialSize, sizeof(char)) - : std::malloc(initialSize * sizeof(char))); - } -} - -MemoryPool::MemoryPool(const void* const dataToInitialiseFrom, size_t sizeInBytes) : MemoryBlock(nullptr, sizeInBytes) { - if (size_ > 0) { - data_ = static_cast(std::malloc(size_ * sizeof(char))); - - if (dataToInitialiseFrom != nullptr) { - memcpy(data_, dataToInitialiseFrom, size_); - } - } -} - -MemoryPool::MemoryPool(const MemoryPool& other) : MemoryBlock(nullptr, other.size_) { - if (size_ > 0) { - data_ = static_cast(std::malloc(size_ * sizeof(char))); - memcpy(data_, other.data_, size_); - } -} - -MemoryPool::MemoryPool(MemoryPool&& other) : MemoryBlock(other.data_, other.size_) { - other.size_ = 0; - other.data_ = nullptr; -} - -MemoryPool::~MemoryPool() { - std::free(data_); -} - -MemoryPool& MemoryPool::operator=(const MemoryPool& other) { - if (this != &other) { - setSize(other.size_, false); - memcpy(data_, other.data_, size_); - } - return *this; -} - -MemoryPool& MemoryPool::operator=(MemoryPool&& other) { - if (this != &other) { - std::free(data_); - - size_ = other.size_; - data_ = other.data_; - - other.size_ = 0; - other.data_ = nullptr; - } - return *this; -} - -//============================================================================== -bool MemoryPool::matches(const void* dataToCompare, size_t dataSize) const { - return size_ == dataSize && memcmp(data_, dataToCompare, size_) == 0; -} - -bool MemoryPool::operator==(const MemoryPool& other) const { - return matches(other.data_, other.size_); -} - -bool MemoryPool::operator!=(const MemoryPool& other) const { - return !operator==(other); -} - -//============================================================================== -void MemoryPool::reset() { - reset(nullptr, 0); -} - -void MemoryPool::reset(char* data, size_t size) { - if (size != 0) { - throw std::runtime_error("MemoryPool can't set external pointer as data."); - } - - std::free(data_); - data_ = nullptr; - size_ = 0; -} - -// this will resize the block to this size_ -void MemoryPool::setSize(size_t newSize, bool initialiseToZero) { - if (size_ != newSize) { - if (newSize <= 0) { - reset(); - } else { - if (data_ != nullptr) { - data_ = static_cast(std::realloc(data_, newSize * sizeof(char))); - - if (initialiseToZero && (newSize > size_)) { - memset(data_ + size_, 0, newSize - size_); - } - } else { - data_ = static_cast(initialiseToZero ? std::calloc(newSize, sizeof(char)) - : std::malloc(newSize * sizeof(char))); - } - - size_ = newSize; - } - } -} - -void MemoryPool::ensureSize(size_t minimumSize, bool initialiseToZero) { - if (size_ < minimumSize) { - setSize(minimumSize, initialiseToZero); - } -} - -//============================================================================== -void MemoryPool::fillWith(int value) { - memset(data_, value, size_); -} - -void MemoryPool::append(const void* const srcData, size_t numBytes) { - if (numBytes > 0) { - size_t oldSize = size_; - setSize(size_ + numBytes); - memcpy(data_ + oldSize, srcData, numBytes); - } -} - -void MemoryPool::replaceWith(const void* const srcData, size_t numBytes) { - if (numBytes > 0) { - setSize(numBytes); - memcpy(data_, srcData, numBytes); - } -} - -void MemoryPool::insert(const void* const srcData, size_t numBytes, size_t insertPosition) { - if (numBytes > 0) { - insertPosition = std::min(insertPosition, size_); - size_t trailingDataSize = size_ - insertPosition; - setSize(size_ + numBytes, false); - - if (trailingDataSize > 0) { - memmove(data_ + insertPosition + numBytes, data_ + insertPosition, trailingDataSize); - } - - memcpy(data_ + insertPosition, srcData, numBytes); - } -} - -void MemoryPool::removeSection(size_t startByte, size_t numBytesToRemove) { - if (startByte + numBytesToRemove >= size_) { - setSize(startByte); - } else if (numBytesToRemove > 0) { - memmove(data_ + startByte, data_ + startByte + numBytesToRemove, size_ - (startByte + numBytesToRemove)); - setSize(size_ - numBytesToRemove); - } -} - -void MemoryPool::copyFrom(const void* src, ssize_t offset, size_t num) { - const char* d = static_cast(src); - - if (offset < 0) { - d += (-offset); - num -= (-offset); - offset = 0; - } - - if (offset + num > size_) { - num = size_ - offset; - } - - if (num > 0) { - memcpy(data_ + offset, d, num); - } -} - -//###################################### -// MemoryView -//###################################### - -void MemoryView::reset() { - reset(nullptr, 0); -} - -void MemoryView::reset(char* data, size_t size) { - throw std::runtime_error("MemoryView can't reset()."); -} - -} // namespace rocketmq diff --git a/src/common/FilterAPI.h b/src/common/FilterAPI.h index 86e89a8ef..3ca8b31a4 100644 --- a/src/common/FilterAPI.h +++ b/src/common/FilterAPI.h @@ -43,7 +43,7 @@ class FilterAPI { UtilAll::Trim(tag); if (!tag.empty()) { subscriptionData->putTagsSet(tag); - subscriptionData->putCodeSet(UtilAll::HashCode(tag)); + subscriptionData->putCodeSet(UtilAll::hash_code(tag)); } } } diff --git a/src/common/InputStream.cpp b/src/common/InputStream.cpp deleted file mode 100644 index 5a53819e2..000000000 --- a/src/common/InputStream.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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 - -#include "MemoryOutputStream.h" -#include "big_endian.h" - -namespace rocketmq { - -int64_t InputStream::getNumBytesRemaining() { - int64_t 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_t InputStream::readInt64BigEndian() { - char asBytes[8]; - uint64_t asInt64; - - if (read(asBytes, 8) == 8) { - ReadBigEndian(asBytes, &asInt64); - return asInt64; - } - return 0; -} - -float InputStream::readFloatBigEndian() { - union { - int32_t asInt; - float asFloat; - } n; - n.asInt = (int32_t)readIntBigEndian(); - return n.asFloat; -} - -double InputStream::readDoubleBigEndian() { - union { - int64_t asInt; - double asDouble; - } n; - n.asInt = readInt64BigEndian(); - return n.asDouble; -} - -size_t InputStream::readIntoMemoryBlock(MemoryPool& block, size_t numBytes) { - MemoryOutputStream mo(block, true); - return (size_t)mo.writeFromInputStream(*this, numBytes); -} - -//============================================================================== -void InputStream::skipNextBytes(int64_t numBytesToSkip) { - if (numBytesToSkip > 0) { - const int skipBufferSize = (int)std::min(numBytesToSkip, (int64_t)16384); - char* temp = static_cast(std::malloc(skipBufferSize * sizeof(char))); - - while (numBytesToSkip > 0 && !isExhausted()) - numBytesToSkip -= read(temp, (int)std::min(numBytesToSkip, (int64_t)skipBufferSize)); - - std::free(temp); - } -} -} // namespace rocketmq diff --git a/src/common/InputStream.h b/src/common/InputStream.h deleted file mode 100644 index 1a29bc8a7..000000000 --- a/src/common/InputStream.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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 __INPUT_STREAM_H__ -#define __INPUT_STREAM_H__ - -#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_t getTotalLength() = 0; - - /** Returns the number of bytes available for reading, or a negative value if - the remaining length is not known. - @see getTotalLength - */ - int64_t 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_t 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_t. - 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(MemoryPool& destBlock, size_t maxNumBytesToRead = -1); - - //============================================================================== - /** Returns the offset of the next byte that will be read from the stream. - @see setPosition - */ - virtual int64_t 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_t 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_t numBytesToSkip); - - protected: - //============================================================================== - InputStream() {} -}; - -} // namespace rocketmq - -#endif // __INPUT_STREAM_H__ diff --git a/src/common/MemoryInputStream.cpp b/src/common/MemoryInputStream.cpp deleted file mode 100644 index 057b8111c..000000000 --- a/src/common/MemoryInputStream.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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" - -#include -#include - -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(nullptr) { - if (keepInternalCopy) { - createInternalCopy(); - } -} - -void MemoryInputStream::createInternalCopy() { - std::free(internalCopy); - internalCopy = static_cast(std::malloc(dataSize)); - memcpy(internalCopy, data, dataSize); - data = internalCopy; -} - -MemoryInputStream::~MemoryInputStream() { - std::free(internalCopy); -} - -int64_t MemoryInputStream::getTotalLength() { - return (int64_t)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_t pos) { - if (pos < 0) - position = 0; - else - position = (int64_t)dataSize < pos ? (int64_t)dataSize : pos; - - return true; -} - -int64_t MemoryInputStream::getPosition() { - return (int64_t)position; -} - -} // namespace rocketmq diff --git a/src/common/MemoryInputStream.h b/src/common/MemoryInputStream.h deleted file mode 100644 index 2097ec6df..000000000 --- a/src/common/MemoryInputStream.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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 __MEMORY_INTPUT_STREAM_H__ -#define __MEMORY_INTPUT_STREAM_H__ - -#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_t getPosition(); - bool setPosition(int64_t pos); - int64_t getTotalLength(); - bool isExhausted(); - int read(void* destBuffer, int maxBytesToRead); - - private: - //============================================================================== - const void* data; - size_t dataSize, position; - char* internalCopy; - - void createInternalCopy(); -}; - -} // namespace rocketmq - -#endif // __MEMORY_INTPUT_STREAM_H__ diff --git a/src/common/MemoryOutputStream.cpp b/src/common/MemoryOutputStream.cpp deleted file mode 100644 index 1c4f4da41..000000000 --- a/src/common/MemoryOutputStream.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 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" - -#include -#include - -namespace rocketmq { - -MemoryOutputStream::MemoryOutputStream(const size_t initialSize) - : poolToUse(&internalPool), externalData(nullptr), position(0), size(0), availableSize(0) { - internalPool.setSize(initialSize, false); -} - -MemoryOutputStream::MemoryOutputStream(MemoryPool& memoryBlockToWriteTo, const bool appendToExistingBlockContent) - : poolToUse(&memoryBlockToWriteTo), externalData(NULL), position(0), size(0), availableSize(0) { - if (appendToExistingBlockContent) { - position = size = memoryBlockToWriteTo.getSize(); - } -} - -MemoryOutputStream::MemoryOutputStream(void* destBuffer, size_t destBufferSize) - : poolToUse(NULL), externalData(destBuffer), position(0), size(0), availableSize(destBufferSize) {} - -MemoryOutputStream::~MemoryOutputStream() { - trimExternalBlockSize(); -} - -void MemoryOutputStream::flush() { - trimExternalBlockSize(); -} - -void MemoryOutputStream::trimExternalBlockSize() { - if (poolToUse != &internalPool && poolToUse != NULL) { - poolToUse->setSize(size, false); - } -} - -void MemoryOutputStream::preallocate(const size_t bytesToPreallocate) { - if (poolToUse != NULL) { - poolToUse->ensureSize(bytesToPreallocate + 1); - } -} - -void MemoryOutputStream::reset() { - position = 0; - size = 0; -} - -char* MemoryOutputStream::prepareToWrite(size_t numBytes) { - size_t storageNeeded = position + numBytes; - - char* data; - - if (poolToUse != NULL) { - if (storageNeeded >= (unsigned int)(poolToUse->getSize())) { - poolToUse->ensureSize((storageNeeded + std::min(storageNeeded / 2, (size_t)(1024 * 1024)) + 32) & ~31u); - } - - data = static_cast(poolToUse->getData()); - } else { - if (storageNeeded > availableSize) { - return NULL; - } - - data = static_cast(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_t byte, size_t howMany) { - if (howMany == 0) { - return true; - } - - if (char* dest = prepareToWrite(howMany)) { - memset(dest, byte, howMany); - return true; - } - - return false; -} - -MemoryPool MemoryOutputStream::getMemoryBlock() const { - return MemoryPool(getData(), getDataSize()); -} - -const void* MemoryOutputStream::getData() const { - if (poolToUse == NULL) { - return externalData; - } - - if (poolToUse->getSize() > size) { - poolToUse->getData()[size] = 0; - } - - return poolToUse->getData(); -} - -bool MemoryOutputStream::setPosition(int64_t newPosition) { - if (newPosition <= (int64_t)size) { - // ok to seek backwards - if (newPosition < 0) { - position = 0; - } else { - position = (int64_t)size < newPosition ? size : newPosition; - } - return true; - } - - // can't move beyond the end of the stream.. - return false; -} - -int64_t MemoryOutputStream::writeFromInputStream(InputStream& source, int64_t maxNumBytesToWrite) { - // before writing from an input, see if we can preallocate to make it more efficient.. - int64_t availableData = source.getTotalLength() - source.getPosition(); - - if (availableData > 0) { - if (maxNumBytesToWrite > availableData || maxNumBytesToWrite < 0) { - maxNumBytesToWrite = availableData; - } - - if (poolToUse != NULL) { - preallocate(poolToUse->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 diff --git a/src/common/MemoryOutputStream.h b/src/common/MemoryOutputStream.h deleted file mode 100644 index ece1a19a8..000000000 --- a/src/common/MemoryOutputStream.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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 __MEMORY_OUTPUT_STREAM_H__ -#define __MEMORY_OUTPUT_STREAM_H__ - -#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(MemoryPool& 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. */ - MemoryPool 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_t getPosition() { return (int64_t)position; } - bool setPosition(int64_t); - int64_t writeFromInputStream(InputStream&, int64_t maxNumBytesToWrite); - bool writeRepeatedByte(uint8_t byte, size_t numTimesToRepeat); - - private: - //============================================================================== - MemoryPool* const poolToUse; - MemoryPool internalPool; - 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 // __MEMORY_OUTPUT_STREAM_H__ diff --git a/src/common/MessageSysFlag.cpp b/src/common/MessageSysFlag.cpp index a61d36c0f..cded96c42 100644 --- a/src/common/MessageSysFlag.cpp +++ b/src/common/MessageSysFlag.cpp @@ -18,27 +18,27 @@ namespace rocketmq { -const int MessageSysFlag::CompressedFlag = 0x1 << 0; -const int MessageSysFlag::MultiTagsFlag = 0x1 << 1; +const int MessageSysFlag::COMPRESSED_FLAG = 0x1 << 0; +const int MessageSysFlag::MULTI_TAGS_FLAG = 0x1 << 1; -const int MessageSysFlag::TransactionNotType = 0x0; -const int MessageSysFlag::TransactionPreparedType = 0x1 << 2; -const int MessageSysFlag::TransactionCommitType = 0x2 << 2; -const int MessageSysFlag::TransactionRollbackType = 0x3 << 2; +const int MessageSysFlag::TRANSACTION_NOT_TYPE = 0x0; +const int MessageSysFlag::TRANSACTION_PREPARED_TYPE = 0x1 << 2; +const int MessageSysFlag::TRANSACTION_COMMIT_TYPE = 0x2 << 2; +const int MessageSysFlag::TRANSACTION_ROLLBACK_TYPE = 0x3 << 2; -const int MessageSysFlag::BronhostV6Flag = 0x1 << 4; -const int MessageSysFlag::StorehostV6Flag = 0x1 << 5; +const int MessageSysFlag::BORNHOST_V6_FLAG = 0x1 << 4; +const int MessageSysFlag::STOREHOST_V6_FLAG = 0x1 << 5; int MessageSysFlag::getTransactionValue(int flag) { - return flag & TransactionRollbackType; + return flag & TRANSACTION_ROLLBACK_TYPE; } int MessageSysFlag::resetTransactionValue(int flag, int type) { - return (flag & (~TransactionRollbackType)) | type; + return (flag & (~TRANSACTION_ROLLBACK_TYPE)) | type; } int MessageSysFlag::clearCompressedFlag(int flag) { - return flag & (~CompressedFlag); + return flag & (~COMPRESSED_FLAG); } } // namespace rocketmq diff --git a/src/common/MessageSysFlag.h b/src/common/MessageSysFlag.h index 8c61579c6..6948e3792 100644 --- a/src/common/MessageSysFlag.h +++ b/src/common/MessageSysFlag.h @@ -21,22 +21,22 @@ namespace rocketmq { class MessageSysFlag { public: - static int getTransactionValue(int flag); - static int resetTransactionValue(int flag, int type); + static const int COMPRESSED_FLAG; + static const int MULTI_TAGS_FLAG; - static int clearCompressedFlag(int flag); + static const int TRANSACTION_NOT_TYPE; + static const int TRANSACTION_PREPARED_TYPE; + static const int TRANSACTION_COMMIT_TYPE; + static const int TRANSACTION_ROLLBACK_TYPE; - public: - static const int CompressedFlag; - static const int MultiTagsFlag; + static const int BORNHOST_V6_FLAG; + static const int STOREHOST_V6_FLAG; - static const int TransactionNotType; - static const int TransactionPreparedType; - static const int TransactionCommitType; - static const int TransactionRollbackType; + public: + static int getTransactionValue(int flag); + static int resetTransactionValue(int flag, int type); - static const int BronhostV6Flag; - static const int StorehostV6Flag; + static int clearCompressedFlag(int flag); }; } // namespace rocketmq diff --git a/src/common/OutputStream.cpp b/src/common/OutputStream.cpp deleted file mode 100644 index 4a9501330..000000000 --- a/src/common/OutputStream.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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 -#include - -#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_t 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_t value) { - uint64_t v; - char pUint64[sizeof(v)]; - WriteBigEndian(pUint64, (uint64_t)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_t asInt; - double asDouble; - } n; - n.asDouble = value; - return writeInt64BigEndian(n.asInt); -} - -int64_t OutputStream::writeFromInputStream(InputStream& source, int64_t numBytesToWrite) { - if (numBytesToWrite < 0) - numBytesToWrite = std::numeric_limits::max(); - - int64_t numWritten = 0; - - while (numBytesToWrite > 0) { - char buffer[8192]; - const int num = source.read(buffer, (int)std::min(numBytesToWrite, (int64_t)sizeof(buffer))); - - if (num <= 0) - break; - - write(buffer, (size_t)num); - - numBytesToWrite -= num; - numWritten += num; - } - - return numWritten; -} -} // namespace rocketmq diff --git a/src/common/OutputStream.h b/src/common/OutputStream.h deleted file mode 100644 index 46378a2f3..000000000 --- a/src/common/OutputStream.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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 __OUTPUT_STREAM_H__ -#define __OUTPUT_STREAM_H__ - -#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_t newPosition) = 0; - - /** Returns the stream's current position. - - @see setPosition - */ - virtual int64_t 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_t 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_t 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_t writeFromInputStream(InputStream& source, int64_t maxNumBytesToWrite); -}; - -} // namespace rocketmq - -#endif // __OUTPUT_STREAM_H__ diff --git a/src/common/SendCallbackWrap.cpp b/src/common/SendCallbackWrap.cpp index 698fe5673..e8951b354 100755 --- a/src/common/SendCallbackWrap.cpp +++ b/src/common/SendCallbackWrap.cpp @@ -167,7 +167,7 @@ void SendCallbackWrap::onExceptionImpl(ResponseFuture* responseFuture, addr, retryBrokerName); try { // new request - m_request.setOpaque(RemotingCommand::createNewRequestId()); + m_request.set_opaque(RemotingCommand::createNewRequestId()); // resend m_addr = std::move(addr); diff --git a/src/common/UtilAll.cpp b/src/common/UtilAll.cpp index 7f2dbb281..162a45e25 100644 --- a/src/common/UtilAll.cpp +++ b/src/common/UtilAll.cpp @@ -39,8 +39,8 @@ namespace rocketmq { -std::string UtilAll::s_localHostName; -std::string UtilAll::s_localIpAddress; +std::string UtilAll::sLocalHostName; +std::string UtilAll::sLocalIpAddress; bool UtilAll::try_lock_for(std::timed_mutex& mutex, long timeout) { auto now = std::chrono::steady_clock::now(); @@ -57,12 +57,12 @@ bool UtilAll::try_lock_for(std::timed_mutex& mutex, long timeout) { } } -int32_t UtilAll::HashCode(const std::string& str) { - // FIXME: don't equal to String#hashCode in Java +int32_t UtilAll::hash_code(const std::string& str) { + // FIXME: don't equal to String#hashCode in Java for non-ascii int32_t h = 0; if (!str.empty()) { for (const auto& c : str) { - h = 31 * h + c; + h = 31 * h + (uint8_t)c; } } return h; @@ -220,29 +220,29 @@ int UtilAll::Split(std::vector& ret_, const std::string& strIn, con } std::string UtilAll::getLocalHostName() { - if (s_localHostName.empty()) { + if (sLocalHostName.empty()) { char name[1024]; if (::gethostname(name, sizeof(name)) != 0) { return null; } - s_localHostName.append(name, strlen(name)); + sLocalHostName.append(name, strlen(name)); } - return s_localHostName; + return sLocalHostName; } std::string UtilAll::getLocalAddress() { - if (s_localIpAddress.empty()) { + if (sLocalIpAddress.empty()) { auto hostname = getLocalHostName(); if (!hostname.empty()) { try { - s_localIpAddress = socketAddress2String(lookupNameServers(hostname)); + sLocalIpAddress = socketAddress2String(lookupNameServers(hostname)); } catch (std::exception& e) { LOG_WARN(e.what()); - s_localIpAddress = "127.0.0.1"; + sLocalIpAddress = "127.0.0.1"; } } } - return s_localIpAddress; + return sLocalIpAddress; } uint32_t UtilAll::getIP() { @@ -372,10 +372,10 @@ int64_t UtilAll::currentTimeSeconds() { } bool UtilAll::deflate(const std::string& input, std::string& out, int level) { - return deflate(input.data(), input.length(), out, level); + return deflate(ByteArray((char*)input.data(), input.size()), out, level); } -bool UtilAll::deflate(const char* input, size_t len, std::string& out, int level) { +bool UtilAll::deflate(const ByteArray& in, std::string& out, int level) { int ret; unsigned have; z_stream strm; @@ -390,8 +390,8 @@ bool UtilAll::deflate(const char* input, size_t len, std::string& out, int level return false; } - strm.avail_in = len; - strm.next_in = (z_const Bytef*)input; + strm.avail_in = in.size(); + strm.next_in = (z_const Bytef*)in.array(); /* run deflate() on input until output buffer not full, finish compression if all of source has been read in */ @@ -413,10 +413,10 @@ bool UtilAll::deflate(const char* input, size_t len, std::string& out, int level } bool UtilAll::inflate(const std::string& input, std::string& out) { - return inflate(input.data(), input.length(), out); + return inflate(ByteArray((char*)input.data(), input.size()), out); } -bool UtilAll::inflate(const char* input, size_t len, std::string& out) { +bool UtilAll::inflate(const ByteArray& in, std::string& out) { int ret; unsigned have; z_stream strm; @@ -433,8 +433,8 @@ bool UtilAll::inflate(const char* input, size_t len, std::string& out) { return false; } - strm.avail_in = len; - strm.next_in = (z_const Bytef*)input; + strm.avail_in = in.size(); + strm.next_in = (z_const Bytef*)in.array(); /* run inflate() on input until output buffer not full */ do { diff --git a/src/common/UtilAll.h b/src/common/UtilAll.h index a919db724..51937142b 100644 --- a/src/common/UtilAll.h +++ b/src/common/UtilAll.h @@ -14,15 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __UTIL_ALL_H__ -#define __UTIL_ALL_H__ +#ifndef ROCKETMQ_COMMON_UTILALL_H_ +#define ROCKETMQ_COMMON_UTILALL_H_ -#include -#include -#include -#include +#include // std::move +#include // std::exception +#include // std::timed_mutex +#include // std::string +#include // std::vector -#include "RocketMQClient.h" +#include "ByteArray.h" namespace rocketmq { @@ -91,7 +92,7 @@ class UtilAll { template static std::string to_string(T value); - static int32_t HashCode(const std::string& str); + static int32_t hash_code(const std::string& str); static std::string bytes2string(const char* bytes, size_t len); static void string2bytes(char* dest, const std::string& src); @@ -122,9 +123,9 @@ class UtilAll { static int64_t currentTimeSeconds(); static bool deflate(const std::string& input, std::string& out, int level); - static bool deflate(const char* input, size_t len, std::string& out, int level); + static bool deflate(const ByteArray& in, std::string& out, int level); static bool inflate(const std::string& input, std::string& out); - static bool inflate(const char* input, size_t len, std::string& out); + static bool inflate(const ByteArray& in, 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 @@ -135,8 +136,8 @@ class UtilAll { static bool ReplaceFile(const std::string& from_path, const std::string& to_path); private: - static std::string s_localHostName; - static std::string s_localIpAddress; + static std::string sLocalHostName; + static std::string sLocalIpAddress; }; template @@ -154,6 +155,11 @@ inline std::string UtilAll::to_string(char* value) { return std::string(value); } +template <> +inline std::string UtilAll::to_string(ByteArrayRef value) { + return batos(std::move(value)); +} + template <> inline std::string UtilAll::to_string(std::exception_ptr eptr) { try { @@ -168,4 +174,4 @@ inline std::string UtilAll::to_string(std::exception_ptr ept } // namespace rocketmq -#endif // __UTIL_ALL_H__ +#endif // ROCKETMQ_COMMON_UTILALL_H_ diff --git a/src/common/Validators.cpp b/src/common/Validators.cpp index 4cd843e6f..9525a4144 100644 --- a/src/common/Validators.cpp +++ b/src/common/Validators.cpp @@ -103,7 +103,7 @@ void Validators::checkMessage(const Message& msg, int maxMessageSize) { THROW_MQEXCEPTION(MQClientException, "the message body is empty", MESSAGE_ILLEGAL); } - if (body.length() > (size_t)maxMessageSize) { + if (body.size() > (size_t)maxMessageSize) { std::string info = "the message body size over max value, MAX: " + UtilAll::to_string(maxMessageSize); THROW_MQEXCEPTION(MQClientException, info, MESSAGE_ILLEGAL); } diff --git a/src/common/big_endian.cpp b/src/common/big_endian.cpp deleted file mode 100644 index f2e192777..000000000 --- a/src/common/big_endian.cpp +++ /dev/null @@ -1,96 +0,0 @@ -// 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 -#include - -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 -bool BigEndianReader::Read(T* value) { - if (ptr_ + sizeof(T) > end_) - return false; - ReadBigEndian(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 -bool BigEndianWriter::Write(T value) { - if (ptr_ + sizeof(T) > end_) - return false; - WriteBigEndian(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 diff --git a/src/common/big_endian.h b/src/common/big_endian.h deleted file mode 100644 index ad591962c..000000000 --- a/src/common/big_endian.h +++ /dev/null @@ -1,101 +0,0 @@ -// 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 -#include - -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 -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(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 -inline void WriteBigEndian(char buf[], T val) { - for (size_t i = 0; i < sizeof(T); ++i) { - buf[sizeof(T) - i - 1] = static_cast(val & 0xFF); - val >>= 8; - } -} - -// Specializations to make clang happy about the (dead code) shifts above. -template <> -inline void ReadBigEndian(const char buf[], uint8_t* out) { - *out = buf[0]; -} - -template <> -inline void WriteBigEndian(char buf[], uint8_t val) { - buf[0] = static_cast(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 - 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 - bool Write(T v); - - char* ptr_; - char* end_; -}; - -} // namespace rocketmq - -#endif // BASE_BIG_ENDIAN_H_ diff --git a/src/consumer/DefaultMQPushConsumer.cpp b/src/consumer/DefaultMQPushConsumer.cpp index 4ef9b36e7..d72994883 100644 --- a/src/consumer/DefaultMQPushConsumer.cpp +++ b/src/consumer/DefaultMQPushConsumer.cpp @@ -27,7 +27,7 @@ DefaultMQPushConsumer::DefaultMQPushConsumer(const std::string& groupname) DefaultMQPushConsumer::DefaultMQPushConsumer(const std::string& groupname, RPCHookPtr rpcHook) : DefaultMQPushConsumerConfigProxy(std::make_shared()), - m_pushConsumerDelegate(nullptr) { + push_consumer_impl_(nullptr) { // set default group name if (groupname.empty()) { setGroupName(DEFAULT_CONSUMER_GROUP); @@ -35,61 +35,61 @@ DefaultMQPushConsumer::DefaultMQPushConsumer(const std::string& groupname, RPCHo setGroupName(groupname); } - m_pushConsumerDelegate = DefaultMQPushConsumerImpl::create(getRealConfig(), rpcHook); + push_consumer_impl_ = DefaultMQPushConsumerImpl::create(getRealConfig(), rpcHook); } DefaultMQPushConsumer::~DefaultMQPushConsumer() = default; void DefaultMQPushConsumer::start() { - m_pushConsumerDelegate->start(); + push_consumer_impl_->start(); } void DefaultMQPushConsumer::shutdown() { - m_pushConsumerDelegate->shutdown(); + push_consumer_impl_->shutdown(); } bool DefaultMQPushConsumer::sendMessageBack(MessageExtPtr msg, int delayLevel) { - return m_pushConsumerDelegate->sendMessageBack(msg, delayLevel); + return push_consumer_impl_->sendMessageBack(msg, delayLevel); } bool DefaultMQPushConsumer::sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) { - return m_pushConsumerDelegate->sendMessageBack(msg, delayLevel, brokerName); + return push_consumer_impl_->sendMessageBack(msg, delayLevel, brokerName); } void DefaultMQPushConsumer::fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) { - m_pushConsumerDelegate->fetchSubscribeMessageQueues(topic, mqs); + push_consumer_impl_->fetchSubscribeMessageQueues(topic, mqs); } void DefaultMQPushConsumer::registerMessageListener(MQMessageListener* messageListener) { - m_pushConsumerDelegate->registerMessageListener(messageListener); + push_consumer_impl_->registerMessageListener(messageListener); } void DefaultMQPushConsumer::registerMessageListener(MessageListenerConcurrently* messageListener) { - m_pushConsumerDelegate->registerMessageListener(messageListener); + push_consumer_impl_->registerMessageListener(messageListener); } void DefaultMQPushConsumer::registerMessageListener(MessageListenerOrderly* messageListener) { - m_pushConsumerDelegate->registerMessageListener(messageListener); + push_consumer_impl_->registerMessageListener(messageListener); } MQMessageListener* DefaultMQPushConsumer::getMessageListener() const { - return m_pushConsumerDelegate->getMessageListener(); + return push_consumer_impl_->getMessageListener(); } void DefaultMQPushConsumer::subscribe(const std::string& topic, const std::string& subExpression) { - m_pushConsumerDelegate->subscribe(topic, subExpression); + push_consumer_impl_->subscribe(topic, subExpression); } void DefaultMQPushConsumer::suspend() { - m_pushConsumerDelegate->suspend(); + push_consumer_impl_->suspend(); } void DefaultMQPushConsumer::resume() { - m_pushConsumerDelegate->resume(); + push_consumer_impl_->resume(); } void DefaultMQPushConsumer::setRPCHook(RPCHookPtr rpcHook) { - std::dynamic_pointer_cast(m_pushConsumerDelegate)->setRPCHook(rpcHook); + std::dynamic_pointer_cast(push_consumer_impl_)->setRPCHook(rpcHook); } } // namespace rocketmq diff --git a/src/consumer/PullAPIWrapper.cpp b/src/consumer/PullAPIWrapper.cpp index 4b7e936ed..221f2856b 100644 --- a/src/consumer/PullAPIWrapper.cpp +++ b/src/consumer/PullAPIWrapper.cpp @@ -16,6 +16,7 @@ */ #include "PullAPIWrapper.h" +#include "ByteBuffer.hpp" #include "MQClientAPIImpl.h" #include "MQClientInstance.h" #include "MessageDecoder.h" @@ -56,12 +57,13 @@ PullResult PullAPIWrapper::processPullResult(const MQMessageQueue& mq, auto& pullResultExt = dynamic_cast(pullResult); // update node - updatePullFromWhichNode(mq, pullResultExt.suggestWhichBrokerId); + updatePullFromWhichNode(mq, pullResultExt.suggert_which_boker_id()); std::vector msgListFilterAgain; if (FOUND == pullResultExt.pull_status()) { // decode all msg list - auto msgList = MessageDecoder::decodes(*pullResultExt.msgMemBlock); + std::unique_ptr byteBuffer(ByteBuffer::wrap(pullResultExt.message_binary())); + auto msgList = MessageDecoder::decodes(*byteBuffer); // filter msg list again if (subscriptionData != nullptr && !subscriptionData->getTagsSet().empty()) { diff --git a/src/consumer/PullRequest.cpp b/src/consumer/PullRequest.cpp index 2df57609a..2ff69d04f 100644 --- a/src/consumer/PullRequest.cpp +++ b/src/consumer/PullRequest.cpp @@ -16,6 +16,8 @@ */ #include "PullRequest.h" +#include // std::stringstream + #include "Logging.h" namespace rocketmq { @@ -64,4 +66,11 @@ void PullRequest::setProcessQueue(ProcessQueuePtr processQueue) { m_processQueue = processQueue; } +std::string PullRequest::toString() const { + std::stringstream ss; + ss << "PullRequest [consumerGroup=" << m_consumerGroup << ", messageQueue=" << m_messageQueue.toString() + << ", nextOffset=" << m_nextOffset << "]"; + return ss.str(); +} + } // namespace rocketmq diff --git a/src/consumer/PullRequest.h b/src/consumer/PullRequest.h index 7de73699c..e86c07dbb 100644 --- a/src/consumer/PullRequest.h +++ b/src/consumer/PullRequest.h @@ -49,12 +49,7 @@ class ROCKETMQCLIENT_API PullRequest { ProcessQueuePtr getProcessQueue(); void setProcessQueue(ProcessQueuePtr processQueue); - std::string toString() const { - std::stringstream ss; - ss << "PullRequest [consumerGroup=" << m_consumerGroup << ", messageQueue=" << m_messageQueue.toString() - << ", nextOffset=" << m_nextOffset << "]"; - return ss.str(); - } + std::string toString() const; private: std::string m_consumerGroup; diff --git a/src/consumer/PullResultExt.h b/src/consumer/PullResultExt.h index 420419cfc..4bbdc1d68 100644 --- a/src/consumer/PullResultExt.h +++ b/src/consumer/PullResultExt.h @@ -16,8 +16,7 @@ */ #include "PullResult.h" -#include "DataBlock.h" -#include "UtilAll.h" +#include "ByteArray.h" namespace rocketmq { @@ -38,16 +37,20 @@ class PullResultExt : public PullResult { int64_t minOffset, int64_t maxOffset, int suggestWhichBrokerId, - MemoryBlockPtr2 messageBinary) + ByteArrayRef messageBinary) : PullResult(pullStatus, nextBeginOffset, minOffset, maxOffset), - suggestWhichBrokerId(suggestWhichBrokerId), - msgMemBlock(messageBinary) {} + suggert_which_boker_id_(suggestWhichBrokerId), + message_binary_(messageBinary) {} ~PullResultExt() override = default; public: - int suggestWhichBrokerId; - MemoryBlockPtr2 msgMemBlock; + inline int suggert_which_boker_id() const { return suggert_which_boker_id_; } + inline ByteArrayRef message_binary() const { return message_binary_; } + + private: + int suggert_which_boker_id_; + ByteArrayRef message_binary_; }; } // namespace rocketmq diff --git a/src/extern/CMessage.cpp b/src/extern/CMessage.cpp index 588668d7f..b7db24536 100644 --- a/src/extern/CMessage.cpp +++ b/src/extern/CMessage.cpp @@ -64,7 +64,7 @@ int SetMessageBody(CMessage* msg, const char* body) { if (msg == NULL) { return NULL_POINTER; } - reinterpret_cast(msg)->setBody(body); + reinterpret_cast(msg)->setBody(std::string(body)); return OK; } @@ -72,7 +72,8 @@ int SetByteMessageBody(CMessage* msg, const char* body, int len) { if (msg == NULL) { return NULL_POINTER; } - reinterpret_cast(msg)->setBody(body, len); + + reinterpret_cast(msg)->setBody(std::string(body, len)); return OK; } diff --git a/src/io/Buffer.hpp b/src/io/Buffer.hpp new file mode 100644 index 000000000..a066e2c28 --- /dev/null +++ b/src/io/Buffer.hpp @@ -0,0 +1,193 @@ +/* + * 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_IO_BUFFER_HPP_ +#define ROCKETMQ_IO_BUFFER_HPP_ + +#include // std::invalid_argument, std::runtime_error + +#include "RocketMQClient.h" + +#include "UtilAll.h" + +namespace rocketmq { + +template +class Buffer { + protected: + Buffer(int32_t mark, int32_t pos, int32_t lim, int32_t cap) throw(std::invalid_argument) { + if (cap < 0) { + throw std::invalid_argument("Negative capacity: " + UtilAll::to_string(cap)); + } + capacity_ = cap; + limit(lim); + position(pos); + if (mark >= 0) { + if (mark > pos) { + throw std::invalid_argument("mark > position: (" + UtilAll::to_string(mark) + " > " + UtilAll::to_string(pos) + + ")"); + } + mark_ = mark; + } + } + + public: + Buffer& position(int new_position) throw(std::invalid_argument) { + if ((new_position > limit_) || (new_position < 0)) { + throw std::invalid_argument(""); + } + position_ = new_position; + if (mark_ > position_) { + mark_ = -1; + } + return *this; + } + + Buffer& limit(int new_limit) throw(std::invalid_argument) { + if ((new_limit > capacity_) || (new_limit < 0)) { + throw std::invalid_argument(""); + } + limit_ = new_limit; + if (position_ > limit_) { + position_ = limit_; + } + if (mark_ > limit_) { + mark_ = -1; + } + return *this; + } + + Buffer& mark() { + mark_ = position_; + return *this; + } + + Buffer& reset() { + int m = mark_; + if (m < 0) { + throw std::runtime_error("InvalidMarkException"); + } + position_ = m; + return *this; + } + + Buffer& clear() { + position_ = 0; + limit_ = capacity_; + mark_ = -1; + return *this; + } + + Buffer& flip() { + limit_ = position_; + position_ = 0; + mark_ = -1; + return *this; + } + + Buffer& rewind() { + position_ = 0; + mark_ = -1; + return *this; + } + + inline int32_t remaining() const { return limit_ - position_; } + inline bool hasRemaining() const { return position_ < limit_; } + + virtual bool isReadOnly() = 0; + virtual bool hasArray() = 0; + virtual A* array() = 0; + virtual int32_t arrayOffset() = 0; + + protected: + int32_t nextGetIndex() { + if (position_ >= limit_) { + throw std::runtime_error("BufferUnderflowException"); + } + return position_++; + } + + int32_t nextGetIndex(int32_t nb) { + if (limit_ - position_ < nb) { + throw std::runtime_error("BufferUnderflowException"); + } + int32_t p = position_; + position_ += nb; + return p; + } + + int32_t nextPutIndex() { + if (position_ >= limit_) { + throw std::runtime_error("BufferOverflowException"); + } + return position_++; + } + + int32_t nextPutIndex(int32_t nb) { + if (limit_ - position_ < nb) { + throw std::runtime_error("BufferOverflowException"); + } + int32_t p = position_; + position_ += nb; + return p; + } + + int32_t checkIndex(int32_t i) const { + if ((i < 0) || (i >= limit_)) { + throw std::runtime_error("IndexOutOfBoundsException"); + } + return i; + } + + int32_t checkIndex(int32_t i, int32_t nb) const { + if ((i < 0) || (nb > limit_ - i)) { + throw std::runtime_error("IndexOutOfBoundsException"); + } + return i; + } + + void truncate() { + mark_ = -1; + position_ = 0; + limit_ = 0; + capacity_ = 0; + } + + void discardMark() { mark_ = -1; } + + static void checkBounds(int32_t off, int32_t len, int32_t size) { + if ((off | len | (off + len) | (size - (off + len))) < 0) { + throw std::runtime_error("IndexOutOfBoundsException"); + } + } + + public: + inline int32_t mark_value() const { return mark_; } + inline int32_t position() const { return position_; } + inline int32_t limit() const { return limit_; } + inline int32_t capacity() const { return capacity_; } + + private: + // Invariants: mark <= position <= limit <= capacity + int32_t mark_ = -1; + int32_t position_ = 0; + int32_t limit_; + int32_t capacity_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_IO_BUFFER_HPP_ diff --git a/src/io/ByteArray.cpp b/src/io/ByteArray.cpp new file mode 100644 index 000000000..16568e028 --- /dev/null +++ b/src/io/ByteArray.cpp @@ -0,0 +1,82 @@ +/* + * 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 "ByteArray.h" + +#include // std::memcpy + +#include // std::move +#include // +#include // std::string + +namespace rocketmq { + +class ByteArrayView : public ByteArray { + public: + ByteArrayView(ByteArrayRef ba, size_t offset, size_t size) : ByteArray(ba->array() + offset, size), origin_(ba) {} + ByteArrayView(ByteArrayRef ba, size_t offset) : ByteArrayView(ba, offset, ba->size() - offset) {} + + ByteArrayRef origin() { return origin_; } + + private: + ByteArrayRef origin_; +}; + +ByteArrayRef slice(ByteArrayRef ba, size_t offset) { + return slice(ba, offset, ba->size() - offset); +} + +ByteArrayRef slice(ByteArrayRef ba, size_t offset, size_t size) { + if (offset < 0 || size < 0 || ba->size() < offset + size) { + std::invalid_argument(""); + } + return std::make_shared(ba, offset, size); +} + +class StringBaseByteArray : public ByteArray { + public: + StringBaseByteArray(const std::string& str) : ByteArray(nullptr, str.size()), string_(str) { + // Since C++11, The returned array is null-terminated, that is, data() and c_str() perform the same function. + // If empty() returns true, the pointer points to a single null character. + array_ = (char*)string_.data(); + } + StringBaseByteArray(std::string&& str) : ByteArray(nullptr, str.size()), string_(std::move(str)) { + array_ = (char*)string_.data(); + } + + std::string sting() { return string_; } + + private: + std::string string_; +}; + +ByteArrayRef stoba(const std::string& str) { + return std::make_shared(str); +} + +ByteArrayRef stoba(std::string&& str) { + return std::make_shared(std::move(str)); +} + +ByteArrayRef catoba(const char* str, size_t len) { + return stoba(std::string(str, len)); +} + +std::string batos(ByteArrayRef ba) { + return std::string(ba->array(), ba->size()); +} + +} // namespace rocketmq diff --git a/src/io/ByteBuffer.cpp b/src/io/ByteBuffer.cpp new file mode 100644 index 000000000..f12bd7258 --- /dev/null +++ b/src/io/ByteBuffer.cpp @@ -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. + */ +#include "ByteBuffer.hpp" + +#include // std::move + +#include "DefaultByteBuffer.hpp" + +namespace rocketmq { + +ByteBuffer* ByteBuffer::allocate(int32_t capacity) { + if (capacity < 0) { + throw std::invalid_argument(""); + } + return new DefaultByteBuffer(capacity, capacity); +} + +ByteBuffer* ByteBuffer::wrap(ByteArrayRef array, int32_t offset, int32_t length) { + try { + return new DefaultByteBuffer(std::move(array), offset, length); + } catch (const std::exception& x) { + throw std::runtime_error("IndexOutOfBoundsException"); + } +} + +} // namespace rocketmq diff --git a/src/io/ByteBuffer.hpp b/src/io/ByteBuffer.hpp new file mode 100644 index 000000000..5a302500b --- /dev/null +++ b/src/io/ByteBuffer.hpp @@ -0,0 +1,184 @@ +/* + * 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_IO_BYTEBUFFER_HPP_ +#define ROCKETMQ_IO_BYTEBUFFER_HPP_ + +#include // std::stringstream + +#include "ByteArray.h" +#include "Buffer.hpp" +#include "ByteOrder.h" + +namespace rocketmq { + +class ByteBuffer : public Buffer { + public: + static ByteBuffer* allocate(int32_t capacity); + + static ByteBuffer* wrap(ByteArrayRef array, int32_t offset, int32_t length); + static ByteBuffer* wrap(ByteArrayRef array) { return wrap(array, 0, array->size()); } + + protected: + ByteBuffer(int32_t mark, int32_t pos, int32_t lim, int32_t cap, ByteArrayRef byte_array, int32_t offset) + : Buffer(mark, pos, lim, cap), + byte_array_(std::move(byte_array)), + offset_(offset), + is_read_only_(false), + big_endian_(true) {} + + ByteBuffer(int32_t mark, int32_t pos, int32_t lim, int32_t cap) : ByteBuffer(mark, pos, lim, cap, nullptr, 0) {} + + public: + virtual ~ByteBuffer() = default; + + public: + virtual ByteBuffer* slice() = 0; + virtual ByteBuffer* duplicate() = 0; + virtual ByteBuffer* asReadOnlyBuffer() = 0; + + // get/put routine + // ====================== + + virtual char get() = 0; + virtual ByteBuffer& put(char b) = 0; + + virtual char get(int32_t index) const = 0; + virtual ByteBuffer& put(int32_t index, char b) = 0; + + virtual ByteBuffer& get(ByteArray& dst, int32_t offset, int32_t length) { + checkBounds(offset, length, dst.size()); + if (length > remaining()) { + throw std::runtime_error("BufferUnderflowException"); + } + int32_t end = offset + length; + for (int32_t i = offset; i < end; i++) { + dst[i] = get(); + } + return *this; + } + + ByteBuffer& get(ByteArray& dst) { return get(dst, 0, dst.size()); } + + virtual ByteBuffer& put(ByteBuffer& src) { + if (&src == this) { + throw std::invalid_argument(""); + } + if (isReadOnly()) { + throw std::runtime_error("ReadOnlyBufferException"); + } + int32_t n = src.remaining(); + if (n > remaining()) { + throw std::runtime_error("BufferOverflowException"); + } + for (int32_t i = 0; i < n; i++) { + put(src.get()); + } + return *this; + } + + virtual ByteBuffer& put(const ByteArray& src, int32_t offset, int32_t length) { + checkBounds(offset, length, src.size()); + if (length > remaining()) { + throw std::runtime_error("BufferOverflowException"); + } + int32_t end = offset + length; + for (int32_t i = offset; i < end; i++) { + put(src[i]); + } + return *this; + } + + ByteBuffer& put(const ByteArray& src) { return put(src, 0, src.size()); } + + public: + bool hasArray() override final { return (byte_array_ != nullptr) && !is_read_only_; } + + char* array() override final { + if (byte_array_ == nullptr) { + throw std::runtime_error("UnsupportedOperationException"); + } + if (is_read_only_) { + throw std::runtime_error("ReadOnlyBufferException"); + } + return byte_array_->array(); + } + + int32_t arrayOffset() override final { + if (byte_array_ == nullptr) { + throw std::runtime_error("UnsupportedOperationException"); + } + if (is_read_only_) { + throw std::runtime_error("ReadOnlyBufferException"); + } + return offset_; + } + + virtual ByteBuffer& compact() = 0; + + virtual std::string toString() { + std::stringstream ss; + ss << "ByteBuffer" + << "[pos=" << position() << " lim=" << limit() << " cap=" << capacity() << "]"; + return ss.str(); + } + + inline ByteOrder order() const { return big_endian_ ? ByteOrder::BO_BIG_ENDIAN : ByteOrder::BO_LITTLE_ENDIAN; } + + inline ByteBuffer& order(ByteOrder bo) { + big_endian_ = (bo == ByteOrder::BO_BIG_ENDIAN); + return *this; + } + + inline ByteArrayRef byte_array() { return byte_array_; } + + public: + virtual int16_t getShort() = 0; + virtual ByteBuffer& putShort(int16_t value) = 0; + virtual int16_t getShort(int32_t index) = 0; + virtual ByteBuffer& putShort(int32_t index, int16_t value) = 0; + + virtual int32_t getInt() = 0; + virtual ByteBuffer& putInt(int32_t value) = 0; + virtual int32_t getInt(int32_t index) = 0; + virtual ByteBuffer& putInt(int32_t index, int32_t value) = 0; + + virtual int64_t getLong() = 0; + virtual ByteBuffer& putLong(int64_t value) = 0; + virtual int64_t getLong(int32_t index) = 0; + virtual ByteBuffer& putLong(int32_t index, int64_t value) = 0; + + virtual float getFloat() = 0; + virtual ByteBuffer& putFloat(float value) = 0; + virtual float getFloat(int32_t index) = 0; + virtual ByteBuffer& putFloat(int32_t index, float value) = 0; + + virtual double getDouble() = 0; + virtual ByteBuffer& putDouble(double value) = 0; + virtual double getDouble(int32_t index) = 0; + virtual ByteBuffer& putDouble(int32_t index, double value) = 0; + + protected: + ByteArrayRef byte_array_; + int32_t offset_; + bool is_read_only_; + + bool big_endian_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_IO_BYTEBUFFER_HPP_ \ No newline at end of file diff --git a/src/io/DefaultByteBuffer.hpp b/src/io/DefaultByteBuffer.hpp new file mode 100644 index 000000000..73a40397b --- /dev/null +++ b/src/io/DefaultByteBuffer.hpp @@ -0,0 +1,222 @@ +/* + * 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_IO_DEFAULTBYTEBUFFER_HPP_ +#define ROCKETMQ_IO_DEFAULTBYTEBUFFER_HPP_ + +#include // std::memcpy + +#include // std::move +#include // std::type_index + +#include "ByteBuffer.hpp" + +namespace rocketmq { + +class DefaultByteBuffer : public ByteBuffer { + protected: + friend class ByteBuffer; + + DefaultByteBuffer(int32_t cap, int32_t lim) : ByteBuffer(-1, 0, lim, cap, std::make_shared(cap), 0) {} + + DefaultByteBuffer(ByteArrayRef buf, int32_t off, int32_t len) + : ByteBuffer(-1, off, off + len, buf->size(), std::move(buf), 0) {} + + DefaultByteBuffer(ByteArrayRef buf, int32_t mark, int32_t pos, int32_t lim, int32_t cap, int32_t off) + : ByteBuffer(mark, pos, lim, cap, std::move(buf), off) {} + + public: + ByteBuffer* slice() override { + return new DefaultByteBuffer(byte_array_, -1, 0, remaining(), remaining(), position() + offset_); + } + + ByteBuffer* duplicate() override { + return new DefaultByteBuffer(byte_array_, mark_value(), position(), limit(), capacity(), offset_); + } + + ByteBuffer* asReadOnlyBuffer() override { + // return new HeapByteBufferR(byte_array_, mark_value(), position(), limit(), capacity(), offset_); + return nullptr; + } + + char get() override { return (*byte_array_)[ix(nextGetIndex())]; } + char get(int i) const override { return (*byte_array_)[ix(checkIndex(i))]; } + + ByteBuffer& get(ByteArray& dst, int32_t offset, int length) override { + checkBounds(offset, length, dst.size()); + if (length > remaining()) { + throw std::runtime_error("BufferUnderflowException"); + } + std::memcpy(dst.array() + offset, byte_array_->array() + ix(position()), length); + position(position() + length); + return *this; + } + + ByteBuffer& put(char x) override { + (*byte_array_)[ix(nextPutIndex())] = x; + return *this; + } + + ByteBuffer& put(int32_t i, char x) override { + (*byte_array_)[ix(checkIndex(i))] = x; + return *this; + } + + ByteBuffer& put(const ByteArray& src, int offset, int length) override { + checkBounds(offset, length, src.size()); + if (length > remaining()) { + throw std::runtime_error("BufferOverflowException"); + } + std::memcpy(byte_array_->array() + ix(position()), src.array() + offset, length); + position(position() + length); + return *this; + } + + ByteBuffer& put(ByteBuffer& src) override { + if (std::type_index(typeid(src)) == std::type_index(typeid(DefaultByteBuffer))) { + if (&src == this) { + throw std::invalid_argument(""); + } + DefaultByteBuffer& sb = dynamic_cast(src); + int32_t n = sb.remaining(); + if (n > remaining()) { + throw std::runtime_error("BufferOverflowException"); + } + std::memcpy(byte_array_->array() + ix(position()), sb.byte_array_->array() + sb.ix(sb.position()), n); + sb.position(sb.position() + n); + position(position() + n); + } else { + ByteBuffer::put(src); + } + return *this; + } + + public: + bool isReadOnly() override { return false; } + + ByteBuffer& compact() override { + std::memcpy(byte_array_->array() + ix(0), byte_array_->array() + ix(position()), remaining()); + position(remaining()); + limit(capacity()); + discardMark(); + return *this; + } + + public: + int16_t getShort() override { + return ByteOrderUtil::Read(byte_array_->array() + ix(nextGetIndex(2)), big_endian_); + } + + int16_t getShort(int32_t i) override { + return ByteOrderUtil::Read(byte_array_->array() + ix(checkIndex(i, 2)), big_endian_); + } + + ByteBuffer& putShort(int16_t x) override { + ByteOrderUtil::Write(byte_array_->array() + ix(nextPutIndex(2)), x, big_endian_); + return *this; + } + + ByteBuffer& putShort(int32_t i, int16_t x) override { + ByteOrderUtil::Write(byte_array_->array() + ix(checkIndex(i, 2)), x, big_endian_); + return *this; + } + + int32_t getInt() override { + return ByteOrderUtil::Read(byte_array_->array() + ix(nextGetIndex(4)), big_endian_); + } + int32_t getInt(int32_t i) override { + return ByteOrderUtil::Read(byte_array_->array() + ix(checkIndex(i, 4)), big_endian_); + } + + ByteBuffer& putInt(int32_t x) override { + ByteOrderUtil::Write(byte_array_->array() + ix(nextPutIndex(4)), x, big_endian_); + return *this; + } + + ByteBuffer& putInt(int32_t i, int32_t x) override { + ByteOrderUtil::Write(byte_array_->array() + ix(checkIndex(i, 4)), x, big_endian_); + return *this; + } + + int64_t getLong() override { + return ByteOrderUtil::Read(byte_array_->array() + ix(nextGetIndex(8)), big_endian_); + } + + int64_t getLong(int32_t i) override { + return ByteOrderUtil::Read(byte_array_->array() + ix(checkIndex(i, 8)), big_endian_); + } + + ByteBuffer& putLong(int64_t x) override { + ByteOrderUtil::Write(byte_array_->array() + ix(nextPutIndex(8)), x, big_endian_); + return *this; + } + + ByteBuffer& putLong(int32_t i, int64_t x) override { + ByteOrderUtil::Write(byte_array_->array() + ix(checkIndex(i, 8)), x, big_endian_); + return *this; + } + + float getFloat() override { + return ByteOrderUtil::ReinterpretRawBits( + ByteOrderUtil::Read(byte_array_->array() + ix(nextGetIndex(4)), big_endian_)); + } + + float getFloat(int32_t i) override { + return ByteOrderUtil::ReinterpretRawBits( + ByteOrderUtil::Read(byte_array_->array() + ix(checkIndex(i, 4)), big_endian_)); + } + + ByteBuffer& putFloat(float x) override { + ByteOrderUtil::Write(byte_array_->array() + ix(nextPutIndex(4)), + ByteOrderUtil::ReinterpretRawBits(x), big_endian_); + return *this; + } + + ByteBuffer& putFloat(int32_t i, float x) override { + ByteOrderUtil::Write(byte_array_->array() + ix(checkIndex(i, 4)), + ByteOrderUtil::ReinterpretRawBits(x), big_endian_); + return *this; + } + + double getDouble() override { + return ByteOrderUtil::ReinterpretRawBits( + ByteOrderUtil::Read(byte_array_->array() + ix(nextGetIndex(8)), big_endian_)); + } + + double getDouble(int32_t i) override { + return ByteOrderUtil::ReinterpretRawBits( + ByteOrderUtil::Read(byte_array_->array() + ix(checkIndex(i, 8)), big_endian_)); + } + + ByteBuffer& putDouble(double x) override { + ByteOrderUtil::Write(byte_array_->array() + ix(nextPutIndex(8)), + ByteOrderUtil::ReinterpretRawBits(x), big_endian_); + return *this; + } + + ByteBuffer& putDouble(int32_t i, double x) override { + ByteOrderUtil::Write(byte_array_->array() + ix(checkIndex(i, 8)), + ByteOrderUtil::ReinterpretRawBits(x), big_endian_); + return *this; + } + + protected: + inline int32_t ix(int32_t i) const { return i + offset_; } +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_IO_DEFAULTBYTEBUFFER_HPP_ diff --git a/src/message/MQMessage.cpp b/src/message/MQMessage.cpp index 71f8a3019..0e46e9dfb 100644 --- a/src/message/MQMessage.cpp +++ b/src/message/MQMessage.cpp @@ -23,6 +23,10 @@ namespace rocketmq { +bool operator==(std::nullptr_t, const MQMessage& message) noexcept { + return nullptr == message.message_impl_; +} + MQMessage::MQMessage() : MQMessage(null, null) {} MQMessage::MQMessage(const std::string& topic, const std::string& body) : MQMessage(topic, null, body) {} @@ -118,10 +122,6 @@ const std::string& MQMessage::getBody() const { return message_impl_->getBody(); } -void MQMessage::setBody(const char* body, int len) { - message_impl_->setBody(body, len); -} - void MQMessage::setBody(const std::string& body) { message_impl_->setBody(body); } diff --git a/src/message/MQMessageQueue.cpp b/src/message/MQMessageQueue.cpp index 50ab3f06e..c9d913c2a 100644 --- a/src/message/MQMessageQueue.cpp +++ b/src/message/MQMessageQueue.cpp @@ -16,90 +16,56 @@ */ #include "MQMessageQueue.h" +#include // std::stringstream + namespace rocketmq { -MQMessageQueue::MQMessageQueue() { - m_queueId = -1; // invalide mq - m_topic.clear(); - m_brokerName.clear(); -} +MQMessageQueue::MQMessageQueue() + : queue_id_(-1) // invalide mq +{} MQMessageQueue::MQMessageQueue(const std::string& topic, const std::string& brokerName, int queueId) - : m_topic(topic), m_brokerName(brokerName), m_queueId(queueId) {} + : topic_(topic), broker_name_(brokerName), queue_id_(queueId) {} MQMessageQueue::MQMessageQueue(const MQMessageQueue& other) - : m_topic(other.m_topic), m_brokerName(other.m_brokerName), m_queueId(other.m_queueId) {} + : MQMessageQueue(other.topic_, other.broker_name_, other.queue_id_) {} MQMessageQueue& MQMessageQueue::operator=(const MQMessageQueue& other) { if (this != &other) { - m_brokerName = other.m_brokerName; - m_topic = other.m_topic; - m_queueId = other.m_queueId; + broker_name_ = other.broker_name_; + topic_ = other.topic_; + queue_id_ = other.queue_id_; } return *this; } -const std::string& MQMessageQueue::getTopic() const { - return m_topic; -} - -void MQMessageQueue::setTopic(const std::string& topic) { - m_topic = topic; -} - -const std::string& MQMessageQueue::getBrokerName() const { - return m_brokerName; -} - -// NOTE: only use to initial the mq -void MQMessageQueue::setBrokerName(const std::string& brokerName) { - m_brokerName = brokerName; -} - -int MQMessageQueue::getQueueId() const { - return m_queueId; -} - -void MQMessageQueue::setQueueId(int queueId) { - m_queueId = queueId; +bool MQMessageQueue::operator==(const MQMessageQueue& other) const { + return this == &other || + (queue_id_ == other.queue_id_ && broker_name_ == other.broker_name_ && topic_ == other.topic_); } -bool MQMessageQueue::operator==(const MQMessageQueue& mq) const { - if (this == &mq) { - return true; - } - - if (m_brokerName != mq.m_brokerName) { - return false; - } - - if (m_queueId != mq.m_queueId) { - return false; - } - - if (m_topic != mq.m_topic) { - return false; - } - - return true; +bool MQMessageQueue::operator<(const MQMessageQueue& mq) const { + return compareTo(mq) < 0; } int MQMessageQueue::compareTo(const MQMessageQueue& mq) const { - int result = m_topic.compare(mq.m_topic); + int result = topic_.compare(mq.topic_); if (result != 0) { return result; } - result = m_brokerName.compare(mq.m_brokerName); + result = broker_name_.compare(mq.broker_name_); if (result != 0) { return result; } - return m_queueId - mq.m_queueId; + return queue_id_ - mq.queue_id_; } -bool MQMessageQueue::operator<(const MQMessageQueue& mq) const { - return compareTo(mq) < 0; +std::string MQMessageQueue::toString() const { + std::stringstream ss; + ss << "MessageQueue [topic=" << topic_ << ", brokerName=" << broker_name_ << ", queueId=" << queue_id_ << "]"; + return ss.str(); } } // namespace rocketmq diff --git a/src/message/MessageClientIDSetter.cpp b/src/message/MessageClientIDSetter.cpp index c007638d5..450273ec5 100644 --- a/src/message/MessageClientIDSetter.cpp +++ b/src/message/MessageClientIDSetter.cpp @@ -33,9 +33,9 @@ namespace rocketmq { MessageClientIDSetter::MessageClientIDSetter() { std::srand((uint32_t)std::time(NULL)); - uint32_t pid = ByteOrder::swapIfLittleEndian(static_cast(UtilAll::getProcessId())); - uint32_t ip = ByteOrder::swapIfLittleEndian(UtilAll::getIP()); - uint32_t random_num = ByteOrder::swapIfLittleEndian(static_cast(std::rand())); + uint32_t pid = ByteOrderUtil::NorminalBigEndian(static_cast(UtilAll::getProcessId())); + uint32_t ip = ByteOrderUtil::NorminalBigEndian(UtilAll::getIP()); + uint32_t random_num = ByteOrderUtil::NorminalBigEndian(static_cast(std::rand())); char bin_buf[10]; std::memcpy(bin_buf + 2, &pid, 4); @@ -90,8 +90,8 @@ std::string MessageClientIDSetter::createUniqueID() { current = UtilAll::currentTimeMillis(); } - uint32_t period = ByteOrder::swapIfLittleEndian(static_cast(current - mStartTime)); - uint16_t seqid = ByteOrder::swapIfLittleEndian(mCounter++); + uint32_t period = ByteOrderUtil::NorminalBigEndian(static_cast(current - mStartTime)); + uint16_t seqid = ByteOrderUtil::NorminalBigEndian(mCounter++); char bin_buf[6]; std::memcpy(bin_buf, &period, 4); diff --git a/src/message/MessageDecoder.cpp b/src/message/MessageDecoder.cpp index e7e4e596d..d0ac623ae 100644 --- a/src/message/MessageDecoder.cpp +++ b/src/message/MessageDecoder.cpp @@ -16,19 +16,15 @@ */ #include "MessageDecoder.h" -#include // std::memcpy - #include // std::move #include // std::stringstream #ifndef WIN32 -#include // htons, htonl #include // struct sockaddr, sockaddr_in, sockaddr_in6 #endif #include "ByteOrder.h" #include "Logging.h" -#include "MemoryOutputStream.h" #include "MessageExtImpl.h" #include "MessageAccessor.h" #include "MessageSysFlag.h" @@ -47,160 +43,155 @@ int MessageDecoder::MessagePhysicOffsetPostion = 28; int MessageDecoder::MessageStoreTimestampPostion = 56; std::string MessageDecoder::createMessageId(const struct sockaddr* sa, int64_t offset) { - MemoryOutputStream mos(sa->sa_family == AF_INET ? 16 : 28); + int msgIDLength = sa->sa_family == AF_INET ? 16 : 28; + std::unique_ptr byteBuffer(ByteBuffer::allocate(msgIDLength)); if (sa->sa_family == AF_INET) { - const struct sockaddr_in* sin = (struct sockaddr_in*)sa; - mos.write(&sin->sin_addr.s_addr, 4); - mos.writeRepeatedByte(0, 2); - mos.write(&sin->sin_port, 2); - mos.writeInt64BigEndian(offset); + struct sockaddr_in* sin = (struct sockaddr_in*)sa; + byteBuffer->put(ByteArray((char*)&sin->sin_addr, 4)); + byteBuffer->putInt(ByteOrderUtil::NorminalBigEndian(sin->sin_port)); } else { - const struct sockaddr_in6* sin6 = (struct sockaddr_in6*)sa; - mos.write(&sin6->sin6_addr, 16); - mos.writeRepeatedByte(0, 2); - mos.write(&sin6->sin6_port, 2); - mos.writeInt64BigEndian(offset); + struct sockaddr_in6* sin6 = (struct sockaddr_in6*)sa; + byteBuffer->put(ByteArray((char*)&sin6->sin6_addr, 16)); + byteBuffer->putInt(ByteOrderUtil::NorminalBigEndian(sin6->sin6_port)); } - - const char* bytes = static_cast(mos.getData()); - int len = mos.getDataSize(); - - return UtilAll::bytes2string(bytes, len); + byteBuffer->putLong(offset); + byteBuffer->flip(); + return UtilAll::bytes2string(byteBuffer->array(), msgIDLength); } MessageId MessageDecoder::decodeMessageId(const std::string& msgId) { size_t ip_length = msgId.length() == 32 ? 4 * 2 : 16 * 2; + ByteArray byteArray(ip_length / 2); std::string ip = msgId.substr(0, ip_length); + UtilAll::string2bytes(byteArray.array(), ip); + std::string port = msgId.substr(ip_length, 8); - std::string offset = msgId.substr(ip_length + 8); + // uint32_t portInt = ByteOrderUtil::NorminalBigEndian(std::stoul(port, nullptr, 16)); + uint32_t portInt = std::stoul(port, nullptr, 16); + + auto* sin = ipPort2SocketAddress(byteArray, portInt); - uint16_t portInt = (uint16_t)std::stoul(port, nullptr, 16); + std::string offset = msgId.substr(ip_length + 8); + // uint64_t offsetInt = ByteOrderUtil::NorminalBigEndian(std::stoull(offset, nullptr, 16)); uint64_t offsetInt = std::stoull(offset, nullptr, 16); - if (ip_length == 32) { - int32_t ipInt = std::stoul(ip, nullptr, 16); - struct sockaddr_in sin; - sin.sin_family = AF_INET; - sin.sin_port = htons(portInt); - sin.sin_addr.s_addr = htonl(ipInt); - return MessageId((struct sockaddr*)&sin, offsetInt); - } else { - struct sockaddr_in6 sin6; - sin6.sin6_family = AF_INET6; - sin6.sin6_port = htons(portInt); - UtilAll::string2bytes((char*)&sin6.sin6_addr, ip); - return MessageId((struct sockaddr*)&sin6, offsetInt); - } + return MessageId(sin, offsetInt); } -MessageExtPtr MessageDecoder::clientDecode(MemoryInputStream& byteBuffer, bool readBody) { +MessageExtPtr MessageDecoder::clientDecode(ByteBuffer& byteBuffer, bool readBody) { return decode(byteBuffer, readBody, true, true); } -MessageExtPtr MessageDecoder::decode(MemoryInputStream& byteBuffer, bool readBody) { +MessageExtPtr MessageDecoder::decode(ByteBuffer& byteBuffer) { + return decode(byteBuffer, true); +} + +MessageExtPtr MessageDecoder::decode(ByteBuffer& byteBuffer, bool readBody) { return decode(byteBuffer, readBody, true, false); } -MessageExtPtr MessageDecoder::decode(MemoryInputStream& byteBuffer, bool readBody, bool deCompressBody, bool isClient) { +MessageExtPtr MessageDecoder::decode(ByteBuffer& byteBuffer, bool readBody, bool deCompressBody, bool isClient) { auto msgExt = isClient ? std::make_shared() : std::make_shared(); // 1 TOTALSIZE - int32_t storeSize = byteBuffer.readIntBigEndian(); + int32_t storeSize = byteBuffer.getInt(); msgExt->setStoreSize(storeSize); // 2 MAGICCODE sizeof(int) - byteBuffer.skipNextBytes(sizeof(int)); + byteBuffer.getInt(); // 3 BODYCRC - int32_t bodyCRC = byteBuffer.readIntBigEndian(); + int32_t bodyCRC = byteBuffer.getInt(); msgExt->setBodyCRC(bodyCRC); // 4 QUEUEID - int32_t queueId = byteBuffer.readIntBigEndian(); + int32_t queueId = byteBuffer.getInt(); msgExt->setQueueId(queueId); // 5 FLAG - int32_t flag = byteBuffer.readIntBigEndian(); + int32_t flag = byteBuffer.getInt(); msgExt->setFlag(flag); // 6 QUEUEOFFSET - int64_t queueOffset = byteBuffer.readInt64BigEndian(); + int64_t queueOffset = byteBuffer.getLong(); msgExt->setQueueOffset(queueOffset); // 7 PHYSICALOFFSET - int64_t physicOffset = byteBuffer.readInt64BigEndian(); + int64_t physicOffset = byteBuffer.getLong(); msgExt->setCommitLogOffset(physicOffset); // 8 SYSFLAG - int32_t sysFlag = byteBuffer.readIntBigEndian(); + int32_t sysFlag = byteBuffer.getInt(); msgExt->setSysFlag(sysFlag); // 9 BORNTIMESTAMP - int64_t bornTimeStamp = byteBuffer.readInt64BigEndian(); + int64_t bornTimeStamp = byteBuffer.getLong(); msgExt->setBornTimestamp(bornTimeStamp); // 10 BORNHOST - int32_t bornHost = byteBuffer.readIntBigEndian(); - int32_t bornPort = byteBuffer.readIntBigEndian(); + int bornhostIPLength = (sysFlag & MessageSysFlag::BORNHOST_V6_FLAG) == 0 ? 4 : 16; + ByteArray bornHost(bornhostIPLength); + byteBuffer.get(bornHost, 0, bornhostIPLength); + int32_t bornPort = byteBuffer.getInt(); msgExt->setBornHost(ipPort2SocketAddress(bornHost, bornPort)); // 11 STORETIMESTAMP - int64_t storeTimestamp = byteBuffer.readInt64BigEndian(); + int64_t storeTimestamp = byteBuffer.getLong(); msgExt->setStoreTimestamp(storeTimestamp); // 12 STOREHOST - int32_t storeHost = byteBuffer.readIntBigEndian(); - int32_t storePort = byteBuffer.readIntBigEndian(); + int storehostIPLength = (sysFlag & MessageSysFlag::STOREHOST_V6_FLAG) == 0 ? 4 : 16; + ByteArray storeHost(bornhostIPLength); + byteBuffer.get(storeHost, 0, storehostIPLength); + int32_t storePort = byteBuffer.getInt(); msgExt->setStoreHost(ipPort2SocketAddress(storeHost, storePort)); // 13 RECONSUMETIMES - int32_t reconsumeTimes = byteBuffer.readIntBigEndian(); + int32_t reconsumeTimes = byteBuffer.getInt(); msgExt->setReconsumeTimes(reconsumeTimes); // 14 Prepared Transaction Offset - int64_t preparedTransactionOffset = byteBuffer.readInt64BigEndian(); + int64_t preparedTransactionOffset = byteBuffer.getLong(); msgExt->setPreparedTransactionOffset(preparedTransactionOffset); // 15 BODY int uncompress_failed = false; - int32_t bodyLen = byteBuffer.readIntBigEndian(); + int32_t bodyLen = byteBuffer.getInt(); if (bodyLen > 0) { if (readBody) { - MemoryPool block; - byteBuffer.readIntoMemoryBlock(block, bodyLen); + ByteArray body(byteBuffer.array() + byteBuffer.arrayOffset() + byteBuffer.position(), bodyLen); + byteBuffer.position(byteBuffer.position() + bodyLen); // decompress body - if (deCompressBody && (sysFlag & MessageSysFlag::CompressedFlag) == MessageSysFlag::CompressedFlag) { - std::string outbody; - if (UtilAll::inflate(block.getData(), block.getSize(), outbody)) { - msgExt->setBody(std::move(outbody)); + if (deCompressBody && (sysFlag & MessageSysFlag::COMPRESSED_FLAG) == MessageSysFlag::COMPRESSED_FLAG) { + std::string origin_body; + if (UtilAll::inflate(body, origin_body)) { + msgExt->setBody(std::move(origin_body)); } else { uncompress_failed = true; } } else { - msgExt->setBody(block.getData(), block.getSize()); + // c_str safety + msgExt->setBody(std::string(body.array(), body.size())); } } else { - byteBuffer.skipNextBytes(bodyLen); + byteBuffer.position(byteBuffer.position() + bodyLen); } } // 16 TOPIC - int8_t topicLen = byteBuffer.readByte(); - MemoryPool block; - byteBuffer.readIntoMemoryBlock(block, topicLen); - const char* const pTopic = static_cast(block.getData()); - topicLen = block.getSize(); - msgExt->setTopic(pTopic, topicLen); + int8_t topicLen = byteBuffer.get(); + ByteArray topic(topicLen); + byteBuffer.get(topic); + msgExt->setTopic(topic.array(), topic.size()); // 17 properties - int16_t propertiesLen = byteBuffer.readShortBigEndian(); + int16_t propertiesLen = byteBuffer.getShort(); if (propertiesLen > 0) { - MemoryPool block; - byteBuffer.readIntoMemoryBlock(block, propertiesLen); - std::string propertiesString(block.getData(), block.getSize()); - + ByteArray properties(propertiesLen); + byteBuffer.get(properties); + std::string propertiesString(properties.array(), properties.size()); std::map propertiesMap = string2messageProperties(propertiesString); MessageAccessor::setProperties(*msgExt, std::move(propertiesMap)); } @@ -216,28 +207,18 @@ MessageExtPtr MessageDecoder::decode(MemoryInputStream& byteBuffer, bool readBod return msgExt; } -MessageExtPtr MessageDecoder::decode(MemoryBlock& mem) { - return decode(mem, true); -} - -MessageExtPtr MessageDecoder::decode(MemoryBlock& mem, bool readBody) { - MemoryInputStream rawInput(mem, true); - return decode(rawInput, readBody); -} - -std::vector MessageDecoder::decodes(MemoryBlock& mem) { - return decodes(mem, true); +std::vector MessageDecoder::decodes(ByteBuffer& byteBuffer) { + return decodes(byteBuffer, true); } -std::vector MessageDecoder::decodes(MemoryBlock& mem, bool readBody) { +std::vector MessageDecoder::decodes(ByteBuffer& byteBuffer, bool readBody) { std::vector msgExts; - MemoryInputStream rawInput(mem, true); - while (rawInput.getNumBytesRemaining() > 0) { - auto msgExt = clientDecode(rawInput, readBody); + while (byteBuffer.hasRemaining()) { + auto msgExt = clientDecode(byteBuffer, readBody); if (nullptr == msgExt) { break; } - msgExts.emplace_back(msgExt); + msgExts.emplace_back(std::move(msgExt)); } return msgExts; } @@ -280,10 +261,10 @@ std::map MessageDecoder::string2messageProperties(cons } std::string MessageDecoder::encodeMessage(Message& message) { - const std::string& body = message.getBody(); - uint32_t bodyLen = body.length(); + const auto& body = message.getBody(); + uint32_t bodyLen = body.size(); std::string properties = MessageDecoder::messageProperties2String(message.getProperties()); - uint16_t propertiesLength = (int16_t)properties.length(); + uint16_t propertiesLength = (int16_t)properties.size(); uint32_t storeSize = 4 // 1 TOTALSIZE + 4 // 2 MAGICCODE + 4 // 3 BODYCRC @@ -295,31 +276,31 @@ std::string MessageDecoder::encodeMessage(Message& message) { std::string encodeMsg; // 1 TOTALSIZE - uint32_t storeSize_net = ByteOrder::swapIfLittleEndian(storeSize); + uint32_t storeSize_net = ByteOrderUtil::NorminalBigEndian(storeSize); encodeMsg.append((char*)&storeSize_net, sizeof(uint32_t)); // 2 MAGICCODE uint32_t magicCode = 0; - uint32_t magicCode_net = ByteOrder::swapIfLittleEndian(magicCode); + uint32_t magicCode_net = ByteOrderUtil::NorminalBigEndian(magicCode); encodeMsg.append((char*)&magicCode_net, sizeof(uint32_t)); // 3 BODYCRC uint32_t bodyCrc = 0; - uint32_t bodyCrc_net = ByteOrder::swapIfLittleEndian(bodyCrc); + uint32_t bodyCrc_net = ByteOrderUtil::NorminalBigEndian(bodyCrc); encodeMsg.append((char*)&bodyCrc_net, sizeof(uint32_t)); // 4 FLAG uint32_t flag = message.getFlag(); - uint32_t flag_net = ByteOrder::swapIfLittleEndian(flag); + uint32_t flag_net = ByteOrderUtil::NorminalBigEndian(flag); encodeMsg.append((char*)&flag_net, sizeof(uint32_t)); // 5 BODY - uint32_t bodyLen_net = ByteOrder::swapIfLittleEndian(bodyLen); + uint32_t bodyLen_net = ByteOrderUtil::NorminalBigEndian(bodyLen); encodeMsg.append((char*)&bodyLen_net, sizeof(uint32_t)); - encodeMsg.append(body); + encodeMsg.append(body.data(), body.size()); // 6 properties - uint16_t propertiesLength_net = ByteOrder::swapIfLittleEndian(propertiesLength); + uint16_t propertiesLength_net = ByteOrderUtil::NorminalBigEndian(propertiesLength); encodeMsg.append((char*)&propertiesLength_net, sizeof(uint16_t)); encodeMsg.append(std::move(properties)); diff --git a/src/message/MessageDecoder.h b/src/message/MessageDecoder.h index 2bc935a75..1dd259c99 100644 --- a/src/message/MessageDecoder.h +++ b/src/message/MessageDecoder.h @@ -17,10 +17,10 @@ #ifndef ROCKETMQ_MESSAGE_MESSAGEDECODER_H_ #define ROCKETMQ_MESSAGE_MESSAGEDECODER_H_ +#include "ByteBuffer.hpp" #include "MQClientException.h" #include "MQMessageExt.h" #include "MessageId.h" -#include "MemoryInputStream.h" namespace rocketmq { @@ -29,11 +29,13 @@ class MessageDecoder { static std::string createMessageId(const struct sockaddr* sa, int64_t offset); static MessageId decodeMessageId(const std::string& msgId); - static MessageExtPtr decode(MemoryBlock& mem); - static MessageExtPtr decode(MemoryBlock& mem, bool readBody); + static MessageExtPtr clientDecode(ByteBuffer& byteBuffer, bool readBody); + static MessageExtPtr decode(ByteBuffer& byteBuffer); + static MessageExtPtr decode(ByteBuffer& byteBuffer, bool readBody); + static MessageExtPtr decode(ByteBuffer& byteBuffer, bool readBody, bool deCompressBody, bool isClient); - static std::vector decodes(MemoryBlock& mem); - static std::vector decodes(MemoryBlock& mem, bool readBody); + static std::vector decodes(ByteBuffer& byteBuffer); + static std::vector decodes(ByteBuffer& byteBuffer, bool readBody); static std::string messageProperties2String(const std::map& properties); static std::map string2messageProperties(const std::string& properties); @@ -41,12 +43,6 @@ class MessageDecoder { static std::string encodeMessage(Message& message); static std::string encodeMessages(std::vector& msgs); - private: - static MessageExtPtr clientDecode(MemoryInputStream& byteBuffer, bool readBody); - - static MessageExtPtr decode(MemoryInputStream& byteBuffer, bool readBody); - static MessageExtPtr decode(MemoryInputStream& byteBuffer, bool readBody, bool deCompressBody, bool isClient); - public: static const char NAME_VALUE_SEPARATOR; static const char PROPERTY_SEPARATOR; diff --git a/src/message/MessageExtImpl.cpp b/src/message/MessageExtImpl.cpp index ea36b3580..94b38c459 100644 --- a/src/message/MessageExtImpl.cpp +++ b/src/message/MessageExtImpl.cpp @@ -60,7 +60,7 @@ MessageExtImpl::~MessageExtImpl() { } TopicFilterType MessageExtImpl::parseTopicFilterType(int32_t sysFlag) { - if ((sysFlag & MessageSysFlag::MultiTagsFlag) == MessageSysFlag::MultiTagsFlag) { + if ((sysFlag & MessageSysFlag::MULTI_TAGS_FLAG) == MessageSysFlag::MULTI_TAGS_FLAG) { return MULTI_TAG; } return SINGLE_TAG; diff --git a/src/message/MessageImpl.cpp b/src/message/MessageImpl.cpp index f3f9def3b..1738952b2 100644 --- a/src/message/MessageImpl.cpp +++ b/src/message/MessageImpl.cpp @@ -144,11 +144,6 @@ const std::string& MessageImpl::getBody() const { return body_; } -void MessageImpl::setBody(const char* body, int len) { - body_.clear(); - body_.append(body, len); -} - void MessageImpl::setBody(const std::string& body) { body_ = body; } diff --git a/src/message/MessageImpl.h b/src/message/MessageImpl.h index bc4424f34..de83e5ee2 100644 --- a/src/message/MessageImpl.h +++ b/src/message/MessageImpl.h @@ -65,7 +65,6 @@ class MessageImpl : public noncopyable, // base void setFlag(int32_t flag) override; const std::string& getBody() const override; - void setBody(const char* body, int len) override; void setBody(const std::string& body) override; void setBody(std::string&& body) override; diff --git a/src/message/MessageUtil.cpp b/src/message/MessageUtil.cpp index dc7e0a02e..21d2510de 100644 --- a/src/message/MessageUtil.cpp +++ b/src/message/MessageUtil.cpp @@ -16,6 +16,7 @@ */ #include "MessageUtil.h" +#include "ByteArray.h" #include "ClientErrorCode.h" #include "MessageImpl.h" #include "MessageAccessor.h" diff --git a/src/producer/DefaultMQProducer.cpp b/src/producer/DefaultMQProducer.cpp index bf1c7ab81..89964703a 100644 --- a/src/producer/DefaultMQProducer.cpp +++ b/src/producer/DefaultMQProducer.cpp @@ -30,7 +30,7 @@ DefaultMQProducer::DefaultMQProducer(const std::string& groupname, RPCHookPtr rp DefaultMQProducer::DefaultMQProducer(const std::string& groupname, RPCHookPtr rpcHook, DefaultMQProducerConfigPtr producerConfig) - : DefaultMQProducerConfigProxy(producerConfig), m_producerDelegate(nullptr) { + : DefaultMQProducerConfigProxy(producerConfig), producer_impl_(nullptr) { // set default group name if (groupname.empty()) { setGroupName(DEFAULT_PRODUCER_GROUP); @@ -38,75 +38,75 @@ DefaultMQProducer::DefaultMQProducer(const std::string& groupname, setGroupName(groupname); } - m_producerDelegate = DefaultMQProducerImpl::create(getRealConfig(), rpcHook); + producer_impl_ = DefaultMQProducerImpl::create(getRealConfig(), rpcHook); } DefaultMQProducer::~DefaultMQProducer() = default; void DefaultMQProducer::start() { - m_producerDelegate->start(); + producer_impl_->start(); } void DefaultMQProducer::shutdown() { - m_producerDelegate->shutdown(); + producer_impl_->shutdown(); } SendResult DefaultMQProducer::send(MQMessage& msg) { - return m_producerDelegate->send(msg); + return producer_impl_->send(msg); } SendResult DefaultMQProducer::send(MQMessage& msg, long timeout) { - return m_producerDelegate->send(msg, timeout); + return producer_impl_->send(msg, timeout); } SendResult DefaultMQProducer::send(MQMessage& msg, const MQMessageQueue& mq) { - return m_producerDelegate->send(msg, mq); + return producer_impl_->send(msg, mq); } SendResult DefaultMQProducer::send(MQMessage& msg, const MQMessageQueue& mq, long timeout) { - return m_producerDelegate->send(msg, mq, timeout); + return producer_impl_->send(msg, mq, timeout); } void DefaultMQProducer::send(MQMessage& msg, SendCallback* sendCallback) noexcept { - m_producerDelegate->send(msg, sendCallback, getSendMsgTimeout()); + producer_impl_->send(msg, sendCallback, getSendMsgTimeout()); } void DefaultMQProducer::send(MQMessage& msg, SendCallback* sendCallback, long timeout) noexcept { - m_producerDelegate->send(msg, sendCallback, timeout); + producer_impl_->send(msg, sendCallback, timeout); } void DefaultMQProducer::send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept { - return m_producerDelegate->send(msg, mq, sendCallback); + return producer_impl_->send(msg, mq, sendCallback); } void DefaultMQProducer::send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) noexcept { - m_producerDelegate->send(msg, mq, sendCallback, timeout); + producer_impl_->send(msg, mq, sendCallback, timeout); } void DefaultMQProducer::sendOneway(MQMessage& msg) { - m_producerDelegate->sendOneway(msg); + producer_impl_->sendOneway(msg); } void DefaultMQProducer::sendOneway(MQMessage& msg, const MQMessageQueue& mq) { - m_producerDelegate->sendOneway(msg, mq); + producer_impl_->sendOneway(msg, mq); } SendResult DefaultMQProducer::send(MQMessage& msg, MessageQueueSelector* selector, void* arg) { - return m_producerDelegate->send(msg, selector, arg); + return producer_impl_->send(msg, selector, arg); } SendResult DefaultMQProducer::send(MQMessage& msg, MessageQueueSelector* selector, void* arg, long timeout) { - return m_producerDelegate->send(msg, selector, arg, timeout); + return producer_impl_->send(msg, selector, arg, timeout); } void DefaultMQProducer::send(MQMessage& msg, MessageQueueSelector* selector, void* arg, SendCallback* sendCallback) noexcept { - return m_producerDelegate->send(msg, selector, arg, sendCallback); + return producer_impl_->send(msg, selector, arg, sendCallback); } void DefaultMQProducer::send(MQMessage& msg, @@ -114,11 +114,11 @@ void DefaultMQProducer::send(MQMessage& msg, void* arg, SendCallback* sendCallback, long timeout) noexcept { - m_producerDelegate->send(msg, selector, arg, sendCallback, timeout); + producer_impl_->send(msg, selector, arg, sendCallback, timeout); } void DefaultMQProducer::sendOneway(MQMessage& msg, MessageQueueSelector* selector, void* arg) { - m_producerDelegate->sendOneway(msg, selector, arg); + producer_impl_->sendOneway(msg, selector, arg); } TransactionSendResult DefaultMQProducer::sendMessageInTransaction(MQMessage& msg, void* arg) { @@ -127,36 +127,35 @@ TransactionSendResult DefaultMQProducer::sendMessageInTransaction(MQMessage& msg } SendResult DefaultMQProducer::send(std::vector& msgs) { - return m_producerDelegate->send(msgs); + return producer_impl_->send(msgs); } SendResult DefaultMQProducer::send(std::vector& msgs, long timeout) { - return m_producerDelegate->send(msgs, timeout); + return producer_impl_->send(msgs, timeout); } SendResult DefaultMQProducer::send(std::vector& msgs, const MQMessageQueue& mq) { - return m_producerDelegate->send(msgs, mq); + return producer_impl_->send(msgs, mq); } SendResult DefaultMQProducer::send(std::vector& msgs, const MQMessageQueue& mq, long timeout) { - return m_producerDelegate->send(msgs, mq, timeout); + return producer_impl_->send(msgs, mq, timeout); } MQMessage DefaultMQProducer::request(MQMessage& msg, long timeout) { - return m_producerDelegate->request(msg, timeout); + return producer_impl_->request(msg, timeout); } bool DefaultMQProducer::isSendLatencyFaultEnable() const { - return std::dynamic_pointer_cast(m_producerDelegate)->isSendLatencyFaultEnable(); + return std::dynamic_pointer_cast(producer_impl_)->isSendLatencyFaultEnable(); } void DefaultMQProducer::setSendLatencyFaultEnable(bool sendLatencyFaultEnable) { - std::dynamic_pointer_cast(m_producerDelegate) - ->setSendLatencyFaultEnable(sendLatencyFaultEnable); + std::dynamic_pointer_cast(producer_impl_)->setSendLatencyFaultEnable(sendLatencyFaultEnable); } void DefaultMQProducer::setRPCHook(RPCHookPtr rpcHook) { - std::dynamic_pointer_cast(m_producerDelegate)->setRPCHook(rpcHook); + std::dynamic_pointer_cast(producer_impl_)->setRPCHook(rpcHook); } } // namespace rocketmq diff --git a/src/producer/DefaultMQProducerImpl.cpp b/src/producer/DefaultMQProducerImpl.cpp index 4fea984ea..54d16fcab 100644 --- a/src/producer/DefaultMQProducerImpl.cpp +++ b/src/producer/DefaultMQProducerImpl.cpp @@ -528,13 +528,13 @@ SendResult* DefaultMQProducerImpl::sendKernelImpl(MessagePtr msg, int sysFlag = 0; bool msgBodyCompressed = false; if (tryToCompressMessage(*msg)) { - sysFlag |= MessageSysFlag::CompressedFlag; + sysFlag |= MessageSysFlag::COMPRESSED_FLAG; msgBodyCompressed = true; } const auto& tranMsg = msg->getProperty(MQMessageConst::PROPERTY_TRANSACTION_PREPARED); if (UtilAll::stob(tranMsg)) { - sysFlag |= MessageSysFlag::TransactionPreparedType; + sysFlag |= MessageSysFlag::TRANSACTION_PREPARED_TYPE; } // TOOD: send message hook @@ -747,14 +747,14 @@ void DefaultMQProducerImpl::checkTransactionStateImpl(const std::string& addr, endHeader->transactionId = transactionId; switch (localTransactionState) { case COMMIT_MESSAGE: - endHeader->commitOrRollback = MessageSysFlag::TransactionCommitType; + endHeader->commitOrRollback = MessageSysFlag::TRANSACTION_COMMIT_TYPE; break; case ROLLBACK_MESSAGE: - endHeader->commitOrRollback = MessageSysFlag::TransactionRollbackType; + endHeader->commitOrRollback = MessageSysFlag::TRANSACTION_ROLLBACK_TYPE; LOG_WARN_NEW("when broker check, client rollback this transaction, {}", endHeader->toString()); break; case UNKNOWN: - endHeader->commitOrRollback = MessageSysFlag::TransactionNotType; + endHeader->commitOrRollback = MessageSysFlag::TRANSACTION_NOT_TYPE; LOG_WARN_NEW("when broker check, client does not know this transaction state, {}", endHeader->toString()); break; default: @@ -785,13 +785,13 @@ void DefaultMQProducerImpl::endTransaction(SendResult& sendResult, requestHeader->commitLogOffset = id.getOffset(); switch (localTransactionState) { case COMMIT_MESSAGE: - requestHeader->commitOrRollback = MessageSysFlag::TransactionCommitType; + requestHeader->commitOrRollback = MessageSysFlag::TRANSACTION_COMMIT_TYPE; break; case ROLLBACK_MESSAGE: - requestHeader->commitOrRollback = MessageSysFlag::TransactionRollbackType; + requestHeader->commitOrRollback = MessageSysFlag::TRANSACTION_ROLLBACK_TYPE; break; case UNKNOWN: - requestHeader->commitOrRollback = MessageSysFlag::TransactionNotType; + requestHeader->commitOrRollback = MessageSysFlag::TRANSACTION_NOT_TYPE; break; default: break; @@ -819,10 +819,10 @@ bool DefaultMQProducerImpl::tryToCompressMessage(Message& msg) { } const auto& body = msg.getBody(); - if (body.length() >= m_producerConfig->getCompressMsgBodyOverHowmuch()) { - std::string outBody; - if (UtilAll::deflate(body, outBody, m_producerConfig->getCompressLevel())) { - msg.setBody(std::move(outBody)); + if (body.size() >= m_producerConfig->getCompressMsgBodyOverHowmuch()) { + std::string out_body; + if (UtilAll::deflate(body, out_body, m_producerConfig->getCompressLevel())) { + msg.setBody(std::move(out_body)); msg.putProperty(MQMessageConst::PROPERTY_ALREADY_COMPRESSED_FLAG, "true"); return true; } diff --git a/src/producer/TransactionMQProducer.cpp b/src/producer/TransactionMQProducer.cpp index cd2e6a770..cae9240e9 100644 --- a/src/producer/TransactionMQProducer.cpp +++ b/src/producer/TransactionMQProducer.cpp @@ -45,17 +45,17 @@ void TransactionMQProducer::setTransactionListener(TransactionListener* transact } void TransactionMQProducer::start() { - std::dynamic_pointer_cast(m_producerDelegate)->initTransactionEnv(); + std::dynamic_pointer_cast(producer_impl_)->initTransactionEnv(); DefaultMQProducer::start(); } void TransactionMQProducer::shutdown() { DefaultMQProducer::shutdown(); - std::dynamic_pointer_cast(m_producerDelegate)->destroyTransactionEnv(); + std::dynamic_pointer_cast(producer_impl_)->destroyTransactionEnv(); } TransactionSendResult TransactionMQProducer::sendMessageInTransaction(MQMessage& msg, void* arg) { - return m_producerDelegate->sendMessageInTransaction(msg, arg); + return producer_impl_->sendMessageInTransaction(msg, arg); } } // namespace rocketmq diff --git a/src/protocol/RemotingCommand.cpp b/src/protocol/RemotingCommand.cpp index 413edbc35..25415239a 100644 --- a/src/protocol/RemotingCommand.cpp +++ b/src/protocol/RemotingCommand.cpp @@ -16,10 +16,14 @@ */ #include "RemotingCommand.h" -#include -#include +#include // std::memcpy + +#include // std::move +#include // std::atomic +#include // std::numeric_limits #include "ByteOrder.h" +#include "ByteBuffer.hpp" #include "Logging.h" #include "MQVersion.h" #include "RemotingSerializable.h" @@ -54,92 +58,104 @@ RemotingCommand::RemotingCommand(int32_t code, int32_t flag, const std::string& remark, CommandCustomHeader* customHeader) - : m_code(code), - m_language(language), - m_version(version), - m_opaque(opaque), - m_flag(flag), - m_remark(remark), - m_customHeader(customHeader) {} + : code_(code), + language_(language), + version_(version), + opaque_(opaque), + flag_(flag), + remark_(remark), + custom_header_(customHeader) {} RemotingCommand::RemotingCommand(RemotingCommand&& command) { - m_code = command.m_code; - m_language = std::move(command.m_language); - m_version = command.m_version; - m_opaque = command.m_opaque; - m_flag = command.m_flag; - m_remark = std::move(command.m_remark); - m_extFields = std::move(command.m_extFields); - m_customHeader = std::move(command.m_customHeader); - m_body = std::move(command.m_body); + code_ = command.code_; + language_ = std::move(command.language_); + version_ = command.version_; + opaque_ = command.opaque_; + flag_ = command.flag_; + remark_ = std::move(command.remark_); + ext_fields_ = std::move(command.ext_fields_); + custom_header_ = std::move(command.custom_header_); + body_ = std::move(command.body_); } RemotingCommand::~RemotingCommand() = default; -MemoryBlockPtr RemotingCommand::encode() const { +ByteArrayRef RemotingCommand::encode() const { Json::Value root; - root["code"] = m_code; - root["language"] = m_language; - root["version"] = m_version; - root["opaque"] = m_opaque; - root["flag"] = m_flag; - root["remark"] = m_remark; - - Json::Value extJson; - for (const auto& it : m_extFields) { - extJson[it.first] = it.second; + root["code"] = code_; + root["language"] = language_; + root["version"] = version_; + root["opaque"] = opaque_; + root["flag"] = flag_; + root["remark"] = remark_; + + Json::Value ext_fields; + for (const auto& it : ext_fields_) { + ext_fields[it.first] = it.second; } - if (m_customHeader != nullptr) { + if (custom_header_ != nullptr) { // write customHeader to extFields - m_customHeader->Encode(extJson); + custom_header_->Encode(ext_fields); } - root["extFields"] = extJson; + root["extFields"] = ext_fields; + // serialize header std::string header = RemotingSerializable::toJson(root); - uint32_t headerLen = header.size(); - uint32_t packageLen = 4 + headerLen; - if (m_body != nullptr) { - packageLen += m_body->getSize(); + // 1> header length size + uint32_t length = 4; + // 2> header data length + length += header.size(); + // 3> body data length + if (body_ != nullptr) { + length += body_->size(); } - uint32_t messageHeader[2]; - messageHeader[0] = ByteOrder::swapIfLittleEndian(packageLen); - messageHeader[1] = ByteOrder::swapIfLittleEndian(headerLen); - - std::unique_ptr package(new MemoryPool(4 + packageLen)); - package->copyFrom(messageHeader, 0, sizeof(messageHeader)); - package->copyFrom(header.data(), sizeof(messageHeader), headerLen); - if (m_body != nullptr && m_body->getSize() > 0) { - package->copyFrom(m_body->getData(), sizeof(messageHeader) + headerLen, m_body->getSize()); + std::unique_ptr result(ByteBuffer::allocate(4 + length)); + + // length + result->putInt(length); + // header length + result->putInt((uint32_t)header.size()); + // header data + result->put(ByteArray((char*)header.data(), header.size())); + // body data; + if (body_ != nullptr) { + result->put(*body_); } - return std::move(package); + // result->flip(); + + return result->byte_array(); +} + +static inline int32_t getHeaderLength(int32_t length) { + return length & 0x00FFFFFF; } -RemotingCommand* RemotingCommand::Decode(MemoryBlockPtr2 package, bool havePackageLen) { +static RemotingCommand* Decode(ByteBuffer& byteBuffer, bool hasPackageLength) { // decode package: [4 bytes(packageLength) +] 4 bytes(headerLength) + header + body - int packageLength = package->getSize(); - uint32_t netHeaderLen; - const char* data = package->getData(); - - if (havePackageLen) { - data += 4; - packageLength -= 4; - package->copyTo(&netHeaderLen, 4, sizeof(netHeaderLen)); - } else { - package->copyTo(&netHeaderLen, 0, sizeof(netHeaderLen)); + + int32_t length = byteBuffer.limit(); + if (hasPackageLength) { + // skip package length + (void)byteBuffer.getInt(); + length -= 4; } - int oriHeaderLen = ByteOrder::swapIfLittleEndian(netHeaderLen); - int headerLength = oriHeaderLen & 0xFFFFFF; // decode header - const char* begin = data + 4; - const char* end = data + 4 + headerLength; + + int32_t oriHeaderLen = byteBuffer.getInt(); + int32_t headerLength = getHeaderLength(oriHeaderLen); + + // ByteArray headData(headerLength); + // byteBuffer.get(headerData); + ByteArray headerData(byteBuffer.array() + byteBuffer.arrayOffset() + byteBuffer.position(), headerLength); + byteBuffer.position(byteBuffer.position() + headerLength); Json::Value object; try { - object = RemotingSerializable::fromJson(begin, end); + object = RemotingSerializable::fromJson(headerData); } catch (std::exception& e) { LOG_WARN_NEW("parse json failed. {}", e.what()); THROW_MQEXCEPTION(MQClientException, "conn't parse json", -1); @@ -162,16 +178,21 @@ RemotingCommand* RemotingCommand::Decode(MemoryBlockPtr2 package, bool havePacka for (auto& name : extFields.getMemberNames()) { auto& value = extFields[name]; if (value.isString()) { - cmd->m_extFields[name] = value.asString(); + cmd->set_ext_field(name, value.asString()); } } } // decode body - int bodyLength = packageLength - 4 - headerLength; + + int32_t bodyLength = length - 4 - headerLength; if (bodyLength > 0) { - auto* body = new MemoryView(package, (havePackageLen ? 8 : 4) + headerLength); - cmd->setBody(body); + // ByteArrayRef bodyData = std::make_shared(bodyLength); + // byteBuffer.get(*bodyData); + ByteArrayRef bodyData = + slice(byteBuffer.byte_array(), byteBuffer.arrayOffset() + byteBuffer.position(), bodyLength); + byteBuffer.position(byteBuffer.position() + bodyLength); + cmd->set_body(std::move(bodyData)); } LOG_DEBUG_NEW("code:{}, language:{}, version:{}, opaque:{}, flag:{}, remark:{}, headLen:{}, bodyLen:{}", code, @@ -180,85 +201,38 @@ RemotingCommand* RemotingCommand::Decode(MemoryBlockPtr2 package, bool havePacka return cmd.release(); } -int32_t RemotingCommand::getCode() const { - return m_code; -} - -void RemotingCommand::setCode(int32_t code) { - m_code = code; -} - -int32_t RemotingCommand::getVersion() const { - return m_version; -} - -int32_t RemotingCommand::getOpaque() const { - return m_opaque; -} - -void RemotingCommand::setOpaque(int32_t opaque) { - m_opaque = opaque; -} - -int32_t RemotingCommand::getFlag() const { - return m_flag; -} - -const std::string& RemotingCommand::getRemark() const { - return m_remark; -} - -void RemotingCommand::setRemark(const std::string& mark) { - m_remark = mark; +RemotingCommand* RemotingCommand::Decode(ByteArrayRef array, bool hasPackageLength) { + std::unique_ptr byteBuffer(ByteBuffer::wrap(std::move(array))); + return rocketmq::Decode(*byteBuffer, hasPackageLength); } bool RemotingCommand::isResponseType() { int bits = 1 << RPC_TYPE; - return (m_flag & bits) == bits; + return (flag_ & bits) == bits; } void RemotingCommand::markResponseType() { int bits = 1 << RPC_TYPE; - m_flag |= bits; + flag_ |= bits; } bool RemotingCommand::isOnewayRPC() { int bits = 1 << RPC_ONEWAY; - return (m_flag & bits) == bits; + return (flag_ & bits) == bits; } void RemotingCommand::markOnewayRPC() { int bits = 1 << RPC_ONEWAY; - m_flag |= bits; -} - -void RemotingCommand::addExtField(const std::string& key, const std::string& value) { - m_extFields[key] = value; + flag_ |= bits; } CommandCustomHeader* RemotingCommand::readCustomHeader() const { - return m_customHeader.get(); -} - -MemoryBlockPtr2 RemotingCommand::getBody() const { - return m_body; -} - -void RemotingCommand::setBody(MemoryBlock* body) { - m_body.reset(body); -} - -void RemotingCommand::setBody(MemoryBlockPtr2 body) { - m_body = body; -} - -void RemotingCommand::setBody(const std::string& body) { - m_body.reset(new MemoryPool(body.data(), body.size())); + return custom_header_.get(); } std::string RemotingCommand::toString() const { std::stringstream ss; - ss << "code:" << m_code << ", opaque:" << m_opaque << ", flag:" << m_flag << ", body.size:" << m_body->getSize(); + ss << "code:" << code_ << ", opaque:" << opaque_ << ", flag:" << flag_ << ", body.size:" << body_->size(); return ss.str(); } diff --git a/src/protocol/RemotingSerializable.cpp b/src/protocol/RemotingSerializable.cpp index 96d04b514..e86492668 100644 --- a/src/protocol/RemotingSerializable.cpp +++ b/src/protocol/RemotingSerializable.cpp @@ -71,9 +71,9 @@ Json::Value RemotingSerializable::fromJson(const std::string& json) { return fromJson(begin, end); } -Json::Value RemotingSerializable::fromJson(const MemoryBlock& data) { - const char* begin = data.getData(); - const char* end = begin + data.getSize(); +Json::Value RemotingSerializable::fromJson(const ByteArray& bytes) { + const char* begin = bytes.array(); + const char* end = begin + bytes.size(); return fromJson(begin, end); } diff --git a/src/protocol/RemotingSerializable.h b/src/protocol/RemotingSerializable.h index 08ed73b08..e5a37d852 100644 --- a/src/protocol/RemotingSerializable.h +++ b/src/protocol/RemotingSerializable.h @@ -19,7 +19,7 @@ #include -#include "DataBlock.h" +#include "ByteArray.h" namespace rocketmq { @@ -35,7 +35,7 @@ class RemotingSerializable { static Json::Value fromJson(std::istream& sin); static Json::Value fromJson(const std::string& json); - static Json::Value fromJson(const MemoryBlock& data); + static Json::Value fromJson(const ByteArray& bytes); static Json::Value fromJson(const char* begin, const char* end); private: diff --git a/src/protocol/TopicList.h b/src/protocol/TopicList.h index faa9bbb7e..450e6b2da 100644 --- a/src/protocol/TopicList.h +++ b/src/protocol/TopicList.h @@ -17,19 +17,19 @@ #ifndef __TOPIC_LIST_H__ #define __TOPIC_LIST_H__ -#include -#include +#include // std::string +#include // std::vector -#include "DataBlock.h" +#include "ByteArray.h" namespace rocketmq { class TopicList { public: - static TopicList* Decode(MemoryBlock& mem) { return new TopicList(); } + static TopicList* Decode(const ByteArray& mem) { return new TopicList(); } private: - std::vector m_topicList; + std::vector topic_list_; }; } // namespace rocketmq diff --git a/src/protocol/TopicRouteData.h b/src/protocol/TopicRouteData.h index 61935881f..446dd7b42 100644 --- a/src/protocol/TopicRouteData.h +++ b/src/protocol/TopicRouteData.h @@ -23,7 +23,7 @@ #include #include -#include "DataBlock.h" +#include "ByteArray.h" #include "Logging.h" #include "RemotingSerializable.h" #include "UtilAll.h" @@ -62,8 +62,8 @@ typedef std::shared_ptr TopicRouteDataPtr; class TopicRouteData { public: - static TopicRouteData* Decode(MemoryBlock& mem) { - Json::Value root = RemotingSerializable::fromJson(mem); + static TopicRouteData* Decode(const ByteArray& bodyData) { + Json::Value root = RemotingSerializable::fromJson(bodyData); std::unique_ptr trd(new TopicRouteData()); trd->setOrderTopicConf(root["orderTopicConf"].asString()); diff --git a/src/protocol/body/LockBatchBody.cpp b/src/protocol/body/LockBatchBody.cpp index 9c3b6f0a4..fde8dcb1a 100644 --- a/src/protocol/body/LockBatchBody.cpp +++ b/src/protocol/body/LockBatchBody.cpp @@ -65,8 +65,8 @@ void LockBatchResponseBody::setLockOKMQSet(std::vector lockOKMQS m_lockOKMQSet.swap(lockOKMQSet); } -LockBatchResponseBody* LockBatchResponseBody::Decode(MemoryBlock& mem) { - Json::Value root = RemotingSerializable::fromJson(mem); +LockBatchResponseBody* LockBatchResponseBody::Decode(const ByteArray& bodyData) { + Json::Value root = RemotingSerializable::fromJson(bodyData); auto& mqs = root["lockOKMQSet"]; std::unique_ptr body(new LockBatchResponseBody()); for (const auto& qd : mqs) { diff --git a/src/protocol/body/LockBatchBody.h b/src/protocol/body/LockBatchBody.h index 22bd8e638..ce38974df 100644 --- a/src/protocol/body/LockBatchBody.h +++ b/src/protocol/body/LockBatchBody.h @@ -20,7 +20,6 @@ #include #include -#include "DataBlock.h" #include "MQMessageQueue.h" #include "RemotingSerializable.h" #include "UtilAll.h" @@ -48,7 +47,7 @@ class LockBatchRequestBody : public RemotingSerializable { class LockBatchResponseBody { public: - static LockBatchResponseBody* Decode(MemoryBlock& mem); + static LockBatchResponseBody* Decode(const ByteArray& bodyData); const std::vector& getLockOKMQSet(); void setLockOKMQSet(std::vector lockOKMQSet); diff --git a/src/protocol/body/ResetOffsetBody.cpp b/src/protocol/body/ResetOffsetBody.cpp index 9caaf084f..497f5915b 100644 --- a/src/protocol/body/ResetOffsetBody.cpp +++ b/src/protocol/body/ResetOffsetBody.cpp @@ -20,9 +20,9 @@ namespace rocketmq { -ResetOffsetBody* ResetOffsetBody::Decode(MemoryBlock& mem) { +ResetOffsetBody* ResetOffsetBody::Decode(const ByteArray& bodyData) { // FIXME: object as key - Json::Value root = RemotingSerializable::fromJson(mem); + Json::Value root = RemotingSerializable::fromJson(bodyData); Json::Value qds = root["offsetTable"]; std::unique_ptr body(new ResetOffsetBody()); for (unsigned int i = 0; i < qds.size(); i++) { @@ -35,11 +35,11 @@ ResetOffsetBody* ResetOffsetBody::Decode(MemoryBlock& mem) { } std::map ResetOffsetBody::getOffsetTable() { - return m_offsetTable; + return offset_table_; } void ResetOffsetBody::setOffsetTable(const MQMessageQueue& mq, int64_t offset) { - m_offsetTable[mq] = offset; + offset_table_[mq] = offset; } } // namespace rocketmq diff --git a/src/protocol/body/ResetOffsetBody.h b/src/protocol/body/ResetOffsetBody.h index bc2c5f061..f1024b9e5 100644 --- a/src/protocol/body/ResetOffsetBody.h +++ b/src/protocol/body/ResetOffsetBody.h @@ -17,22 +17,22 @@ #ifndef __RESET_OFFSET_BODY__ #define __RESET_OFFSET_BODY__ -#include +#include // std::map -#include "DataBlock.h" +#include "ByteArray.h" #include "MQMessageQueue.h" namespace rocketmq { class ResetOffsetBody { public: - static ResetOffsetBody* Decode(MemoryBlock& mem); + static ResetOffsetBody* Decode(const ByteArray& bodyData); std::map getOffsetTable(); void setOffsetTable(const MQMessageQueue& mq, int64_t offset); private: - std::map m_offsetTable; + std::map offset_table_; }; } // namespace rocketmq diff --git a/src/protocol/header/CommandHeader.cpp b/src/protocol/header/CommandHeader.cpp index 2bb5ceec5..6a6ce8026 100644 --- a/src/protocol/header/CommandHeader.cpp +++ b/src/protocol/header/CommandHeader.cpp @@ -642,8 +642,8 @@ void ConsumerSendMsgBackRequestHeader::SetDeclaredFieldOfCommandHeader(std::map< // GetConsumerListByGroupResponseBody //###################################### -GetConsumerListByGroupResponseBody* GetConsumerListByGroupResponseBody::Decode(MemoryBlock& mem) { - Json::Value root = RemotingSerializable::fromJson(mem); +GetConsumerListByGroupResponseBody* GetConsumerListByGroupResponseBody::Decode(const ByteArray& bodyData) { + Json::Value root = RemotingSerializable::fromJson(bodyData); auto& ids = root["consumerIdList"]; std::unique_ptr body(new GetConsumerListByGroupResponseBody()); for (unsigned int i = 0; i < ids.size(); i++) { diff --git a/src/protocol/header/CommandHeader.h b/src/protocol/header/CommandHeader.h index 53b211464..39998d6a2 100644 --- a/src/protocol/header/CommandHeader.h +++ b/src/protocol/header/CommandHeader.h @@ -19,8 +19,8 @@ #include +#include "ByteArray.h" #include "CommandCustomHeader.h" -#include "DataBlock.h" namespace rocketmq { @@ -395,7 +395,7 @@ class ConsumerSendMsgBackRequestHeader : public CommandCustomHeader { class GetConsumerListByGroupResponseBody : public CommandCustomHeader { public: - static GetConsumerListByGroupResponseBody* Decode(MemoryBlock& mem); + static GetConsumerListByGroupResponseBody* Decode(const ByteArray& bodyData); void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: diff --git a/src/transport/SocketUtil.cpp b/src/transport/SocketUtil.cpp index e4810d8d5..59dff7bee 100644 --- a/src/transport/SocketUtil.cpp +++ b/src/transport/SocketUtil.cpp @@ -42,12 +42,21 @@ union sockaddr_union { thread_local static sockaddr_union sin_buf; -struct sockaddr* ipPort2SocketAddress(uint32_t host, uint16_t port) { - struct sockaddr_in* sin = &sin_buf.sin; - sin->sin_family = AF_INET; - sin->sin_port = htons(port); - sin->sin_addr.s_addr = htonl(host); - return (struct sockaddr*)sin; +struct sockaddr* ipPort2SocketAddress(const ByteArray& ip, uint16_t port) { + if (ip.size() == 4) { + struct sockaddr_in* sin = &sin_buf.sin; + sin->sin_family = AF_INET; + sin->sin_port = ByteOrderUtil::NorminalBigEndian(port); + ByteOrderUtil::Readsin_addr)>(&sin->sin_addr, ip.array()); + return (struct sockaddr*)sin; + } else if (ip.size() == 16) { + struct sockaddr_in6* sin6 = &sin_buf.sin6; + sin6->sin6_family = AF_INET6; + sin6->sin6_port = ByteOrderUtil::NorminalBigEndian(port); + ByteOrderUtil::Readsin6_addr)>(&sin6->sin6_addr, ip.array()); + return (struct sockaddr*)sin6; + } + return nullptr; } struct sockaddr* string2SocketAddress(const std::string& addr) { @@ -159,11 +168,11 @@ struct sockaddr* copySocketAddress(struct sockaddr* dst, const struct sockaddr* } uint64_t h2nll(uint64_t v) { - return ByteOrder::swapIfLittleEndian(v); + return ByteOrderUtil::NorminalBigEndian(v); } uint64_t n2hll(uint64_t v) { - return ByteOrder::swapIfLittleEndian(v); + return ByteOrderUtil::NorminalBigEndian(v); } } // namespace rocketmq diff --git a/src/transport/SocketUtil.h b/src/transport/SocketUtil.h index e6a421bab..bd2f31cd8 100644 --- a/src/transport/SocketUtil.h +++ b/src/transport/SocketUtil.h @@ -18,6 +18,7 @@ #define __SOCKET_UTIL_H__ #include + #include #ifndef WIN32 @@ -28,13 +29,15 @@ #pragma comment(lib, "ws2_32.lib") #endif +#include "ByteArray.h" + namespace rocketmq { static inline size_t sockaddr_size(const struct sockaddr* sa) { return sa->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); } -struct sockaddr* ipPort2SocketAddress(uint32_t host, uint16_t port); +struct sockaddr* ipPort2SocketAddress(const ByteArray& ip, uint16_t port); struct sockaddr* string2SocketAddress(const std::string& addr); std::string socketAddress2String(const struct sockaddr* addr); diff --git a/src/transport/TcpRemotingClient.cpp b/src/transport/TcpRemotingClient.cpp index 948eb0eb7..5691f58f2 100644 --- a/src/transport/TcpRemotingClient.cpp +++ b/src/transport/TcpRemotingClient.cpp @@ -16,10 +16,11 @@ */ #include "TcpRemotingClient.h" -#include +#include + +#include // std::move #include "Logging.h" -#include "MemoryOutputStream.h" #include "UtilAll.h" namespace rocketmq { @@ -232,7 +233,7 @@ std::unique_ptr TcpRemotingClient::invokeSync(const std::string CloseTransport(addr, channel); throw e; } catch (const RemotingTimeoutException& e) { - int code = request.getCode(); + int code = request.code(); if (code != GET_CONSUMER_LIST_BY_GROUP) { CloseTransport(addr, channel); LOG_WARN_NEW("invokeSync: close socket because of timeout, {}ms, {}", timeoutMillis, @@ -250,8 +251,8 @@ std::unique_ptr TcpRemotingClient::invokeSyncImpl( TcpTransportPtr channel, RemotingCommand& request, int64_t timeoutMillis) throw(RemotingTimeoutException, RemotingSendRequestException) { - int code = request.getCode(); - int opaque = request.getOpaque(); + int code = request.code(); + int opaque = request.opaque(); auto responseFuture = std::make_shared(code, opaque, timeoutMillis); putResponseFuture(channel, opaque, responseFuture); @@ -305,8 +306,8 @@ void TcpRemotingClient::invokeAsyncImpl(TcpTransportPtr channel, RemotingCommand& request, int64_t timeoutMillis, InvokeCallback* invokeCallback) throw(RemotingSendRequestException) { - int code = request.getCode(); - int opaque = request.getOpaque(); + int code = request.code(); + int opaque = request.opaque(); // delete in callback auto responseFuture = std::make_shared(code, opaque, timeoutMillis, invokeCallback); @@ -555,8 +556,8 @@ bool TcpRemotingClient::CloseNameServerTransport(TcpTransportPtr channel) { } bool TcpRemotingClient::SendCommand(TcpTransportPtr channel, RemotingCommand& msg) { - MemoryBlockPtr package(msg.encode()); - return channel->sendMessage(package->getData(), package->getSize()); + auto package = msg.encode(); + return channel->sendMessage(package->array(), package->size()); } void TcpRemotingClient::channelClosed(TcpTransportPtr channel) { @@ -564,15 +565,14 @@ void TcpRemotingClient::channelClosed(TcpTransportPtr channel) { m_handleExecutor.submit([channel] { static_cast(channel->getInfo())->activeAllResponses(); }); } -void TcpRemotingClient::messageReceived(MemoryBlockPtr mem, TcpTransportPtr channel) { - m_dispatchExecutor.submit( - std::bind(&TcpRemotingClient::processMessageReceived, this, MemoryBlockPtr2(std::move(mem)), channel)); +void TcpRemotingClient::messageReceived(ByteArrayRef msg, TcpTransportPtr channel) { + m_dispatchExecutor.submit(std::bind(&TcpRemotingClient::processMessageReceived, this, std::move(msg), channel)); } -void TcpRemotingClient::processMessageReceived(MemoryBlockPtr2 mem, TcpTransportPtr channel) { +void TcpRemotingClient::processMessageReceived(ByteArrayRef msg, TcpTransportPtr channel) { std::unique_ptr cmd; try { - cmd.reset(RemotingCommand::Decode(mem)); + cmd.reset(RemotingCommand::Decode(std::move(msg))); } catch (...) { LOG_ERROR_NEW("processMessageReceived error"); return; @@ -612,7 +612,7 @@ void TcpRemotingClient::processMessageReceived(MemoryBlockPtr2 mem, TcpTransport void TcpRemotingClient::processResponseCommand(std::unique_ptr responseCommand, TcpTransportPtr channel) { - int opaque = responseCommand->getOpaque(); + int opaque = responseCommand->opaque(); auto responseFuture = popResponseFuture(channel, opaque); if (responseFuture != nullptr) { int code = responseFuture->getRequestCode(); @@ -636,7 +636,7 @@ void TcpRemotingClient::processRequestCommand(std::unique_ptr r TcpTransportPtr channel) { std::unique_ptr response; - int requestCode = requestCommand->getCode(); + int requestCode = requestCommand->code(); const auto& it = m_processorTable.find(requestCode); if (it != m_processorTable.end()) { try { @@ -653,14 +653,14 @@ void TcpRemotingClient::processRequestCommand(std::unique_ptr r } } else { // send REQUEST_CODE_NOT_SUPPORTED response - std::string error = "request type " + UtilAll::to_string(requestCommand->getCode()) + " not supported"; + std::string error = "request type " + UtilAll::to_string(requestCommand->code()) + " not supported"; response.reset(new RemotingCommand(REQUEST_CODE_NOT_SUPPORTED, error)); LOG_ERROR_NEW("{}: {}", channel->getPeerAddrAndPort(), error); } if (!requestCommand->isOnewayRPC() && response != nullptr) { - response->setOpaque(requestCommand->getOpaque()); + response->set_opaque(requestCommand->opaque()); response->markResponseType(); try { if (!SendCommand(channel, *response)) { diff --git a/src/transport/TcpRemotingClient.h b/src/transport/TcpRemotingClient.h index e06f7ab76..f1937149e 100755 --- a/src/transport/TcpRemotingClient.h +++ b/src/transport/TcpRemotingClient.h @@ -66,8 +66,8 @@ class TcpRemotingClient { void channelClosed(TcpTransportPtr channel); - void messageReceived(MemoryBlockPtr mem, TcpTransportPtr channel); - void processMessageReceived(MemoryBlockPtr2 mem, TcpTransportPtr channel); + void messageReceived(ByteArrayRef msg, TcpTransportPtr channel); + void processMessageReceived(ByteArrayRef msg, TcpTransportPtr channel); void processRequestCommand(std::unique_ptr cmd, TcpTransportPtr channel); void processResponseCommand(std::unique_ptr cmd, TcpTransportPtr channel); diff --git a/src/transport/TcpTransport.cpp b/src/transport/TcpTransport.cpp index 770bb436b..15cfa9dd4 100644 --- a/src/transport/TcpTransport.cpp +++ b/src/transport/TcpTransport.cpp @@ -229,7 +229,7 @@ void TcpTransport::dataArrived(BufferEvent& event) { return; } - uint32_t msgLen = ByteOrder::swapIfLittleEndian(packageLength); // same as ntohl() + uint32_t msgLen = ByteOrderUtil::NorminalBigEndian(packageLength); // same as ntohl() size_t recvLen = evbuffer_get_length(input); if (recvLen >= msgLen + 4) { LOG_DEBUG_NEW("had received all data. msgLen:{}, from:{}, recvLen:{}", msgLen, event.getfd(), recvLen); @@ -239,19 +239,19 @@ void TcpTransport::dataArrived(BufferEvent& event) { } if (msgLen > 0) { - MemoryBlockPtr msg(new MemoryPool(msgLen, true)); + auto msg = std::make_shared(msgLen); event.read(&packageLength, 4); // skip length field - event.read(msg->getData(), msgLen); + event.read(msg->array(), msgLen); messageReceived(std::move(msg)); } } } -void TcpTransport::messageReceived(MemoryBlockPtr mem) { +void TcpTransport::messageReceived(ByteArrayRef msg) { if (m_readCallback != nullptr) { - m_readCallback(std::move(mem), shared_from_this()); + m_readCallback(std::move(msg), shared_from_this()); } } diff --git a/src/transport/TcpTransport.h b/src/transport/TcpTransport.h index 5a1ccb7ff..cffe2e9de 100755 --- a/src/transport/TcpTransport.h +++ b/src/transport/TcpTransport.h @@ -21,7 +21,7 @@ #include #include -#include "DataBlock.h" +#include "ByteArray.h" #include "EventLoop.h" namespace rocketmq { @@ -44,7 +44,7 @@ class TcpTransportInfo { class TcpTransport : public noncopyable, public std::enable_shared_from_this { public: - typedef std::function ReadCallback; + typedef std::function ReadCallback; typedef std::function CloseCallback; public: @@ -76,7 +76,7 @@ class TcpTransport : public noncopyable, public std::enable_shared_from_this -#include - -#include - -#include "big_endian.h" - -using testing::InitGoogleMock; -using testing::InitGoogleTest; -using testing::Return; - -using rocketmq::BigEndianReader; -using rocketmq::BigEndianWriter; - -TEST(BigEndianTest, BigEndianObject) { - char buf[32]; - - BigEndianWriter writer(buf, 32); - BigEndianReader reader(buf, 32); - - uint64_t uint64[1]; - EXPECT_TRUE(writer.WriteU64((uint64_t)0x1234567890ABCDEF)); - EXPECT_EQ(*(uint64_t*)reader.ptr(), 0xEFCDAB9078563412); - EXPECT_TRUE(reader.ReadU64(uint64)); - EXPECT_EQ(*uint64, 0x1234567890ABCDEF); - - uint32_t uint32[1]; - EXPECT_TRUE(writer.WriteU32((uint32_t)0x12345678)); - EXPECT_EQ(*(uint32_t*)reader.ptr(), 0x78563412); - EXPECT_TRUE(reader.ReadU32(uint32)); - EXPECT_EQ(*uint32, 0x12345678); - - uint16_t uint16[1]; - EXPECT_TRUE(writer.WriteU16((uint16_t)0x1234)); - EXPECT_EQ(*(uint16_t*)reader.ptr(), 0x3412); - EXPECT_TRUE(reader.ReadU16(uint16)); - EXPECT_EQ(*uint16, 0x1234); - - uint8_t uint8[1]; - EXPECT_TRUE(writer.WriteU8((uint8_t)0x12)); - EXPECT_EQ(*(uint8_t*)reader.ptr(), 0x12); - EXPECT_TRUE(reader.ReadU8(uint8)); - EXPECT_EQ(*uint8, 0x12); - - char str[] = "RocketMQ"; - char str2[sizeof(str)]; - EXPECT_TRUE(writer.WriteBytes(str, sizeof(str) - 1)); - EXPECT_TRUE(strncmp(reader.ptr(), str, sizeof(str) - 1) == 0); - EXPECT_TRUE(reader.ReadBytes(str2, sizeof(str) - 1)); - EXPECT_TRUE(strncmp(str2, str, sizeof(str) - 1) == 0); -} - -TEST(BigEndianTest, BigEndian) { - char buf[8]; - - rocketmq::WriteBigEndian(buf, (uint8_t)0x12); - EXPECT_EQ(*(uint8_t*)buf, 0x12); - - uint8_t out[1]; - rocketmq::ReadBigEndian(buf, out); - EXPECT_EQ(*out, 0x12); -} - -int main(int argc, char* argv[]) { - InitGoogleMock(&argc, argv); - testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "BigEndianTest.*"; - return RUN_ALL_TESTS(); -} diff --git a/test/src/common/ClientRPCHookTest.cpp b/test/src/common/ClientRPCHookTest.cpp index 0d22c9361..02ce84343 100644 --- a/test/src/common/ClientRPCHookTest.cpp +++ b/test/src/common/ClientRPCHookTest.cpp @@ -50,7 +50,7 @@ TEST(ClientRPCHookTest, BeforeRequest) { RemotingCommand sendRequestCommand(MQRequestCode::UPDATE_AND_CREATE_TOPIC, sendMessageRequestHeader); clientRPCHook.doBeforeRequest("127.0.0.1:9876", sendRequestCommand, true); - sendRequestCommand.setBody("1231231"); + sendRequestCommand.set_body("1231231"); clientRPCHook.doBeforeRequest("127.0.0.1:9876", sendRequestCommand, true); } diff --git a/test/src/common/MemoryBlockTest.cpp b/test/src/common/MemoryBlockTest.cpp deleted file mode 100644 index fc8d0ec9a..000000000 --- a/test/src/common/MemoryBlockTest.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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 -#include - -#include - -#include "DataBlock.h" - -using testing::InitGoogleMock; -using testing::InitGoogleTest; -using testing::Return; - -using rocketmq::MemoryBlock; -using rocketmq::MemoryPool; - -TEST(MemoryBlockTest, Init) { - MemoryBlock memoryBlock; - EXPECT_EQ(memoryBlock.getSize(), 0); - EXPECT_TRUE(memoryBlock.getData() == nullptr); - - MemoryPool twoMemoryBlock(0, true); - EXPECT_EQ(twoMemoryBlock.getSize(), 0); - EXPECT_TRUE(twoMemoryBlock.getData() == nullptr); - - MemoryPool threeMemoryBlock(10, true); - EXPECT_EQ(threeMemoryBlock.getSize(), 10); - EXPECT_TRUE(threeMemoryBlock.getData() != nullptr); - - MemoryPool frouMemoryBlock(12, false); - EXPECT_EQ(frouMemoryBlock.getSize(), 12); - EXPECT_TRUE(frouMemoryBlock.getData() != nullptr); - - char buf[] = "RocketMQ"; - MemoryPool fiveMemoryBlock(buf, 0); - EXPECT_EQ(fiveMemoryBlock.getSize(), 0); - EXPECT_TRUE(fiveMemoryBlock.getData() == nullptr); - - MemoryPool sixMemoryBlock(nullptr, 16); - EXPECT_EQ(sixMemoryBlock.getSize(), 16); - EXPECT_TRUE(sixMemoryBlock.getData() != nullptr); - - MemoryPool sevenMemoryBlock(buf, sizeof(buf) - 1); - EXPECT_EQ(sevenMemoryBlock.getSize(), sizeof(buf) - 1); - EXPECT_EQ((std::string)sevenMemoryBlock, buf); - - MemoryPool nineMemoryBlock(sevenMemoryBlock); - EXPECT_EQ(nineMemoryBlock.getSize(), sevenMemoryBlock.getSize()); - EXPECT_EQ(nineMemoryBlock, sevenMemoryBlock); - - MemoryPool eightMemoryBlock(fiveMemoryBlock); - EXPECT_EQ(eightMemoryBlock.getSize(), fiveMemoryBlock.getSize()); - EXPECT_TRUE(eightMemoryBlock.getData() == nullptr); -} - -TEST(MemoryBlockTest, Operators) { - MemoryPool memoryBlock(8, false); - - MemoryPool operaterMemoryBlock = memoryBlock; - EXPECT_TRUE(operaterMemoryBlock == memoryBlock); - - char buf[] = "RocketMQ"; - MemoryPool twoMemoryBlock(buf, sizeof(buf) - 1); - EXPECT_FALSE(memoryBlock == twoMemoryBlock); - - MemoryPool threeMemoryBlock(buf, 7); - EXPECT_FALSE(memoryBlock == threeMemoryBlock); - EXPECT_TRUE(twoMemoryBlock != threeMemoryBlock); - - threeMemoryBlock.fillWith(49); - EXPECT_EQ((std::string)threeMemoryBlock, "1111111"); - - threeMemoryBlock.reset(); - EXPECT_EQ(threeMemoryBlock.getSize(), 0); - EXPECT_TRUE(threeMemoryBlock.getData() == nullptr); - - threeMemoryBlock.setSize(16, false); - EXPECT_EQ(threeMemoryBlock.getSize(), 16); - - threeMemoryBlock.setSize(0, false); - EXPECT_EQ(threeMemoryBlock.getSize(), 0); - EXPECT_TRUE(threeMemoryBlock.getData() == nullptr); - - MemoryPool appendMemoryBlock; - EXPECT_EQ(appendMemoryBlock.getSize(), 0); - EXPECT_TRUE(appendMemoryBlock.getData() == nullptr); - - appendMemoryBlock.append(buf, 0); - EXPECT_EQ(appendMemoryBlock.getSize(), 0); - EXPECT_TRUE(appendMemoryBlock.getData() == nullptr); - - appendMemoryBlock.append(buf, sizeof(buf) - 1); - EXPECT_EQ(appendMemoryBlock.getSize(), 8); - - MemoryPool replaceWithMemoryBlock; - replaceWithMemoryBlock.append(buf, sizeof(buf) - 1); - - char aliyunBuf[] = "aliyun"; - replaceWithMemoryBlock.replaceWith(aliyunBuf, 0); - EXPECT_EQ(replaceWithMemoryBlock.getSize(), 8); - EXPECT_EQ((std::string)replaceWithMemoryBlock, "RocketMQ"); - - replaceWithMemoryBlock.replaceWith(aliyunBuf, sizeof(aliyunBuf) - 1); - EXPECT_EQ(replaceWithMemoryBlock.getSize(), 6); - EXPECT_EQ((std::string)replaceWithMemoryBlock, "aliyun"); - - MemoryPool insertMemoryBlock; - insertMemoryBlock.append(buf, sizeof(buf) - 1); - insertMemoryBlock.insert(aliyunBuf, 0, 0); - EXPECT_EQ((std::string)insertMemoryBlock, "RocketMQ"); - - MemoryPool twoInsertMemoryBlock; - twoInsertMemoryBlock.append(buf, sizeof(buf) - 1); - twoInsertMemoryBlock.insert(aliyunBuf, sizeof(aliyunBuf) - 1, 0); - EXPECT_EQ((std::string)twoInsertMemoryBlock, "aliyunRocketMQ"); - - MemoryPool threeInsertMemoryBlock; - threeInsertMemoryBlock.append(buf, sizeof(buf) - 1); - threeInsertMemoryBlock.insert(aliyunBuf, sizeof(aliyunBuf) - 1, 100); - EXPECT_EQ((std::string)threeInsertMemoryBlock, "RocketMQaliyun"); - - MemoryPool removeSectionMemoryBlock(buf, sizeof(buf) - 1); - removeSectionMemoryBlock.removeSection(8, 0); - EXPECT_EQ((std::string)removeSectionMemoryBlock, "RocketMQ"); - - MemoryPool twoRemoveSectionMemoryBlock(buf, sizeof(buf) - 1); - twoRemoveSectionMemoryBlock.removeSection(1, 4); - EXPECT_EQ((std::string)twoRemoveSectionMemoryBlock, "RtMQ"); -} - -int main(int argc, char* argv[]) { - InitGoogleMock(&argc, argv); - testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "MemoryBlockTest.*"; - return RUN_ALL_TESTS(); -} diff --git a/test/src/common/MemoryOutputStreamTest.cpp b/test/src/common/MemoryOutputStreamTest.cpp deleted file mode 100644 index 80218cffe..000000000 --- a/test/src/common/MemoryOutputStreamTest.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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 -#include - -#include "DataBlock.h" -#include "MemoryInputStream.h" -#include "MemoryOutputStream.h" - -using testing::InitGoogleMock; -using testing::InitGoogleTest; -using testing::Return; - -using rocketmq::MemoryBlock; -using rocketmq::MemoryInputStream; -using rocketmq::MemoryOutputStream; -using rocketmq::MemoryPool; - -TEST(MemoryOutputStreamTest, Init) { - MemoryOutputStream memoryOutput; - EXPECT_EQ(memoryOutput.getMemoryBlock().getSize(), 0); - EXPECT_TRUE(memoryOutput.getData() != nullptr); - - EXPECT_EQ(memoryOutput.getPosition(), 0); - EXPECT_EQ(memoryOutput.getDataSize(), 0); - - MemoryOutputStream twoMemoryOutput(512); - EXPECT_EQ(memoryOutput.getMemoryBlock().getSize(), 0); - - MemoryPool memoryBlock(12, false); - MemoryOutputStream threeMemoryOutput(memoryBlock, false); - EXPECT_EQ(threeMemoryOutput.getPosition(), 0); - EXPECT_EQ(threeMemoryOutput.getDataSize(), 0); - - MemoryOutputStream frouMemoryOutput(memoryBlock, true); - EXPECT_EQ(frouMemoryOutput.getPosition(), memoryBlock.getSize()); - EXPECT_EQ(frouMemoryOutput.getDataSize(), memoryBlock.getSize()); - - char buf[] = "RocketMQ"; - MemoryOutputStream fiveMemoryOutputStream(buf, sizeof(buf)); - EXPECT_EQ(fiveMemoryOutputStream.getData(), buf); - - fiveMemoryOutputStream.reset(); - EXPECT_EQ(memoryOutput.getPosition(), 0); - EXPECT_EQ(memoryOutput.getDataSize(), 0); -} - -TEST(MemoryOutputStreamTest, Flush) { - char buf[] = "RocketMQ"; - MemoryOutputStream memoryOutput; - memoryOutput.write(buf, sizeof(buf) - 1); - memoryOutput.flush(); - EXPECT_FALSE(memoryOutput.getData() == buf); -} - -TEST(MemoryOutputStreamTest, Preallocate) { - MemoryOutputStream memoryOutput; - - // TODO: - memoryOutput.preallocate(250); - - memoryOutput.preallocate(256); -} - -TEST(MemoryOutputStreamTest, GetMemoryBlock) { - char buf[] = "RocketMQ"; - MemoryOutputStream memoryOutput; - memoryOutput.write(buf, sizeof(buf) - 1); - MemoryPool memoryBlock = memoryOutput.getMemoryBlock(); - EXPECT_EQ(memoryBlock.getSize(), memoryOutput.getDataSize()); -} - -TEST(MemoryOutputStreamTest, PrepareToWriteAndGetData) { - char buf[] = "RocketMQ"; - MemoryOutputStream memoryOutput(buf, sizeof(buf)); - EXPECT_EQ(memoryOutput.getData(), buf); - - // prepareToWrite - // EXPECT_TRUE(memoryOutput.writeIntBigEndian(123)); - EXPECT_TRUE(memoryOutput.writeByte('r')); - EXPECT_STREQ(static_cast(memoryOutput.getData()), "rocketMQ"); - - MemoryOutputStream blockMmoryOutput(8); - auto* memoryData = static_cast(blockMmoryOutput.getData()); - EXPECT_EQ(memoryData[blockMmoryOutput.getDataSize()], 0); - - blockMmoryOutput.write(buf, 8); - blockMmoryOutput.write(buf, 8); - auto* data = static_cast(blockMmoryOutput.getData()); - EXPECT_STREQ(data, "rocketMQrocketMQ"); -} - -TEST(MemoryOutputStreamTest, Position) { - char buf[] = "RocketMQ"; - - MemoryOutputStream memoryOutput; - EXPECT_EQ(memoryOutput.getPosition(), 0); - - memoryOutput.write(buf, sizeof(buf) - 1); - EXPECT_EQ(memoryOutput.getPosition(), 8); - - EXPECT_FALSE(memoryOutput.setPosition(9)); - - EXPECT_TRUE(memoryOutput.setPosition(-1)); - EXPECT_EQ(memoryOutput.getPosition(), 0); - - EXPECT_TRUE(memoryOutput.setPosition(8)); - EXPECT_EQ(memoryOutput.getPosition(), 8); - - EXPECT_TRUE(memoryOutput.setPosition(7)); - EXPECT_EQ(memoryOutput.getPosition(), 7); -} - -TEST(MemoryOutputStreamTest, Write) { - MemoryOutputStream memoryOutput; - MemoryInputStream memoryInput(memoryOutput.getData(), 256, false); - - EXPECT_TRUE(memoryOutput.writeBool(true)); - EXPECT_TRUE(memoryInput.readBool()); - - EXPECT_TRUE(memoryOutput.writeBool(false)); - EXPECT_FALSE(memoryInput.readBool()); - - EXPECT_TRUE(memoryOutput.writeByte('a')); - EXPECT_EQ(memoryInput.readByte(), 'a'); - - EXPECT_TRUE(memoryOutput.writeShortBigEndian(128)); - EXPECT_EQ(memoryInput.readShortBigEndian(), 128); - - EXPECT_TRUE(memoryOutput.writeIntBigEndian(123)); - EXPECT_EQ(memoryInput.readIntBigEndian(), 123); - - EXPECT_TRUE(memoryOutput.writeInt64BigEndian(123123)); - EXPECT_EQ(memoryInput.readInt64BigEndian(), 123123); - - EXPECT_TRUE(memoryOutput.writeDoubleBigEndian(12.71)); - EXPECT_EQ(memoryInput.readDoubleBigEndian(), 12.71); - - EXPECT_TRUE(memoryOutput.writeFloatBigEndian(12.1)); - float f = 12.1; - EXPECT_EQ(memoryInput.readFloatBigEndian(), f); -} - -TEST(MemoryInputStreamTest, Info) { - char buf[] = "RocketMQ"; - - MemoryInputStream memoryInput(buf, sizeof(buf) - 1, false); - EXPECT_EQ(memoryInput.getData(), buf); - EXPECT_EQ(memoryInput.getTotalLength(), 8); - - MemoryInputStream twoMemoryInput(buf, sizeof(buf) - 1, true); - EXPECT_NE(twoMemoryInput.getData(), buf); - - MemoryBlock memoryBlock(buf, sizeof(buf) - 1); - MemoryInputStream threeMemoryInput(memoryBlock, false); - EXPECT_EQ(threeMemoryInput.getData(), memoryBlock.getData()); - EXPECT_EQ(threeMemoryInput.getTotalLength(), 8); - - MemoryInputStream frouMemoryInput(memoryBlock, true); - EXPECT_NE(frouMemoryInput.getData(), memoryBlock.getData()); -} - -TEST(MemoryInputStreamTest, Position) { - char buf[] = "RocketMQ"; - - MemoryInputStream memoryInput(buf, sizeof(buf) - 1, false); - EXPECT_EQ(memoryInput.getPosition(), 0); - EXPECT_FALSE(memoryInput.isExhausted()); - - memoryInput.setPosition(9); - EXPECT_EQ(memoryInput.getPosition(), 8); - EXPECT_TRUE(memoryInput.isExhausted()); - - memoryInput.setPosition(-1); - EXPECT_EQ(memoryInput.getPosition(), 0); -} - -int main(int argc, char* argv[]) { - InitGoogleMock(&argc, argv); - testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "*.*"; - return RUN_ALL_TESTS(); -} diff --git a/test/src/extern/CProducerTest.cpp b/test/src/extern/CProducerTest.cpp index 5c97043eb..17ed7c602 100644 --- a/test/src/extern/CProducerTest.cpp +++ b/test/src/extern/CProducerTest.cpp @@ -49,10 +49,10 @@ class MockDefaultMQProducer : public DefaultMQProducer { MOCK_METHOD(void, start, (), (override)); MOCK_METHOD(void, shutdown, (), (override)); - MOCK_METHOD(SendResult, send, (MQMessage*), (override)); - MOCK_METHOD(void, send, (MQMessage*, SendCallback*), (noexcept, override)); - MOCK_METHOD(SendResult, send, (MQMessage*, MessageQueueSelector*, void*, long), (override)); - MOCK_METHOD(void, sendOneway, (MQMessage*), (override)); + MOCK_METHOD(SendResult, send, (MQMessage&), (override)); + MOCK_METHOD(void, send, (MQMessage&, SendCallback*), (noexcept, override)); + MOCK_METHOD(SendResult, send, (MQMessage&, MessageQueueSelector*, void*, long), (override)); + MOCK_METHOD(void, sendOneway, (MQMessage&), (override)); }; void CSendSuccessCallbackFunc(CSendResult result) {} diff --git a/test/src/extern/CPullConsumerTest.cpp b/test/src/extern/CPullConsumerTest.cpp index a356a5774..2297779e3 100644 --- a/test/src/extern/CPullConsumerTest.cpp +++ b/test/src/extern/CPullConsumerTest.cpp @@ -22,7 +22,7 @@ #include "DefaultMQPullConsumer.h" #include "MQClientInstance.h" -#include "MQMessageExt.h" +#include "MessageExtImpl.h" #include "MQMessageQueue.h" #include "PullResult.h" #include "SessionCredentials.h" @@ -39,7 +39,8 @@ using testing::SetArgReferee; using rocketmq::DefaultMQPullConsumer; using rocketmq::MessageModel; -using rocketmq::MQMessageExt; +using rocketmq::MessageExtPtr; +using rocketmq::MessageClientExtImpl; using rocketmq::MQMessageQueue; using rocketmq::PullResult; using rocketmq::PullStatus; @@ -70,9 +71,9 @@ TEST(CPullConsumerTest, Pull) { PullResult offsetIllegalPullResult(PullStatus::OFFSET_ILLEGAL, 1, 2, 3); PullResult defaultPullResult((PullStatus)-1, 1, 2, 3); - std::vector> src; + std::vector src; for (int i = 0; i < 5; i++) { - auto ext = std::make_shared(); + auto ext = std::make_shared(); src.push_back(ext); } PullResult foundPullResult(PullStatus::FOUND, 1, 2, 3, src); diff --git a/test/src/message/MQMessageExtTest.cpp b/test/src/message/MQMessageExtTest.cpp index 86a28aae0..400d90008 100644 --- a/test/src/message/MQMessageExtTest.cpp +++ b/test/src/message/MQMessageExtTest.cpp @@ -18,6 +18,7 @@ #include #include "MQMessageExt.h" +#include "MessageExtImpl.h" #include "MessageSysFlag.h" #include "SocketUtil.h" #include "TopicFilterType.h" @@ -26,14 +27,15 @@ using testing::InitGoogleMock; using testing::InitGoogleTest; using testing::Return; +using rocketmq::MessageClientExtImpl; +using rocketmq::MessageExtImpl; using rocketmq::MessageSysFlag; -using rocketmq::MQMessageClientExt; using rocketmq::MQMessageConst; using rocketmq::MQMessageExt; using rocketmq::TopicFilterType; -TEST(MessageExtTest, MessageClientExt) { - MQMessageClientExt messageClientExt; +TEST(MessageExtTest, MessageClientExtImpl) { + MessageClientExtImpl messageClientExt; EXPECT_EQ(messageClientExt.getQueueOffset(), 0); EXPECT_EQ(messageClientExt.getCommitLogOffset(), 0); EXPECT_EQ(messageClientExt.getBornTimestamp(), 0); @@ -117,8 +119,8 @@ TEST(MessageExtTest, MessageExt) { } TEST(MessageExtTest, ParseTopicFilterType) { - EXPECT_EQ(MQMessageExt::parseTopicFilterType(MessageSysFlag::MultiTagsFlag), TopicFilterType::MULTI_TAG); - EXPECT_EQ(MQMessageExt::parseTopicFilterType(0), TopicFilterType::SINGLE_TAG); + EXPECT_EQ(MessageExtImpl::parseTopicFilterType(MessageSysFlag::MULTI_TAGS_FLAG), TopicFilterType::MULTI_TAG); + EXPECT_EQ(MessageExtImpl::parseTopicFilterType(0), TopicFilterType::SINGLE_TAG); } int main(int argc, char* argv[]) { diff --git a/test/src/message/MQMessageTest.cpp b/test/src/message/MQMessageTest.cpp index bea6ae268..515e384ed 100644 --- a/test/src/message/MQMessageTest.cpp +++ b/test/src/message/MQMessageTest.cpp @@ -85,10 +85,6 @@ TEST(MessageTest, GetterAndSetter) { message.setBody("testBody"); EXPECT_EQ(message.getBody(), "testBody"); - const char* body = "testBody"; - message.setBody(body, 5); - EXPECT_EQ(message.getBody(), "testB"); - EXPECT_EQ(message.getTags(), ""); // default message.setTags("testTags"); EXPECT_EQ(message.getTags(), "testTags"); diff --git a/test/src/message/MessageBatchTest.cpp b/test/src/message/MessageBatchTest.cpp index 7d84592d3..8e61c4df7 100644 --- a/test/src/message/MessageBatchTest.cpp +++ b/test/src/message/MessageBatchTest.cpp @@ -30,6 +30,7 @@ using testing::Return; using rocketmq::MessageBatch; using rocketmq::MessageDecoder; using rocketmq::MQMessage; +using rocketmq::stoba; TEST(MessageBatchTest, Encode) { std::vector msgs; diff --git a/test/src/message/MessageDecoderTest.cpp b/test/src/message/MessageDecoderTest.cpp index 5acfc8148..8f15e02e5 100644 --- a/test/src/message/MessageDecoderTest.cpp +++ b/test/src/message/MessageDecoderTest.cpp @@ -17,18 +17,17 @@ #include #include -#include #include #include +#include "ByteArray.h" +#include "ByteBuffer.hpp" #include "MessageDecoder.h" #include "MQMessage.h" #include "MQMessageConst.h" #include "MQMessageExt.h" #include "MessageId.h" -#include "MemoryInputStream.h" -#include "MemoryOutputStream.h" #include "MessageSysFlag.h" #include "RemotingCommand.h" #include "UtilAll.h" @@ -38,9 +37,8 @@ using testing::InitGoogleMock; using testing::InitGoogleTest; using testing::Return; -using rocketmq::MemoryBlock; -using rocketmq::MemoryInputStream; -using rocketmq::MemoryOutputStream; +using rocketmq::ByteArray; +using rocketmq::ByteBuffer; using rocketmq::MessageSysFlag; using rocketmq::MessageDecoder; using rocketmq::MQMessage; @@ -49,124 +47,134 @@ using rocketmq::MQMessageExt; using rocketmq::MessageId; using rocketmq::RemotingCommand; using rocketmq::SendMessageRequestHeader; +using rocketmq::stoba; using rocketmq::UtilAll; // TODO TEST(MessageDecoderTest, MessageId) { std::string strMsgId = MessageDecoder::createMessageId(rocketmq::string2SocketAddress("127.0.0.1:10091"), 1024LL); - EXPECT_EQ(strMsgId, "0100007F0000276B0000000000000400"); + EXPECT_EQ(strMsgId, "7F0000010000276B0000000000000400"); MessageId msgId = MessageDecoder::decodeMessageId(strMsgId); - EXPECT_EQ(msgId.getOffset(), 1024); + EXPECT_EQ(msgId.getOffset(), 1024LL); + + std::string strMsgId2 = MessageDecoder::createMessageId(rocketmq::string2SocketAddress("/172.16.2.114:0"), 123456LL); + EXPECT_EQ(strMsgId2, "AC10027200000000000000000001E240"); + + MessageId msgId2 = MessageDecoder::decodeMessageId(strMsgId2); + EXPECT_EQ(msgId2.getOffset(), 123456LL); } TEST(MessageDecoderTest, Decode) { - MemoryOutputStream* memoryOut = new MemoryOutputStream(1024); + std::unique_ptr byteBuffer(ByteBuffer::allocate(1024)); MQMessageExt msgExt; // 1 TOTALSIZE 4=0+4 - memoryOut->writeIntBigEndian(111); + byteBuffer->putInt(111); msgExt.setStoreSize(111); // 2 MAGICCODE sizeof(int) 8=4+4 - memoryOut->writeIntBigEndian(14); + byteBuffer->putInt(14); // 3 BODYCRC 12=8+4 - memoryOut->writeIntBigEndian(24); + byteBuffer->putInt(24); msgExt.setBodyCRC(24); // 4 QUEUEID 16=12+4 - memoryOut->writeIntBigEndian(4); + byteBuffer->putInt(4); msgExt.setQueueId(4); // 5 FLAG 20=16+4 - memoryOut->writeIntBigEndian(4); + byteBuffer->putInt(4); msgExt.setFlag(4); // 6 QUEUEOFFSET 28=20+8 - memoryOut->writeInt64BigEndian(1024LL); + byteBuffer->putLong(1024LL); msgExt.setQueueOffset(1024LL); // 7 PHYSICALOFFSET 36=28+8 - memoryOut->writeInt64BigEndian(2048LL); + byteBuffer->putLong(2048LL); msgExt.setCommitLogOffset(2048LL); // 8 SYSFLAG 40=36+4 - memoryOut->writeIntBigEndian(0); + byteBuffer->putInt(0); msgExt.setSysFlag(0); // 9 BORNTIMESTAMP 48=40+8 - memoryOut->writeInt64BigEndian(4096LL); + byteBuffer->putLong(4096LL); msgExt.setBornTimestamp(4096LL); // 10 BORNHOST 56=48+4+4 - memoryOut->writeIntBigEndian(ntohl(inet_addr("127.0.0.1"))); - memoryOut->writeIntBigEndian(10091); + byteBuffer->putInt(ntohl(inet_addr("127.0.0.1"))); + byteBuffer->putInt(10091); msgExt.setBornHost(rocketmq::string2SocketAddress("127.0.0.1:10091")); // 11 STORETIMESTAMP 64=56+8 - memoryOut->writeInt64BigEndian(4096LL); + byteBuffer->putLong(4096LL); msgExt.setStoreTimestamp(4096LL); // 12 STOREHOST 72=64+4+4 - memoryOut->writeIntBigEndian(ntohl(inet_addr("127.0.0.2"))); - memoryOut->writeIntBigEndian(10092); + byteBuffer->putInt(ntohl(inet_addr("127.0.0.2"))); + byteBuffer->putInt(10092); msgExt.setStoreHost(rocketmq::string2SocketAddress("127.0.0.2:10092")); // 13 RECONSUMETIMES 76=72+4 - memoryOut->writeIntBigEndian(18); + byteBuffer->putInt(18); msgExt.setReconsumeTimes(18); // 14 Prepared Transaction Offset 84=76+8 - memoryOut->writeInt64BigEndian(12LL); + byteBuffer->putLong(12LL); msgExt.setPreparedTransactionOffset(12LL); // 15 BODY 98=84+4+10 - std::string body = "1234567890"; - memoryOut->writeIntBigEndian(body.size()); - memoryOut->write(body.data(), body.size()); + std::string body("1234567890"); + byteBuffer->putInt(body.size()); + byteBuffer->put(*stoba(body)); msgExt.setBody(body); // 16 TOPIC 109=98+1+10 std::string topic = "topic_1234"; - memoryOut->writeByte(topic.size()); - memoryOut->write(topic.data(), topic.size()); + byteBuffer->put((int8_t)topic.size()); + byteBuffer->put(*stoba(topic)); msgExt.setTopic(topic); // 17 PROPERTIES 111=109+2 - memoryOut->writeShortBigEndian(0); + byteBuffer->putShort(0); msgExt.setMsgId(MessageDecoder::createMessageId(msgExt.getStoreHost(), (int64_t)msgExt.getCommitLogOffset())); - auto block = memoryOut->getMemoryBlock(); - auto msgs = MessageDecoder::decodes(*static_cast(&block)); + byteBuffer->flip(); + auto msgs = MessageDecoder::decodes(*byteBuffer); EXPECT_EQ(msgs.size(), 1); std::cout << msgs[0]->toString() << std::endl; std::cout << msgExt.toString() << std::endl; EXPECT_EQ(msgs[0]->toString(), msgExt.toString()); - msgs = MessageDecoder::decodes(*static_cast(&block), false); - EXPECT_EQ(msgs[0]->getBody().size(), 0); + byteBuffer->rewind(); + msgs = MessageDecoder::decodes(*byteBuffer, false); + EXPECT_EQ(msgs[0]->getBody(), ""); //=============================================================== + byteBuffer->clear(); + // 8 SYSFLAG 40=36+4 - memoryOut->setPosition(36); - memoryOut->writeIntBigEndian(0 | MessageSysFlag::CompressedFlag); - msgExt.setSysFlag(0 | MessageSysFlag::CompressedFlag); + byteBuffer->position(36); + byteBuffer->putInt(0 | MessageSysFlag::COMPRESSED_FLAG); + msgExt.setSysFlag(0 | MessageSysFlag::COMPRESSED_FLAG); // 15 Body 84 std::string compressedBody; UtilAll::deflate(body, compressedBody, 5); - memoryOut->setPosition(84); - memoryOut->writeIntBigEndian(compressedBody.size()); - memoryOut->write(compressedBody.data(), compressedBody.size()); + byteBuffer->position(84); + byteBuffer->putInt(compressedBody.size()); + byteBuffer->put(*stoba(compressedBody)); msgExt.setBody(compressedBody); // 16 TOPIC - memoryOut->writeByte(topic.size()); - memoryOut->write(topic.data(), topic.size()); + byteBuffer->put((int8_t)topic.size()); + byteBuffer->put(*stoba(topic)); msgExt.setTopic(topic); // 17 PROPERTIES @@ -174,17 +182,18 @@ TEST(MessageDecoderTest, Decode) { properties["RocketMQ"] = "cpp-client"; properties[MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX] = "123456"; std::string props = MessageDecoder::messageProperties2String(properties); - memoryOut->writeShortBigEndian(props.size()); - memoryOut->write(props.data(), props.size()); + byteBuffer->putShort(props.size()); + byteBuffer->put(*stoba(props)); msgExt.setProperties(properties); msgExt.setMsgId("123456"); - memoryOut->setPosition(0); - memoryOut->writeIntBigEndian(memoryOut->getDataSize()); - msgExt.setStoreSize(memoryOut->getDataSize()); + byteBuffer->flip(); + + byteBuffer->putInt(byteBuffer->limit()); + msgExt.setStoreSize(byteBuffer->limit()); - block = memoryOut->getMemoryBlock(); - msgs = MessageDecoder::decodes(*static_cast(&block)); + byteBuffer->rewind(); + msgs = MessageDecoder::decodes(*byteBuffer); EXPECT_EQ(msgs[0]->toString(), msgExt.toString()); } diff --git a/test/src/protocol/CommandHeaderTest.cpp b/test/src/protocol/CommandHeaderTest.cpp index 37ed24167..502ab29ba 100644 --- a/test/src/protocol/CommandHeaderTest.cpp +++ b/test/src/protocol/CommandHeaderTest.cpp @@ -24,7 +24,7 @@ #include #include -#include "DataBlock.h" +#include "ByteArray.h" #include "MQClientException.h" #include "MessageSysFlag.h" #include "UtilAll.h" @@ -37,6 +37,7 @@ using testing::Return; using Json::FastWriter; using Json::Value; +using rocketmq::ByteArray; using rocketmq::CommandCustomHeader; using rocketmq::ConsumerSendMsgBackRequestHeader; using rocketmq::CreateTopicRequestHeader; @@ -51,8 +52,6 @@ using rocketmq::GetMaxOffsetResponseHeader; using rocketmq::GetMinOffsetRequestHeader; using rocketmq::GetMinOffsetResponseHeader; using rocketmq::GetRouteInfoRequestHeader; -using rocketmq::MemoryBlock; -using rocketmq::MemoryView; using rocketmq::NotifyConsumerIdsChangedRequestHeader; using rocketmq::PullMessageRequestHeader; using rocketmq::PullMessageResponseHeader; @@ -80,8 +79,8 @@ TEST(CommandHeaderTest, GetConsumerListByGroupResponseBody) { FastWriter writer; std::string data = writer.write(root); - std::unique_ptr mem(new MemoryBlock(const_cast(data.data()), data.size())); - std::unique_ptr body(GetConsumerListByGroupResponseBody::Decode(*mem)); + const ByteArray bodyData((char*)data.data(), data.size()); + std::unique_ptr body(GetConsumerListByGroupResponseBody::Decode(bodyData)); EXPECT_EQ(body->consumerIdList.size(), 2); } diff --git a/test/src/protocol/LockBatchBodyTest.cpp b/test/src/protocol/LockBatchBodyTest.cpp index 567f27cee..64da9fb0c 100644 --- a/test/src/protocol/LockBatchBodyTest.cpp +++ b/test/src/protocol/LockBatchBodyTest.cpp @@ -19,7 +19,7 @@ #include -#include "DataBlock.h" +#include "ByteArray.h" #include "MQMessageQueue.h" #include "protocol/body/LockBatchBody.h" @@ -27,9 +27,9 @@ using testing::InitGoogleMock; using testing::InitGoogleTest; using testing::Return; +using rocketmq::ByteArray; using rocketmq::LockBatchRequestBody; using rocketmq::LockBatchResponseBody; -using rocketmq::MemoryBlock; using rocketmq::MQMessageQueue; using rocketmq::UnlockBatchRequestBody; @@ -75,10 +75,10 @@ TEST(LockBatchBodyTest, LockBatchResponseBody) { root["lockOKMQSet"] = mqs; Json::FastWriter fastwrite; - std::string outData = fastwrite.write(root); + std::string data = fastwrite.write(root); - std::unique_ptr mem(new MemoryBlock(const_cast(outData.data()), outData.size())); - std::unique_ptr lockBatchResponseBody(LockBatchResponseBody::Decode(*mem)); + const ByteArray bodyData((char*)data.data(), data.size()); + std::unique_ptr lockBatchResponseBody(LockBatchResponseBody::Decode(bodyData)); MQMessageQueue messageQueue("testTopic", "testBroker", 1); EXPECT_EQ(messageQueue, lockBatchResponseBody->getLockOKMQSet()[0]); diff --git a/test/src/protocol/RemotingCommandTest.cpp b/test/src/protocol/RemotingCommandTest.cpp index e579e0027..7729d9377 100644 --- a/test/src/protocol/RemotingCommandTest.cpp +++ b/test/src/protocol/RemotingCommandTest.cpp @@ -20,10 +20,9 @@ #include #include -#include "DataBlock.h" +#include "ByteArray.h" #include "MQProtos.h" #include "MQVersion.h" -#include "MemoryOutputStream.h" #include "RemotingCommand.h" #include "protocol/header/CommandHeader.h" @@ -31,13 +30,12 @@ using testing::InitGoogleMock; using testing::InitGoogleTest; using testing::Return; +using rocketmq::ByteArray; using rocketmq::GetConsumerRunningInfoRequestHeader; using rocketmq::GetEarliestMsgStoretimeResponseHeader; using rocketmq::GetMaxOffsetResponseHeader; using rocketmq::GetMinOffsetResponseHeader; using rocketmq::GetRouteInfoRequestHeader; -using rocketmq::MemoryBlock; -using rocketmq::MemoryOutputStream; using rocketmq::MQRequestCode; using rocketmq::MQVersion; using rocketmq::NotifyConsumerIdsChangedRequestHeader; @@ -50,15 +48,15 @@ using rocketmq::SendMessageResponseHeader; TEST(RemotingCommandTest, Init) { RemotingCommand remotingCommand; - EXPECT_EQ(remotingCommand.getCode(), 0); + EXPECT_EQ(remotingCommand.code(), 0); RemotingCommand twoRemotingCommand(13); - EXPECT_EQ(twoRemotingCommand.getCode(), 13); - EXPECT_EQ(twoRemotingCommand.getOpaque(), 0); - EXPECT_EQ(twoRemotingCommand.getRemark(), ""); - EXPECT_EQ(twoRemotingCommand.getVersion(), MQVersion::s_CurrentVersion); - EXPECT_EQ(twoRemotingCommand.getFlag(), 0); - EXPECT_TRUE(twoRemotingCommand.getBody() == nullptr); + EXPECT_EQ(twoRemotingCommand.code(), 13); + EXPECT_EQ(twoRemotingCommand.opaque(), 0); + EXPECT_EQ(twoRemotingCommand.remark(), ""); + EXPECT_EQ(twoRemotingCommand.version(), MQVersion::s_CurrentVersion); + EXPECT_EQ(twoRemotingCommand.flag(), 0); + EXPECT_TRUE(twoRemotingCommand.body() == nullptr); EXPECT_TRUE(twoRemotingCommand.readCustomHeader() == nullptr); RemotingCommand threeRemotingCommand(13, new GetRouteInfoRequestHeader("topic")); @@ -66,86 +64,85 @@ TEST(RemotingCommandTest, Init) { RemotingCommand frouRemotingCommand(13, "CPP", MQVersion::s_CurrentVersion, 12, 3, "remark", new GetRouteInfoRequestHeader("topic")); - EXPECT_EQ(frouRemotingCommand.getCode(), 13); - EXPECT_EQ(frouRemotingCommand.getOpaque(), 12); - EXPECT_EQ(frouRemotingCommand.getRemark(), "remark"); - EXPECT_EQ(frouRemotingCommand.getVersion(), MQVersion::s_CurrentVersion); - EXPECT_EQ(frouRemotingCommand.getFlag(), 3); - EXPECT_TRUE(frouRemotingCommand.getBody() == nullptr); + EXPECT_EQ(frouRemotingCommand.code(), 13); + EXPECT_EQ(frouRemotingCommand.opaque(), 12); + EXPECT_EQ(frouRemotingCommand.remark(), "remark"); + EXPECT_EQ(frouRemotingCommand.version(), MQVersion::s_CurrentVersion); + EXPECT_EQ(frouRemotingCommand.flag(), 3); + EXPECT_TRUE(frouRemotingCommand.body() == nullptr); EXPECT_FALSE(frouRemotingCommand.readCustomHeader() == nullptr); RemotingCommand sixRemotingCommand(std::move(frouRemotingCommand)); - EXPECT_EQ(sixRemotingCommand.getCode(), 13); - EXPECT_EQ(sixRemotingCommand.getOpaque(), 12); - EXPECT_EQ(sixRemotingCommand.getRemark(), "remark"); - EXPECT_EQ(sixRemotingCommand.getVersion(), MQVersion::s_CurrentVersion); - EXPECT_EQ(sixRemotingCommand.getFlag(), 3); - EXPECT_TRUE(sixRemotingCommand.getBody() == nullptr); + EXPECT_EQ(sixRemotingCommand.code(), 13); + EXPECT_EQ(sixRemotingCommand.opaque(), 12); + EXPECT_EQ(sixRemotingCommand.remark(), "remark"); + EXPECT_EQ(sixRemotingCommand.version(), MQVersion::s_CurrentVersion); + EXPECT_EQ(sixRemotingCommand.flag(), 3); + EXPECT_TRUE(sixRemotingCommand.body() == nullptr); EXPECT_FALSE(sixRemotingCommand.readCustomHeader() == nullptr); RemotingCommand* sevenRemotingCommand = &sixRemotingCommand; - EXPECT_EQ(sevenRemotingCommand->getCode(), 13); - EXPECT_EQ(sevenRemotingCommand->getOpaque(), 12); - EXPECT_EQ(sevenRemotingCommand->getRemark(), "remark"); - EXPECT_EQ(sevenRemotingCommand->getVersion(), MQVersion::s_CurrentVersion); - EXPECT_EQ(sevenRemotingCommand->getFlag(), 3); - EXPECT_TRUE(sevenRemotingCommand->getBody() == nullptr); + EXPECT_EQ(sevenRemotingCommand->code(), 13); + EXPECT_EQ(sevenRemotingCommand->opaque(), 12); + EXPECT_EQ(sevenRemotingCommand->remark(), "remark"); + EXPECT_EQ(sevenRemotingCommand->version(), MQVersion::s_CurrentVersion); + EXPECT_EQ(sevenRemotingCommand->flag(), 3); + EXPECT_TRUE(sevenRemotingCommand->body() == nullptr); EXPECT_FALSE(sevenRemotingCommand->readCustomHeader() == nullptr); } TEST(RemotingCommandTest, Info) { RemotingCommand remotingCommand; - remotingCommand.setCode(13); - EXPECT_EQ(remotingCommand.getCode(), 13); + remotingCommand.set_code(13); + EXPECT_EQ(remotingCommand.code(), 13); - remotingCommand.setOpaque(12); - EXPECT_EQ(remotingCommand.getOpaque(), 12); + remotingCommand.set_opaque(12); + EXPECT_EQ(remotingCommand.opaque(), 12); - remotingCommand.setRemark("123"); - EXPECT_EQ(remotingCommand.getRemark(), "123"); + remotingCommand.set_remark("123"); + EXPECT_EQ(remotingCommand.remark(), "123"); - remotingCommand.setBody("msgBody"); - EXPECT_EQ((std::string)*remotingCommand.getBody(), "msgBody"); + remotingCommand.set_body("msgBody"); + EXPECT_EQ((std::string)remotingCommand.body()->array(), "msgBody"); - remotingCommand.addExtField("key", "value"); + remotingCommand.set_ext_field("key", "value"); } TEST(RemotingCommandTest, Flag) { RemotingCommand remotingCommand(13, "CPP", MQVersion::s_CurrentVersion, 12, 0, "remark", new GetRouteInfoRequestHeader("topic")); ; - EXPECT_EQ(remotingCommand.getFlag(), 0); + EXPECT_EQ(remotingCommand.flag(), 0); remotingCommand.markResponseType(); int bits = 1 << 0; int flag = 0; flag |= bits; - EXPECT_EQ(remotingCommand.getFlag(), flag); + EXPECT_EQ(remotingCommand.flag(), flag); EXPECT_TRUE(remotingCommand.isResponseType()); bits = 1 << 1; flag |= bits; remotingCommand.markOnewayRPC(); - EXPECT_EQ(remotingCommand.getFlag(), flag); + EXPECT_EQ(remotingCommand.flag(), flag); EXPECT_TRUE(remotingCommand.isOnewayRPC()); } TEST(RemotingCommandTest, EncodeAndDecode) { RemotingCommand remotingCommand(MQRequestCode::QUERY_BROKER_OFFSET, "CPP", MQVersion::s_CurrentVersion, 12, 3, "remark", nullptr); - remotingCommand.setBody("123123"); + remotingCommand.set_body("123123"); auto package = remotingCommand.encode(); - std::unique_ptr decodeRemtingCommand( - RemotingCommand::Decode(std::shared_ptr(std::move(package)), true)); + std::unique_ptr decodeRemtingCommand(RemotingCommand::Decode(package, true)); - EXPECT_EQ(remotingCommand.getCode(), decodeRemtingCommand->getCode()); - EXPECT_EQ(remotingCommand.getOpaque(), decodeRemtingCommand->getOpaque()); - EXPECT_EQ(remotingCommand.getRemark(), decodeRemtingCommand->getRemark()); - EXPECT_EQ(remotingCommand.getVersion(), decodeRemtingCommand->getVersion()); - EXPECT_EQ(remotingCommand.getFlag(), decodeRemtingCommand->getFlag()); + EXPECT_EQ(remotingCommand.code(), decodeRemtingCommand->code()); + EXPECT_EQ(remotingCommand.opaque(), decodeRemtingCommand->opaque()); + EXPECT_EQ(remotingCommand.remark(), decodeRemtingCommand->remark()); + EXPECT_EQ(remotingCommand.version(), decodeRemtingCommand->version()); + EXPECT_EQ(remotingCommand.flag(), decodeRemtingCommand->flag()); EXPECT_TRUE(decodeRemtingCommand->readCustomHeader() == nullptr); // ~RemotingCommand delete @@ -156,10 +153,10 @@ TEST(RemotingCommandTest, EncodeAndDecode) { RemotingCommand remotingCommand2(MQRequestCode::GET_CONSUMER_RUNNING_INFO, "CPP", MQVersion::s_CurrentVersion, 12, 3, "remark", requestHeader); - remotingCommand2.setBody("123123"); + remotingCommand2.set_body("123123"); package = remotingCommand2.encode(); - decodeRemtingCommand.reset(RemotingCommand::Decode(std::shared_ptr(std::move(package)), true)); + decodeRemtingCommand.reset(RemotingCommand::Decode(package, true)); auto* header = decodeRemtingCommand->decodeCommandCustomHeader(); EXPECT_EQ(requestHeader->getClientId(), header->getClientId()); @@ -171,9 +168,9 @@ TEST(RemotingCommandTest, SetExtHeader) { EXPECT_TRUE(remotingCommand->readCustomHeader() == nullptr); - remotingCommand->addExtField("msgId", "ABCD"); - remotingCommand->addExtField("queueId", "1"); - remotingCommand->addExtField("queueOffset", "1024"); + remotingCommand->set_ext_field("msgId", "ABCD"); + remotingCommand->set_ext_field("queueId", "1"); + remotingCommand->set_ext_field("queueOffset", "1024"); auto* sendMessageResponseHeader = remotingCommand->decodeCommandCustomHeader(); EXPECT_EQ(sendMessageResponseHeader->msgId, "ABCD"); EXPECT_EQ(sendMessageResponseHeader->queueId, 1); diff --git a/test/src/protocol/TopicRouteDataTest.cpp b/test/src/protocol/TopicRouteDataTest.cpp index b9671ede2..3b518b9f1 100644 --- a/test/src/protocol/TopicRouteDataTest.cpp +++ b/test/src/protocol/TopicRouteDataTest.cpp @@ -19,15 +19,15 @@ #include -#include "DataBlock.h" +#include "ByteArray.h" #include "TopicRouteData.h" using testing::InitGoogleMock; using testing::InitGoogleTest; using testing::Return; +using rocketmq::ByteArray; using rocketmq::BrokerData; -using rocketmq::MemoryBlock; using rocketmq::QueueData; using rocketmq::TopicRouteData; @@ -59,10 +59,10 @@ TEST(TopicRouteDataTest, TopicRouteData) { root["brokerDatas"] = brokerDatas; - std::string out = root.toStyledString(); + std::string data = root.toStyledString(); - std::unique_ptr block(new MemoryBlock(const_cast(out.data()), out.size())); - std::unique_ptr topicRouteData(TopicRouteData::Decode(*block)); + const ByteArray bodyData((char*)data.data(), data.size()); + std::unique_ptr topicRouteData(TopicRouteData::Decode(bodyData)); EXPECT_EQ(root["orderTopicConf"], topicRouteData->getOrderTopicConf()); diff --git a/test/src/transport/ClientRemotingProcessorTest.cpp b/test/src/transport/ClientRemotingProcessorTest.cpp index d57fd320a..843fa49a5 100644 --- a/test/src/transport/ClientRemotingProcessorTest.cpp +++ b/test/src/transport/ClientRemotingProcessorTest.cpp @@ -22,10 +22,10 @@ #include #include +#include "ByteArray.h" #include "ClientRPCHook.h" #include "ClientRemotingProcessor.h" #include "ConsumerRunningInfo.h" -#include "DataBlock.h" #include "MQClientConfigImpl.h" #include "MQClientInstance.h" #include "MQMessageQueue.h" @@ -47,11 +47,11 @@ using testing::SetArgReferee; using Json::FastWriter; using Json::Value; +using rocketmq::ByteArray; using rocketmq::ClientRemotingProcessor; using rocketmq::ClientRPCHook; using rocketmq::ConsumerRunningInfo; using rocketmq::GetConsumerRunningInfoRequestHeader; -using rocketmq::MemoryBlock; using rocketmq::MQClientConfig; using rocketmq::MQClientConfigImpl; using rocketmq::MQClientInstance; diff --git a/test/src/transport/ResponseFutureTest.cpp b/test/src/transport/ResponseFutureTest.cpp index bc717e0ac..e199fe07b 100644 --- a/test/src/transport/ResponseFutureTest.cpp +++ b/test/src/transport/ResponseFutureTest.cpp @@ -66,7 +66,7 @@ TEST(ResponseFutureTest, Response) { std::unique_ptr responseCommand(new RemotingCommand()); responseFuture.setResponseCommand(std::move(responseCommand)); - EXPECT_EQ(responseFuture.getResponseCommand()->getCode(), 0); + EXPECT_EQ(responseFuture.getResponseCommand()->code(), 0); ResponseFuture responseFuture2(MQRequestCode::QUERY_BROKER_OFFSET, 4, 1000); uint64_t millis = UtilAll::currentTimeMillis(); diff --git a/test/src/transport/SocketUtilTest.cpp b/test/src/transport/SocketUtilTest.cpp index 41d200d36..e7b8a7089 100644 --- a/test/src/transport/SocketUtilTest.cpp +++ b/test/src/transport/SocketUtilTest.cpp @@ -23,10 +23,13 @@ using testing::InitGoogleMock; using testing::InitGoogleTest; using testing::Return; +using rocketmq::ByteArray; + using namespace rocketmq; TEST(SocketUtilTest, Convert) { - struct sockaddr* sa = ipPort2SocketAddress(0x7F000001, 0x276B); + char ip[] = {0x7F, 0x00, 0x00, 0x01}; + struct sockaddr* sa = ipPort2SocketAddress(ByteArray(ip, sizeof(ip)), 0x276B); struct sockaddr_in* sin = (struct sockaddr_in*)sa; EXPECT_EQ(sin->sin_addr.s_addr, 0x0100007F); EXPECT_EQ(sin->sin_port, 0x6B27); From c3d9a3cb77d88784af69e02eecfef516af3fe510 Mon Sep 17 00:00:00 2001 From: James Yin Date: Wed, 22 Jul 2020 12:56:28 +0800 Subject: [PATCH 10/62] feat(request-reply): more request interface --- include/DefaultMQProducer.h | 9 + include/MQProducer.h | 10 + src/MQClientAPIImpl.cpp | 10 +- src/common/CommunicationMode.h | 8 +- src/consumer/DefaultMQPushConsumerImpl.cpp | 2 +- src/producer/DefaultMQProducer.cpp | 27 +++ src/producer/DefaultMQProducerImpl.cpp | 216 ++++++++++++++++++--- src/producer/DefaultMQProducerImpl.h | 10 + src/producer/RequestResponseFuture.cpp | 4 + src/producer/RequestResponseFuture.h | 2 + 10 files changed, 257 insertions(+), 41 deletions(-) diff --git a/include/DefaultMQProducer.h b/include/DefaultMQProducer.h index e34f94eaa..f0baf01f2 100644 --- a/include/DefaultMQProducer.h +++ b/include/DefaultMQProducer.h @@ -75,6 +75,15 @@ class ROCKETMQCLIENT_API DefaultMQProducer : public MQProducer, public DefaultMQ // RPC MQMessage request(MQMessage& msg, long timeout) override; + void request(MQMessage& msg, RequestCallback* requestCallback, long timeout) override; + MQMessage request(MQMessage& msg, const MQMessageQueue& mq, long timeout) override; + void request(MQMessage& msg, const MQMessageQueue& mq, RequestCallback* requestCallback, long timeout) override; + MQMessage request(MQMessage& msg, MessageQueueSelector* selector, void* arg, long timeout) override; + void request(MQMessage& msg, + MessageQueueSelector* selector, + void* arg, + RequestCallback* requestCallback, + long timeout) override; public: // DefaultMQProducerConfig bool isSendLatencyFaultEnable() const override; diff --git a/include/MQProducer.h b/include/MQProducer.h index dc32fa317..69caaecf8 100644 --- a/include/MQProducer.h +++ b/include/MQProducer.h @@ -18,6 +18,7 @@ #define __MQ_PRODUCER_H__ #include "MQSelector.h" +#include "RequestCallback.h" #include "SendCallback.h" #include "SendResult.h" #include "TransactionSendResult.h" @@ -73,6 +74,15 @@ class ROCKETMQCLIENT_API MQProducer { // RPC virtual MQMessage request(MQMessage& msg, long timeout) = 0; + virtual void request(MQMessage& msg, RequestCallback* requestCallback, long timeout) = 0; + virtual MQMessage request(MQMessage& msg, const MQMessageQueue& mq, long timeout) = 0; + virtual void request(MQMessage& msg, const MQMessageQueue& mq, RequestCallback* requestCallback, long timeout) = 0; + virtual MQMessage request(MQMessage& msg, MessageQueueSelector* selector, void* arg, long timeout) = 0; + virtual void request(MQMessage& msg, + MessageQueueSelector* selector, + void* arg, + RequestCallback* requestCallback, + long timeout) = 0; }; } // namespace rocketmq diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index a1868b614..8ef0d975f 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -130,14 +130,14 @@ SendResult* MQClientAPIImpl::sendMessage(const std::string& addr, request.set_body(msg->getBody()); switch (communicationMode) { - case ComMode_ONEWAY: + case CommunicationMode::ONEWAY: m_remotingClient->invokeOneway(addr, request); return nullptr; - case ComMode_ASYNC: + case CommunicationMode::ASYNC: sendMessageAsync(addr, brokerName, msg, std::move(request), sendCallback, topicPublishInfo, instance, timeoutMillis, retryTimesWhenSendFailed, producer); return nullptr; - case ComMode_SYNC: + case CommunicationMode::SYNC: return sendMessageSync(addr, brokerName, msg, request, timeoutMillis); default: assert(false); @@ -244,10 +244,10 @@ PullResult* MQClientAPIImpl::pullMessage(const std::string& addr, RemotingCommand request(PULL_MESSAGE, requestHeader); switch (communicationMode) { - case ComMode_ASYNC: + case CommunicationMode::ASYNC: pullMessageAsync(addr, request, timeoutMillis, pullCallback); return nullptr; - case ComMode_SYNC: + case CommunicationMode::SYNC: return pullMessageSync(addr, request, timeoutMillis); default: assert(false); diff --git a/src/common/CommunicationMode.h b/src/common/CommunicationMode.h index bf8c0fe36..f05a3ef72 100644 --- a/src/common/CommunicationMode.h +++ b/src/common/CommunicationMode.h @@ -14,13 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __COMMUNICATION_MODE_H__ -#define __COMMUNICATION_MODE_H__ +#ifndef ROCKETMQ_COMMON_COMMUNICATIONMODE_H_ +#define ROCKETMQ_COMMON_COMMUNICATIONMODE_H_ namespace rocketmq { -enum CommunicationMode { ComMode_SYNC, ComMode_ASYNC, ComMode_ONEWAY }; +enum CommunicationMode { SYNC, ASYNC, ONEWAY }; } // namespace rocketmq -#endif // __COMMUNICATION_MODE_H__ +#endif // ROCKETMQ_COMMON_COMMUNICATIONMODE_H_ diff --git a/src/consumer/DefaultMQPushConsumerImpl.cpp b/src/consumer/DefaultMQPushConsumerImpl.cpp index 800b4c78c..6e83861f4 100644 --- a/src/consumer/DefaultMQPushConsumerImpl.cpp +++ b/src/consumer/DefaultMQPushConsumerImpl.cpp @@ -566,7 +566,7 @@ void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pullRequest) { commitOffsetValue, // 7 1000 * 15, // 8 m_pushConsumerConfig->getAsyncPullTimeout(), // 9 - ComMode_ASYNC, // 10 + CommunicationMode::ASYNC, // 10 callback); // 11 } catch (MQException& e) { LOG_ERROR_NEW("pullKernelImpl exception: {}", e.what()); diff --git a/src/producer/DefaultMQProducer.cpp b/src/producer/DefaultMQProducer.cpp index 89964703a..179dfdbe4 100644 --- a/src/producer/DefaultMQProducer.cpp +++ b/src/producer/DefaultMQProducer.cpp @@ -146,6 +146,33 @@ MQMessage DefaultMQProducer::request(MQMessage& msg, long timeout) { return producer_impl_->request(msg, timeout); } +void DefaultMQProducer::request(MQMessage& msg, RequestCallback* requestCallback, long timeout) { + producer_impl_->request(msg, requestCallback, timeout); +} + +MQMessage DefaultMQProducer::request(MQMessage& msg, const MQMessageQueue& mq, long timeout) { + return producer_impl_->request(msg, mq, timeout); +} + +void DefaultMQProducer::request(MQMessage& msg, + const MQMessageQueue& mq, + RequestCallback* requestCallback, + long timeout) { + producer_impl_->request(msg, mq, requestCallback, timeout); +} + +MQMessage DefaultMQProducer::request(MQMessage& msg, MessageQueueSelector* selector, void* arg, long timeout) { + return producer_impl_->request(msg, selector, arg, timeout); +} + +void DefaultMQProducer::request(MQMessage& msg, + MessageQueueSelector* selector, + void* arg, + RequestCallback* requestCallback, + long timeout) { + producer_impl_->request(msg, selector, arg, requestCallback, timeout); +} + bool DefaultMQProducer::isSendLatencyFaultEnable() const { return std::dynamic_pointer_cast(producer_impl_)->isSendLatencyFaultEnable(); } diff --git a/src/producer/DefaultMQProducerImpl.cpp b/src/producer/DefaultMQProducerImpl.cpp index 54d16fcab..158dc4d9f 100644 --- a/src/producer/DefaultMQProducerImpl.cpp +++ b/src/producer/DefaultMQProducerImpl.cpp @@ -45,6 +45,47 @@ namespace rocketmq { +class RequestSendCallback : public AutoDeleteSendCallback { + public: + RequestSendCallback(std::shared_ptr requestFuture) : request_future_(requestFuture) {} + + void onSuccess(SendResult& sendResult) override { request_future_->setSendRequestOk(true); } + + void onException(MQException& e) noexcept override { + request_future_->setSendRequestOk(false); + request_future_->putResponseMessage(nullptr); + request_future_->setCause(std::make_exception_ptr(e)); + } + + private: + std::shared_ptr request_future_; +}; + +class AsyncRequestSendCallback : public AutoDeleteSendCallback { + public: + AsyncRequestSendCallback(std::shared_ptr requestFuture) : request_future_(requestFuture) {} + + void onSuccess(SendResult& sendResult) override { request_future_->setSendRequestOk(true); } + + void onException(MQException& e) noexcept override { + request_future_->setCause(std::make_exception_ptr(e)); + auto response_future = RequestFutureTable::removeRequestFuture(request_future_->getCorrelationId()); + if (response_future != nullptr) { + // response_future is same as request_future_ + response_future->setSendRequestOk(false); + response_future->putResponseMessage(nullptr); + try { + response_future->executeRequestCallback(); + } catch (std::exception& e) { + LOG_WARN_NEW("execute requestCallback in requestFail, and callback throw {}", e.what()); + } + } + } + + private: + std::shared_ptr request_future_; +}; + DefaultMQProducerImpl::DefaultMQProducerImpl(DefaultMQProducerConfigPtr config) : DefaultMQProducerImpl(config, nullptr) {} @@ -135,7 +176,8 @@ SendResult DefaultMQProducerImpl::send(MQMessage& msg) { SendResult DefaultMQProducerImpl::send(MQMessage& msg, long timeout) { try { - std::unique_ptr sendResult(sendDefaultImpl(msg.getMessageImpl(), ComMode_SYNC, nullptr, timeout)); + std::unique_ptr sendResult( + sendDefaultImpl(msg.getMessageImpl(), CommunicationMode::SYNC, nullptr, timeout)); return *sendResult; } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); @@ -156,7 +198,7 @@ SendResult DefaultMQProducerImpl::send(MQMessage& msg, const MQMessageQueue& mq, try { std::unique_ptr sendResult( - sendKernelImpl(msg.getMessageImpl(), mq, ComMode_SYNC, nullptr, nullptr, timeout)); + sendKernelImpl(msg.getMessageImpl(), mq, CommunicationMode::SYNC, nullptr, nullptr, timeout)); return *sendResult; } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); @@ -170,7 +212,7 @@ void DefaultMQProducerImpl::send(MQMessage& msg, SendCallback* sendCallback) noe void DefaultMQProducerImpl::send(MQMessage& msg, SendCallback* sendCallback, long timeout) noexcept { try { - (void)sendDefaultImpl(msg.getMessageImpl(), ComMode_ASYNC, sendCallback, timeout); + (void)sendDefaultImpl(msg.getMessageImpl(), CommunicationMode::ASYNC, sendCallback, timeout); } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); sendCallback->onException(e); @@ -199,7 +241,7 @@ void DefaultMQProducerImpl::send(MQMessage& msg, } try { - sendKernelImpl(msg.getMessageImpl(), mq, ComMode_ASYNC, sendCallback, nullptr, timeout); + sendKernelImpl(msg.getMessageImpl(), mq, CommunicationMode::ASYNC, sendCallback, nullptr, timeout); } catch (MQBrokerException& e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); @@ -218,7 +260,7 @@ void DefaultMQProducerImpl::send(MQMessage& msg, void DefaultMQProducerImpl::sendOneway(MQMessage& msg) { try { - sendDefaultImpl(msg.getMessageImpl(), ComMode_ONEWAY, nullptr, m_producerConfig->getSendMsgTimeout()); + sendDefaultImpl(msg.getMessageImpl(), CommunicationMode::ONEWAY, nullptr, m_producerConfig->getSendMsgTimeout()); } catch (MQBrokerException e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); @@ -233,7 +275,8 @@ void DefaultMQProducerImpl::sendOneway(MQMessage& msg, const MQMessageQueue& mq) } try { - sendKernelImpl(msg.getMessageImpl(), mq, ComMode_ONEWAY, nullptr, nullptr, m_producerConfig->getSendMsgTimeout()); + sendKernelImpl(msg.getMessageImpl(), mq, CommunicationMode::ONEWAY, nullptr, nullptr, + m_producerConfig->getSendMsgTimeout()); } catch (MQBrokerException e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); @@ -247,7 +290,7 @@ SendResult DefaultMQProducerImpl::send(MQMessage& msg, MessageQueueSelector* sel SendResult DefaultMQProducerImpl::send(MQMessage& msg, MessageQueueSelector* selector, void* arg, long timeout) { try { std::unique_ptr result( - sendSelectImpl(msg.getMessageImpl(), selector, arg, ComMode_SYNC, nullptr, timeout)); + sendSelectImpl(msg.getMessageImpl(), selector, arg, CommunicationMode::SYNC, nullptr, timeout)); return *result.get(); } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); @@ -269,7 +312,7 @@ void DefaultMQProducerImpl::send(MQMessage& msg, long timeout) noexcept { try { try { - sendSelectImpl(msg.getMessageImpl(), selector, arg, ComMode_ASYNC, sendCallback, timeout); + sendSelectImpl(msg.getMessageImpl(), selector, arg, CommunicationMode::ASYNC, sendCallback, timeout); } catch (MQBrokerException& e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); @@ -288,7 +331,8 @@ void DefaultMQProducerImpl::send(MQMessage& msg, void DefaultMQProducerImpl::sendOneway(MQMessage& msg, MessageQueueSelector* selector, void* arg) { try { - sendSelectImpl(msg.getMessageImpl(), selector, arg, ComMode_ONEWAY, nullptr, m_producerConfig->getSendMsgTimeout()); + sendSelectImpl(msg.getMessageImpl(), selector, arg, CommunicationMode::ONEWAY, nullptr, + m_producerConfig->getSendMsgTimeout()); } catch (MQBrokerException e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); @@ -344,23 +388,116 @@ MessagePtr DefaultMQProducerImpl::batch(std::vector& msgs) { } } -class RequestSendCallback : public AutoDeleteSendCallback { - public: - RequestSendCallback(std::shared_ptr requestFuture) : m_requestFuture(requestFuture) {} +MQMessage DefaultMQProducerImpl::request(MQMessage& msg, long timeout) { + auto beginTimestamp = UtilAll::currentTimeMillis(); + prepareSendRequest(msg, timeout); + const auto& correlationId = msg.getProperty(MQMessageConst::PROPERTY_CORRELATION_ID); + + std::exception_ptr eptr = nullptr; + MessagePtr responseMessage; + try { + auto requestResponseFuture = std::make_shared(correlationId, timeout, nullptr); + RequestFutureTable::putRequestFuture(correlationId, requestResponseFuture); - void onSuccess(SendResult& sendResult) override { m_requestFuture->setSendRequestOk(true); } + auto cost = UtilAll::currentTimeMillis() - beginTimestamp; + sendDefaultImpl(msg.getMessageImpl(), CommunicationMode::ASYNC, new RequestSendCallback(requestResponseFuture), + timeout - cost); - void onException(MQException& e) noexcept override { - m_requestFuture->setSendRequestOk(false); - m_requestFuture->putResponseMessage(nullptr); - m_requestFuture->setCause(std::make_exception_ptr(e)); + responseMessage = requestResponseFuture->waitResponseMessage(timeout - cost); + if (responseMessage == nullptr) { + if (requestResponseFuture->isSendRequestOk()) { + std::string info = "send request message to <" + msg.getTopic() + "> OK, but wait reply message timeout, " + + UtilAll::to_string(timeout) + " ms."; + THROW_MQEXCEPTION(RequestTimeoutException, info, ClientErrorCode::REQUEST_TIMEOUT_EXCEPTION); + } else { + std::string info = "send request message to <" + msg.getTopic() + "> fail"; + THROW_MQEXCEPTION2(MQClientException, info, -1, requestResponseFuture->getCause()); + } + } + } catch (...) { + eptr = std::current_exception(); } - private: - std::shared_ptr m_requestFuture; -}; + // finally + RequestFutureTable::removeRequestFuture(correlationId); -MQMessage DefaultMQProducerImpl::request(MQMessage& msg, long timeout) { + if (eptr != nullptr) { + std::rethrow_exception(eptr); + } + + return MQMessage(responseMessage); +} + +void DefaultMQProducerImpl::request(MQMessage& msg, RequestCallback* requestCallback, long timeout) { + auto beginTimestamp = UtilAll::currentTimeMillis(); + prepareSendRequest(msg, timeout); + const auto& correlationId = msg.getProperty(MQMessageConst::PROPERTY_CORRELATION_ID); + + auto requestResponseFuture = std::make_shared(correlationId, timeout, requestCallback); + RequestFutureTable::putRequestFuture(correlationId, requestResponseFuture); + + auto cost = UtilAll::currentTimeMillis() - beginTimestamp; + sendDefaultImpl(msg.getMessageImpl(), CommunicationMode::ASYNC, new AsyncRequestSendCallback(requestResponseFuture), + timeout - cost); +} + +MQMessage DefaultMQProducerImpl::request(MQMessage& msg, const MQMessageQueue& mq, long timeout) { + auto beginTimestamp = UtilAll::currentTimeMillis(); + prepareSendRequest(msg, timeout); + const auto& correlationId = msg.getProperty(MQMessageConst::PROPERTY_CORRELATION_ID); + + std::exception_ptr eptr = nullptr; + MessagePtr responseMessage; + try { + auto requestResponseFuture = std::make_shared(correlationId, timeout, nullptr); + RequestFutureTable::putRequestFuture(correlationId, requestResponseFuture); + + auto cost = UtilAll::currentTimeMillis() - beginTimestamp; + sendKernelImpl(msg.getMessageImpl(), mq, CommunicationMode::ASYNC, new RequestSendCallback(requestResponseFuture), + nullptr, timeout - cost); + + responseMessage = requestResponseFuture->waitResponseMessage(timeout - cost); + if (responseMessage == nullptr) { + if (requestResponseFuture->isSendRequestOk()) { + std::string info = "send request message to <" + msg.getTopic() + "> OK, but wait reply message timeout, " + + UtilAll::to_string(timeout) + " ms."; + THROW_MQEXCEPTION(RequestTimeoutException, info, ClientErrorCode::REQUEST_TIMEOUT_EXCEPTION); + } else { + std::string info = "send request message to <" + msg.getTopic() + "> fail"; + THROW_MQEXCEPTION2(MQClientException, info, -1, requestResponseFuture->getCause()); + } + } + } catch (...) { + eptr = std::current_exception(); + } + + // finally + RequestFutureTable::removeRequestFuture(correlationId); + + if (eptr != nullptr) { + std::rethrow_exception(eptr); + } + + return MQMessage(responseMessage); +} + +void DefaultMQProducerImpl::request(MQMessage& msg, + const MQMessageQueue& mq, + RequestCallback* requestCallback, + long timeout) { + auto beginTimestamp = UtilAll::currentTimeMillis(); + prepareSendRequest(msg, timeout); + const auto& correlationId = msg.getProperty(MQMessageConst::PROPERTY_CORRELATION_ID); + + auto requestResponseFuture = std::make_shared(correlationId, timeout, requestCallback); + RequestFutureTable::putRequestFuture(correlationId, requestResponseFuture); + + auto cost = UtilAll::currentTimeMillis() - beginTimestamp; + sendKernelImpl(msg.getMessageImpl(), mq, CommunicationMode::ASYNC, + new AsyncRequestSendCallback(requestResponseFuture), nullptr, timeout - cost); +} + +MQMessage DefaultMQProducerImpl::request(MQMessage& msg, MessageQueueSelector* selector, void* arg, long timeout) { auto beginTimestamp = UtilAll::currentTimeMillis(); prepareSendRequest(msg, timeout); const auto& correlationId = msg.getProperty(MQMessageConst::PROPERTY_CORRELATION_ID); @@ -372,8 +509,8 @@ MQMessage DefaultMQProducerImpl::request(MQMessage& msg, long timeout) { RequestFutureTable::putRequestFuture(correlationId, requestResponseFuture); auto cost = UtilAll::currentTimeMillis() - beginTimestamp; - sendDefaultImpl(msg.getMessageImpl(), CommunicationMode::ComMode_ASYNC, - new RequestSendCallback(requestResponseFuture), timeout - cost); + sendSelectImpl(msg.getMessageImpl(), selector, arg, CommunicationMode::ASYNC, + new RequestSendCallback(requestResponseFuture), timeout - cost); responseMessage = requestResponseFuture->waitResponseMessage(timeout - cost); if (responseMessage == nullptr) { @@ -400,6 +537,23 @@ MQMessage DefaultMQProducerImpl::request(MQMessage& msg, long timeout) { return MQMessage(responseMessage); } +void DefaultMQProducerImpl::request(MQMessage& msg, + MessageQueueSelector* selector, + void* arg, + RequestCallback* requestCallback, + long timeout) { + auto beginTimestamp = UtilAll::currentTimeMillis(); + prepareSendRequest(msg, timeout); + const auto& correlationId = msg.getProperty(MQMessageConst::PROPERTY_CORRELATION_ID); + + auto requestResponseFuture = std::make_shared(correlationId, timeout, requestCallback); + RequestFutureTable::putRequestFuture(correlationId, requestResponseFuture); + + auto cost = UtilAll::currentTimeMillis() - beginTimestamp; + sendSelectImpl(msg.getMessageImpl(), selector, arg, CommunicationMode::ASYNC, + new AsyncRequestSendCallback(requestResponseFuture), timeout - cost); +} + void DefaultMQProducerImpl::prepareSendRequest(Message& msg, long timeout) { const auto correlationId = CorrelationIdUtil::createCorrelationId(); const auto& requestClientId = m_clientInstance->getClientId(); @@ -441,7 +595,7 @@ SendResult* DefaultMQProducerImpl::sendDefaultImpl(MessagePtr msg, if (topicPublishInfo != nullptr && topicPublishInfo->ok()) { bool callTimeout = false; std::unique_ptr sendResult; - int timesTotal = communicationMode == CommunicationMode::ComMode_SYNC ? 1 + m_producerConfig->getRetryTimes() : 1; + int timesTotal = communicationMode == CommunicationMode::SYNC ? 1 + m_producerConfig->getRetryTimes() : 1; int times = 0; std::string lastBrokerName; for (; times < timesTotal; times++) { @@ -466,11 +620,11 @@ SendResult* DefaultMQProducerImpl::sendDefaultImpl(MessagePtr msg, endTimestamp = UtilAll::currentTimeMillis(); updateFaultItem(mq.getBrokerName(), endTimestamp - beginTimestampPrev, false); switch (communicationMode) { - case ComMode_ASYNC: + case CommunicationMode::ASYNC: return nullptr; - case ComMode_ONEWAY: + case CommunicationMode::ONEWAY: return nullptr; - case ComMode_SYNC: + case CommunicationMode::SYNC: if (sendResult->getSendStatus() != SEND_OK) { if (m_producerConfig->isRetryAnotherBrokerWhenNotStoreOK()) { continue; @@ -569,7 +723,7 @@ SendResult* DefaultMQProducerImpl::sendKernelImpl(MessagePtr msg, SendResult* sendResult = nullptr; switch (communicationMode) { - case ComMode_ASYNC: { + case CommunicationMode::ASYNC: { long costTimeAsync = UtilAll::currentTimeMillis() - beginStartTime; if (timeout < costTimeAsync) { THROW_MQEXCEPTION(RemotingTooMuchRequestException, "sendKernelImpl call timeout", -1); @@ -578,8 +732,8 @@ SendResult* DefaultMQProducerImpl::sendKernelImpl(MessagePtr msg, brokerAddr, mq.getBrokerName(), msg, std::move(requestHeader), timeout, communicationMode, sendCallback, topicPublishInfo, m_clientInstance, m_producerConfig->getRetryTimes4Async(), shared_from_this()); } break; - case ComMode_ONEWAY: - case ComMode_SYNC: { + case CommunicationMode::ONEWAY: + case CommunicationMode::SYNC: { long costTimeSync = UtilAll::currentTimeMillis() - beginStartTime; if (timeout < costTimeSync) { THROW_MQEXCEPTION(RemotingTooMuchRequestException, "sendKernelImpl call timeout", -1); @@ -637,7 +791,7 @@ TransactionSendResult* DefaultMQProducerImpl::sendMessageInTransactionImpl(Messa MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_TRANSACTION_PREPARED, "true"); MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_PRODUCER_GROUP, m_producerConfig->getGroupName()); try { - sendResult.reset(sendDefaultImpl(msg, ComMode_SYNC, nullptr, timeout)); + sendResult.reset(sendDefaultImpl(msg, CommunicationMode::SYNC, nullptr, timeout)); } catch (MQException& e) { THROW_MQEXCEPTION(MQClientException, "send message Exception", -1); } diff --git a/src/producer/DefaultMQProducerImpl.h b/src/producer/DefaultMQProducerImpl.h index 0b1a93a9a..b3f42095b 100644 --- a/src/producer/DefaultMQProducerImpl.h +++ b/src/producer/DefaultMQProducerImpl.h @@ -92,7 +92,17 @@ class DefaultMQProducerImpl : public std::enable_shared_from_this& msgs, const MQMessageQueue& mq) override; SendResult send(std::vector& msgs, const MQMessageQueue& mq, long timeout) override; + // RPC MQMessage request(MQMessage& msg, long timeout) override; + void request(MQMessage& msg, RequestCallback* requestCallback, long timeout) override; + MQMessage request(MQMessage& msg, const MQMessageQueue& mq, long timeout) override; + void request(MQMessage&, const MQMessageQueue& mq, RequestCallback* requestCallback, long timeout) override; + MQMessage request(MQMessage& msg, MessageQueueSelector* selector, void* arg, long timeout) override; + void request(MQMessage& msg, + MessageQueueSelector* selector, + void* arg, + RequestCallback* requestCallback, + long timeout) override; public: // MQProducerInner TransactionListener* getCheckListener() override; diff --git a/src/producer/RequestResponseFuture.cpp b/src/producer/RequestResponseFuture.cpp index c3b28f935..d798057db 100644 --- a/src/producer/RequestResponseFuture.cpp +++ b/src/producer/RequestResponseFuture.cpp @@ -85,6 +85,10 @@ void RequestResponseFuture::putResponseMessage(MessagePtr responseMsg) { } } +const std::string& RequestResponseFuture::getCorrelationId() { + return m_correlationId; +} + bool RequestResponseFuture::isSendRequestOk() { return m_sendRequestOk; } diff --git a/src/producer/RequestResponseFuture.h b/src/producer/RequestResponseFuture.h index d4e3e6825..9f82eb815 100644 --- a/src/producer/RequestResponseFuture.h +++ b/src/producer/RequestResponseFuture.h @@ -37,6 +37,8 @@ class RequestResponseFuture { MessagePtr waitResponseMessage(int64_t timeout); void putResponseMessage(MessagePtr responseMsg); + const std::string& getCorrelationId(); + bool isSendRequestOk(); void setSendRequestOk(bool sendRequestOk); From 28a47275e072fe0f317c65badccaf8897e809d24 Mon Sep 17 00:00:00 2001 From: James Yin Date: Fri, 24 Jul 2020 11:04:07 +0800 Subject: [PATCH 11/62] refactor(consumer): remove const in consumeMessage --- example/AsyncProducer.cpp | 1 + example/BatchProducer.cpp | 1 + example/OrderlyProducer.cpp | 1 + example/OrderlyPushConsumer.cpp | 3 ++- example/PushConsumer.cpp | 3 ++- example/RequestReply.cpp | 5 +++-- example/SendDelayMsg.cpp | 1 + example/SyncProducer.cpp | 1 + example/TransactionProducer.cpp | 1 + example/common.h | 7 ++----- include/MQMessageListener.h | 2 +- src/extern/CPushConsumer.cpp | 4 ++-- 12 files changed, 18 insertions(+), 12 deletions(-) diff --git a/example/AsyncProducer.cpp b/example/AsyncProducer.cpp index 87e7368d5..130bc6759 100644 --- a/example/AsyncProducer.cpp +++ b/example/AsyncProducer.cpp @@ -16,6 +16,7 @@ */ #include "common.h" #include "concurrent/latch.hpp" +#include "DefaultMQProducer.h" using namespace rocketmq; diff --git a/example/BatchProducer.cpp b/example/BatchProducer.cpp index e698b6643..7ed4cb7e9 100644 --- a/example/BatchProducer.cpp +++ b/example/BatchProducer.cpp @@ -15,6 +15,7 @@ * limitations under the License. */ #include "common.h" +#include "DefaultMQProducer.h" using namespace rocketmq; diff --git a/example/OrderlyProducer.cpp b/example/OrderlyProducer.cpp index f2ce9f6e5..b0b602bd9 100644 --- a/example/OrderlyProducer.cpp +++ b/example/OrderlyProducer.cpp @@ -15,6 +15,7 @@ * limitations under the License. */ #include "common.h" +#include "DefaultMQProducer.h" using namespace rocketmq; diff --git a/example/OrderlyPushConsumer.cpp b/example/OrderlyPushConsumer.cpp index 62959f1f5..edb35636e 100644 --- a/example/OrderlyPushConsumer.cpp +++ b/example/OrderlyPushConsumer.cpp @@ -16,6 +16,7 @@ */ #include "common.h" #include "concurrent/latch.hpp" +#include "DefaultMQPushConsumer.h" using namespace rocketmq; @@ -27,7 +28,7 @@ class MyMsgListener : public MessageListenerOrderly { MyMsgListener() {} virtual ~MyMsgListener() {} - virtual ConsumeStatus consumeMessage(const std::vector& msgs) override { + virtual ConsumeStatus consumeMessage(std::vector& msgs) override { auto old = g_msgCount.fetch_sub(msgs.size()); if (old > 0) { for (size_t i = 0; i < msgs.size(); ++i) { diff --git a/example/PushConsumer.cpp b/example/PushConsumer.cpp index 0e7ccc902..aa3b9cb65 100644 --- a/example/PushConsumer.cpp +++ b/example/PushConsumer.cpp @@ -16,6 +16,7 @@ */ #include "common.h" #include "concurrent/latch.hpp" +#include "DefaultMQPushConsumer.h" #include "UtilAll.h" using namespace rocketmq; @@ -27,7 +28,7 @@ class MyMsgListener : public MessageListenerConcurrently { public: virtual ~MyMsgListener() = default; - ConsumeStatus consumeMessage(const std::vector& msgs) override { + ConsumeStatus consumeMessage(std::vector& msgs) override { auto old = g_msgCount.fetch_sub(msgs.size()); if (old > 0) { for (size_t i = 0; i < msgs.size(); ++i) { diff --git a/example/RequestReply.cpp b/example/RequestReply.cpp index ebb52e32f..8fb7a3caa 100644 --- a/example/RequestReply.cpp +++ b/example/RequestReply.cpp @@ -19,7 +19,8 @@ #include "../src/common/UtilAll.h" #include "common.h" #include "MessageUtil.h" -#include "common.h" +#include "DefaultMQProducer.h" +#include "DefaultMQPushConsumer.h" using namespace rocketmq; @@ -28,7 +29,7 @@ class MyResponseMessageListener : public MessageListenerConcurrently { MyResponseMessageListener(DefaultMQProducer* replyProducer) : m_replyProducer(replyProducer) {} virtual ~MyResponseMessageListener() = default; - ConsumeStatus consumeMessage(const std::vector& msgs) override { + ConsumeStatus consumeMessage(std::vector& msgs) override { for (const auto& msg : msgs) { try { std::cout << "handle message: " << msg.toString() << std::endl; diff --git a/example/SendDelayMsg.cpp b/example/SendDelayMsg.cpp index a1ed15073..dd0ba7281 100644 --- a/example/SendDelayMsg.cpp +++ b/example/SendDelayMsg.cpp @@ -15,6 +15,7 @@ * limitations under the License. */ #include "common.h" +#include "DefaultMQProducer.h" using namespace rocketmq; diff --git a/example/SyncProducer.cpp b/example/SyncProducer.cpp index c5bbaf134..69b71a803 100644 --- a/example/SyncProducer.cpp +++ b/example/SyncProducer.cpp @@ -15,6 +15,7 @@ * limitations under the License. */ #include "common.h" +#include "DefaultMQProducer.h" using namespace rocketmq; diff --git a/example/TransactionProducer.cpp b/example/TransactionProducer.cpp index 214d32125..bddb55955 100644 --- a/example/TransactionProducer.cpp +++ b/example/TransactionProducer.cpp @@ -15,6 +15,7 @@ * limitations under the License. */ #include "common.h" +#include "TransactionMQProducer.h" using namespace rocketmq; diff --git a/example/common.h b/example/common.h index 3de419954..3a6e46edf 100644 --- a/example/common.h +++ b/example/common.h @@ -30,12 +30,9 @@ #include "ArgHelper.h" #endif -#include "DefaultMQProducer.h" -#include "DefaultMQPullConsumer.h" -#include "DefaultMQPushConsumer.h" -#include "TransactionMQProducer.h" +#include "PullResult.h" -std::atomic g_msgCount(1); +static std::atomic g_msgCount(1); class RocketmqSendAndConsumerArgs { public: diff --git a/include/MQMessageListener.h b/include/MQMessageListener.h index b12763226..11287f9ee 100644 --- a/include/MQMessageListener.h +++ b/include/MQMessageListener.h @@ -38,7 +38,7 @@ class ROCKETMQCLIENT_API MQMessageListener { virtual MessageListenerType getMessageListenerType() { return messageListenerDefaultly; } - virtual ConsumeStatus consumeMessage(const std::vector& msgs) { return RECONSUME_LATER; }; + virtual ConsumeStatus consumeMessage(std::vector& msgs) { return RECONSUME_LATER; }; }; class ROCKETMQCLIENT_API MessageListenerConcurrently : virtual public MQMessageListener { diff --git a/src/extern/CPushConsumer.cpp b/src/extern/CPushConsumer.cpp index b93a94fcc..c8755271c 100644 --- a/src/extern/CPushConsumer.cpp +++ b/src/extern/CPushConsumer.cpp @@ -32,7 +32,7 @@ class MessageListenerInner : public MessageListenerConcurrently { ~MessageListenerInner() = default; - ConsumeStatus consumeMessage(const std::vector& msgs) override { + ConsumeStatus consumeMessage(std::vector& msgs) override { // to do user call back if (m_msgReceivedCallback == nullptr) { return RECONSUME_LATER; @@ -56,7 +56,7 @@ class MessageListenerOrderlyInner : public MessageListenerOrderly { MessageListenerOrderlyInner(CPushConsumer* consumer, MessageCallBack callback) : m_consumer(consumer), m_msgReceivedCallback(callback) {} - ConsumeStatus consumeMessage(const std::vector& msgs) override { + ConsumeStatus consumeMessage(std::vector& msgs) override { if (m_msgReceivedCallback == nullptr) { return RECONSUME_LATER; } From dc782f256e498ec7a99dc24cdde5016b7704adf4 Mon Sep 17 00:00:00 2001 From: James Yin Date: Wed, 29 Jul 2020 22:23:17 +0800 Subject: [PATCH 12/62] fix: use invalid ByteArrayRef after call std::move --- src/io/DefaultByteBuffer.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/io/DefaultByteBuffer.hpp b/src/io/DefaultByteBuffer.hpp index 73a40397b..ca740bab9 100644 --- a/src/io/DefaultByteBuffer.hpp +++ b/src/io/DefaultByteBuffer.hpp @@ -32,8 +32,7 @@ class DefaultByteBuffer : public ByteBuffer { DefaultByteBuffer(int32_t cap, int32_t lim) : ByteBuffer(-1, 0, lim, cap, std::make_shared(cap), 0) {} - DefaultByteBuffer(ByteArrayRef buf, int32_t off, int32_t len) - : ByteBuffer(-1, off, off + len, buf->size(), std::move(buf), 0) {} + DefaultByteBuffer(ByteArrayRef buf, int32_t off, int32_t len) : ByteBuffer(-1, off, off + len, buf->size(), buf, 0) {} DefaultByteBuffer(ByteArrayRef buf, int32_t mark, int32_t pos, int32_t lim, int32_t cap, int32_t off) : ByteBuffer(mark, pos, lim, cap, std::move(buf), off) {} From 15a8b0b253e62d52ee0464a0f3915c465360c5bc Mon Sep 17 00:00:00 2001 From: James Yin Date: Thu, 6 Aug 2020 23:07:02 +0800 Subject: [PATCH 13/62] fix: missing include functional --- example/common.h | 1 + src/producer/DefaultMQProducerImpl.cpp | 6 +++--- src/protocol/ConsumerRunningInfo.cpp | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/example/common.h b/example/common.h index 3a6e46edf..393fda072 100644 --- a/example/common.h +++ b/example/common.h @@ -19,6 +19,7 @@ #include #include +#include #include #include #include diff --git a/src/producer/DefaultMQProducerImpl.cpp b/src/producer/DefaultMQProducerImpl.cpp index 158dc4d9f..e5ef3b04b 100644 --- a/src/producer/DefaultMQProducerImpl.cpp +++ b/src/producer/DefaultMQProducerImpl.cpp @@ -261,7 +261,7 @@ void DefaultMQProducerImpl::send(MQMessage& msg, void DefaultMQProducerImpl::sendOneway(MQMessage& msg) { try { sendDefaultImpl(msg.getMessageImpl(), CommunicationMode::ONEWAY, nullptr, m_producerConfig->getSendMsgTimeout()); - } catch (MQBrokerException e) { + } catch (MQBrokerException& e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); } @@ -277,7 +277,7 @@ void DefaultMQProducerImpl::sendOneway(MQMessage& msg, const MQMessageQueue& mq) try { sendKernelImpl(msg.getMessageImpl(), mq, CommunicationMode::ONEWAY, nullptr, nullptr, m_producerConfig->getSendMsgTimeout()); - } catch (MQBrokerException e) { + } catch (MQBrokerException& e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); } @@ -333,7 +333,7 @@ void DefaultMQProducerImpl::sendOneway(MQMessage& msg, MessageQueueSelector* sel try { sendSelectImpl(msg.getMessageImpl(), selector, arg, CommunicationMode::ONEWAY, nullptr, m_producerConfig->getSendMsgTimeout()); - } catch (MQBrokerException e) { + } catch (MQBrokerException& e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); } diff --git a/src/protocol/ConsumerRunningInfo.cpp b/src/protocol/ConsumerRunningInfo.cpp index 3f1b81ec1..19f5fff61 100644 --- a/src/protocol/ConsumerRunningInfo.cpp +++ b/src/protocol/ConsumerRunningInfo.cpp @@ -16,6 +16,7 @@ */ #include "ConsumerRunningInfo.h" +#include "RemotingSerializable.h" #include "UtilAll.h" namespace rocketmq { @@ -89,8 +90,7 @@ std::string ConsumerRunningInfo::encode() { root["subscriptionSet"].append(subscription.toJson()); } - Json::FastWriter fastwrite; - std::string finals = fastwrite.write(root); + std::string finals = RemotingSerializable::toJson(root); Json::Value mq; std::string key = "\"mqTable\":"; From cb2789660c8ca49e76bfd1dc56c713ae90efa47a Mon Sep 17 00:00:00 2001 From: James Yin Date: Thu, 6 Aug 2020 23:34:00 +0800 Subject: [PATCH 14/62] refactor: remove dynamic exception specifications --- include/MessageUtil.h | 2 +- src/MQClientAPIImpl.cpp | 4 ++-- src/MQClientAPIImpl.h | 4 ++-- src/consumer/RebalanceImpl.cpp | 2 +- src/consumer/RebalanceImpl.h | 2 +- src/io/Buffer.hpp | 6 +++--- src/message/MessageUtil.cpp | 3 +-- src/transport/TcpRemotingClient.cpp | 18 ++++++++---------- src/transport/TcpRemotingClient.h | 13 ++++++------- 9 files changed, 25 insertions(+), 29 deletions(-) diff --git a/include/MessageUtil.h b/include/MessageUtil.h index d44fd8fdc..ba21b70a1 100644 --- a/include/MessageUtil.h +++ b/include/MessageUtil.h @@ -24,7 +24,7 @@ namespace rocketmq { class ROCKETMQCLIENT_API MessageUtil { public: - static MQMessage createReplyMessage(const Message& requestMessage, const std::string& body) throw(MQClientException); + static MQMessage createReplyMessage(const Message& requestMessage, const std::string& body); static const std::string& getReplyToClient(const Message& msg); }; diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index 8ef0d975f..42c9f6f03 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -156,7 +156,7 @@ void MQClientAPIImpl::sendMessageAsync(const std::string& addr, MQClientInstancePtr instance, int64_t timeoutMillis, int retryTimesWhenSendFailed, - DefaultMQProducerImplPtr producer) throw(RemotingException) { + DefaultMQProducerImplPtr producer) { // delete in future auto* cbw = new SendCallbackWrap(addr, brokerName, msg, std::forward(request), sendCallback, topicPublishInfo, instance, retryTimesWhenSendFailed, 0, producer); @@ -169,7 +169,7 @@ void MQClientAPIImpl::sendMessageAsync(const std::string& addr, } } -void MQClientAPIImpl::sendMessageAsyncImpl(SendCallbackWrap* cbw, int64_t timeoutMillis) throw(RemotingException) { +void MQClientAPIImpl::sendMessageAsyncImpl(SendCallbackWrap* cbw, int64_t timeoutMillis) { const auto& addr = cbw->getAddr(); auto& request = cbw->getRemotingCommand(); m_remotingClient->invokeAsync(addr, request, cbw, timeoutMillis); diff --git a/src/MQClientAPIImpl.h b/src/MQClientAPIImpl.h index dcf8da9c4..c77399103 100644 --- a/src/MQClientAPIImpl.h +++ b/src/MQClientAPIImpl.h @@ -179,9 +179,9 @@ class MQClientAPIImpl { MQClientInstancePtr instance, int64_t timeoutMilliseconds, int retryTimesWhenSendFailed, - DefaultMQProducerImplPtr producer) throw(RemotingException); + DefaultMQProducerImplPtr producer); - void sendMessageAsyncImpl(SendCallbackWrap* cbw, int64_t timeoutMillis) throw(RemotingException); + void sendMessageAsyncImpl(SendCallbackWrap* cbw, int64_t timeoutMillis); PullResult* pullMessageSync(const std::string& addr, RemotingCommand& request, int timeoutMillis); diff --git a/src/consumer/RebalanceImpl.cpp b/src/consumer/RebalanceImpl.cpp index d3b8e78c0..fb24e978d 100644 --- a/src/consumer/RebalanceImpl.cpp +++ b/src/consumer/RebalanceImpl.cpp @@ -224,7 +224,7 @@ void RebalanceImpl::lockAll() { } } -void RebalanceImpl::doRebalance(const bool isOrder) throw(MQClientException) { +void RebalanceImpl::doRebalance(const bool isOrder) { LOG_DEBUG("start doRebalance"); for (const auto& it : m_subscriptionInner) { const std::string& topic = it.first; diff --git a/src/consumer/RebalanceImpl.h b/src/consumer/RebalanceImpl.h index 0a62f4927..18b555b81 100755 --- a/src/consumer/RebalanceImpl.h +++ b/src/consumer/RebalanceImpl.h @@ -49,7 +49,7 @@ class RebalanceImpl { bool lock(MQMessageQueue mq); void lockAll(); - void doRebalance(const bool isOrder = false) throw(MQClientException); + void doRebalance(const bool isOrder = false); void destroy(); diff --git a/src/io/Buffer.hpp b/src/io/Buffer.hpp index a066e2c28..aae1d5b74 100644 --- a/src/io/Buffer.hpp +++ b/src/io/Buffer.hpp @@ -28,7 +28,7 @@ namespace rocketmq { template class Buffer { protected: - Buffer(int32_t mark, int32_t pos, int32_t lim, int32_t cap) throw(std::invalid_argument) { + Buffer(int32_t mark, int32_t pos, int32_t lim, int32_t cap) { if (cap < 0) { throw std::invalid_argument("Negative capacity: " + UtilAll::to_string(cap)); } @@ -45,7 +45,7 @@ class Buffer { } public: - Buffer& position(int new_position) throw(std::invalid_argument) { + Buffer& position(int new_position) { if ((new_position > limit_) || (new_position < 0)) { throw std::invalid_argument(""); } @@ -56,7 +56,7 @@ class Buffer { return *this; } - Buffer& limit(int new_limit) throw(std::invalid_argument) { + Buffer& limit(int new_limit) { if ((new_limit > capacity_) || (new_limit < 0)) { throw std::invalid_argument(""); } diff --git a/src/message/MessageUtil.cpp b/src/message/MessageUtil.cpp index 21d2510de..418750a61 100644 --- a/src/message/MessageUtil.cpp +++ b/src/message/MessageUtil.cpp @@ -25,8 +25,7 @@ namespace rocketmq { -MQMessage MessageUtil::createReplyMessage(const Message& requestMessage, - const std::string& body) throw(MQClientException) { +MQMessage MessageUtil::createReplyMessage(const Message& requestMessage, const std::string& body) { const auto& cluster = requestMessage.getProperty(MQMessageConst::PROPERTY_CLUSTER); if (!cluster.empty()) { auto replyMessage = std::make_shared(UtilAll::getReplyTopic(cluster), body); diff --git a/src/transport/TcpRemotingClient.cpp b/src/transport/TcpRemotingClient.cpp index 5691f58f2..cf035f280 100644 --- a/src/transport/TcpRemotingClient.cpp +++ b/src/transport/TcpRemotingClient.cpp @@ -215,7 +215,7 @@ void TcpRemotingClient::scanResponseTable() { std::unique_ptr TcpRemotingClient::invokeSync(const std::string& addr, RemotingCommand& request, - int timeoutMillis) throw(RemotingException) { + int timeoutMillis) { auto beginStartTime = UtilAll::currentTimeMillis(); auto channel = GetTransport(addr); if (channel != nullptr) { @@ -247,10 +247,9 @@ std::unique_ptr TcpRemotingClient::invokeSync(const std::string } } -std::unique_ptr TcpRemotingClient::invokeSyncImpl( - TcpTransportPtr channel, - RemotingCommand& request, - int64_t timeoutMillis) throw(RemotingTimeoutException, RemotingSendRequestException) { +std::unique_ptr TcpRemotingClient::invokeSyncImpl(TcpTransportPtr channel, + RemotingCommand& request, + int64_t timeoutMillis) { int code = request.code(); int opaque = request.opaque(); @@ -281,7 +280,7 @@ std::unique_ptr TcpRemotingClient::invokeSyncImpl( void TcpRemotingClient::invokeAsync(const std::string& addr, RemotingCommand& request, InvokeCallback* invokeCallback, - int64_t timeoutMillis) throw(RemotingException) { + int64_t timeoutMillis) { auto beginStartTime = UtilAll::currentTimeMillis(); auto channel = GetTransport(addr); if (channel != nullptr) { @@ -305,7 +304,7 @@ void TcpRemotingClient::invokeAsync(const std::string& addr, void TcpRemotingClient::invokeAsyncImpl(TcpTransportPtr channel, RemotingCommand& request, int64_t timeoutMillis, - InvokeCallback* invokeCallback) throw(RemotingSendRequestException) { + InvokeCallback* invokeCallback) { int code = request.code(); int opaque = request.opaque(); @@ -335,7 +334,7 @@ void TcpRemotingClient::invokeAsyncImpl(TcpTransportPtr channel, } } -void TcpRemotingClient::invokeOneway(const std::string& addr, RemotingCommand& request) throw(RemotingException) { +void TcpRemotingClient::invokeOneway(const std::string& addr, RemotingCommand& request) { auto channel = GetTransport(addr); if (channel != nullptr) { try { @@ -351,8 +350,7 @@ void TcpRemotingClient::invokeOneway(const std::string& addr, RemotingCommand& r } } -void TcpRemotingClient::invokeOnewayImpl(TcpTransportPtr channel, - RemotingCommand& request) throw(RemotingSendRequestException) { +void TcpRemotingClient::invokeOnewayImpl(TcpTransportPtr channel, RemotingCommand& request) { request.markOnewayRPC(); try { if (!SendCommand(channel, request)) { diff --git a/src/transport/TcpRemotingClient.h b/src/transport/TcpRemotingClient.h index f1937149e..6897dee48 100755 --- a/src/transport/TcpRemotingClient.h +++ b/src/transport/TcpRemotingClient.h @@ -48,14 +48,14 @@ class TcpRemotingClient { std::unique_ptr invokeSync(const std::string& addr, RemotingCommand& request, - int timeoutMillis = 3000) throw(RemotingException); + int timeoutMillis = 3000); void invokeAsync(const std::string& addr, RemotingCommand& request, InvokeCallback* invokeCallback, - int64_t timeoutMillis) throw(RemotingException); + int64_t timeoutMillis); - void invokeOneway(const std::string& addr, RemotingCommand& request) throw(RemotingException); + void invokeOneway(const std::string& addr, RemotingCommand& request); void registerProcessor(MQRequestCode requestCode, RequestProcessor* requestProcessor); @@ -84,13 +84,12 @@ class TcpRemotingClient { std::unique_ptr invokeSyncImpl(TcpTransportPtr channel, RemotingCommand& request, - int64_t timeoutMillis) throw(RemotingTimeoutException, - RemotingSendRequestException); + int64_t timeoutMillis); void invokeAsyncImpl(TcpTransportPtr channel, RemotingCommand& request, int64_t timeoutMillis, - InvokeCallback* invokeCallback) throw(RemotingSendRequestException); - void invokeOnewayImpl(TcpTransportPtr channel, RemotingCommand& request) throw(RemotingSendRequestException); + InvokeCallback* invokeCallback); + void invokeOnewayImpl(TcpTransportPtr channel, RemotingCommand& request); // rpc hook void doBeforeRpcHooks(const std::string& addr, RemotingCommand& request, bool toSent); From e1068cbdd511388e95c2aee1176c368cebed2200 Mon Sep 17 00:00:00 2001 From: James Yin Date: Sat, 22 Aug 2020 06:23:11 +0800 Subject: [PATCH 15/62] fix: check the lock of process queue is expired --- src/consumer/ConsumeMessageOrderlyService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/consumer/ConsumeMessageOrderlyService.cpp b/src/consumer/ConsumeMessageOrderlyService.cpp index ec6c3ff1b..4404edcb8 100755 --- a/src/consumer/ConsumeMessageOrderlyService.cpp +++ b/src/consumer/ConsumeMessageOrderlyService.cpp @@ -131,7 +131,7 @@ void ConsumeMessageOrderlyService::ConsumeRequest(ProcessQueuePtr processQueue, break; } - if (CLUSTERING == m_consumer->messageModel() && !processQueue->isLockExpired()) { + if (CLUSTERING == m_consumer->messageModel() && processQueue->isLockExpired()) { LOG_WARN_NEW("the message queue lock expired, so consume later, {}", messageQueue.toString()); tryLockLaterAndReconsume(messageQueue, processQueue, 10); break; From 6bf16392daeba44cca1ed37536f0ab1505bf1d3e Mon Sep 17 00:00:00 2001 From: James Yin Date: Wed, 22 Jul 2020 00:52:29 +0800 Subject: [PATCH 16/62] style: follow Chromium c++ style --- example/ArgHelper.cpp | 20 +- example/ArgHelper.h | 9 +- example/AsyncProducer.cpp | 6 +- example/BatchProducer.cpp | 6 +- example/OrderlyProducer.cpp | 6 +- example/OrderlyPushConsumer.cpp | 2 +- example/PullConsumer.cpp | 6 +- example/PushConsumer.cpp | 2 +- example/RequestReply.cpp | 4 +- example/SyncProducer.cpp | 6 +- example/TransactionProducer.cpp | 8 +- example/common.h | 14 +- include/AllocateMQStrategy.h | 2 +- include/Array.h | 2 +- include/ConsumeType.h | 6 +- include/DefaultMQProducer.h | 10 +- include/DefaultMQProducerConfig.h | 16 +- include/DefaultMQProducerConfigProxy.h | 90 ++- include/DefaultMQPullConsumer.h | 6 +- include/DefaultMQPullConsumerConfig.h | 6 +- include/DefaultMQPullConsumerConfigProxy.h | 6 +- include/DefaultMQPushConsumer.h | 10 +- include/DefaultMQPushConsumerConfig.h | 16 +- include/DefaultMQPushConsumerConfigProxy.h | 102 ++-- include/MQAdmin.h | 6 +- include/MQClientConfig.h | 12 +- include/MQClientConfigProxy.h | 66 +- include/MQConsumer.h | 11 +- .../{MQClientException.h => MQException.h} | 57 +- include/MQMessage.h | 2 +- include/MQMessageConst.h | 6 +- include/MQMessageExt.h | 2 +- include/MQMessageListener.h | 17 +- include/MQMessageQueue.h | 12 +- include/MQProducer.h | 8 +- include/MQPullConsumer.h | 6 +- include/MQPushConsumer.h | 12 +- include/MQSelector.h | 8 +- include/Message.h | 2 +- include/MessageExt.h | 2 +- include/MessageUtil.h | 5 +- .../NamesrvConfig.h => include/OffsetStore.h | 47 +- include/PullCallback.h | 16 +- include/QueryResult.h | 6 +- include/RemotingCommand.h | 5 +- include/RequestCallback.h | 20 +- include/SendCallback.h | 20 +- include/SendResult.h | 68 ++- include/SessionCredentials.h | 56 +- include/TransactionListener.h | 9 +- include/TransactionMQProducer.h | 25 +- include/TransactionMQProducerConfig.h | 9 +- include/TransactionSendResult.h | 16 +- include/c/CBatchMessage.h | 6 +- include/c/CCommon.h | 6 +- include/c/CErrorMessage.h | 6 +- include/c/CMQException.h | 6 +- include/c/CMessage.h | 8 +- include/c/CMessageExt.h | 8 +- include/c/CMessageQueue.h | 6 +- include/c/CProducer.h | 9 +- include/c/CPullConsumer.h | 6 +- include/c/CPullResult.h | 6 +- include/c/CPushConsumer.h | 8 +- include/c/CSendResult.h | 6 +- include/c/CTransactionStatus.h | 6 +- src/ClientRemotingProcessor.cpp | 12 +- src/ClientRemotingProcessor.h | 8 +- src/MQAdminImpl.cpp | 40 +- src/MQAdminImpl.h | 10 +- src/MQClientAPIImpl.cpp | 89 +-- src/MQClientAPIImpl.h | 18 +- src/MQClientConfigImpl.cpp | 116 ---- src/MQClientConfigImpl.h | 70 --- src/MQClientConfigImpl.hpp | 106 ++++ src/MQClientImpl.cpp | 36 +- src/MQClientImpl.h | 20 +- src/MQClientInstance.cpp | 363 ++++++----- src/MQClientInstance.h | 64 +- src/MQClientManager.cpp | 16 +- src/MQClientManager.h | 15 +- src/common/ClientErrorCode.h | 6 +- src/common/ClientRPCHook.cpp | 24 +- src/common/{FilterAPI.h => FilterAPI.hpp} | 20 +- src/common/InvokeCallback.h | 7 +- src/common/MQVersion.cpp | 4 +- src/common/MQVersion.h | 10 +- src/common/MessageSysFlag.h | 6 +- src/common/NameSpaceUtil.h | 6 +- src/common/PermName.h | 9 +- src/common/PullCallbackWrap.cpp | 18 +- src/common/PullCallbackWrap.h | 10 +- src/common/PullSysFlag.cpp | 10 +- src/common/PullSysFlag.h | 12 +- src/common/SendCallbackWrap.cpp | 103 ++-- src/common/SendCallbackWrap.h | 40 +- src/common/ServiceState.h | 6 +- src/common/ServiceThread.cpp | 36 +- src/common/ServiceThread.h | 25 +- src/common/SubscriptionData.h | 53 +- src/common/SubscriptionGroupConfig.h | 8 +- src/common/TopicConfig.cpp | 93 +-- src/common/TopicConfig.h | 50 +- src/common/UtilAll.cpp | 2 +- src/common/Validators.cpp | 17 +- src/common/Validators.h | 14 +- src/common/VirtualEnvUtil.cpp | 4 +- src/common/VirtualEnvUtil.h | 9 +- src/common/noncopyable.h | 6 +- src/concurrent/concurrent_queue.hpp | 6 +- src/concurrent/executor.hpp | 6 +- src/concurrent/executor_impl.hpp | 28 +- src/concurrent/latch.hpp | 6 +- src/concurrent/thread.hpp | 6 +- src/concurrent/thread_group.hpp | 14 +- src/concurrent/time.hpp | 6 +- ...eMQAveragely.h => AllocateMQAveragely.hpp} | 8 +- .../ConsumeMessageConcurrentlyService.cpp | 45 +- src/consumer/ConsumeMessageOrderlyService.cpp | 73 +-- src/consumer/ConsumeMsgService.h | 27 +- src/consumer/DefaultMQPullConsumerImpl.cpp | 2 +- src/consumer/DefaultMQPushConsumer.cpp | 7 +- .../DefaultMQPushConsumerConfigImpl.cpp | 125 ---- .../DefaultMQPushConsumerConfigImpl.h | 81 --- .../DefaultMQPushConsumerConfigImpl.hpp | 112 ++++ src/consumer/DefaultMQPushConsumerImpl.cpp | 572 +++++++++--------- src/consumer/DefaultMQPushConsumerImpl.h | 81 +-- .../FindBrokerResult.hpp} | 22 +- src/consumer/LocalFileOffsetStore.cpp | 193 ++++++ src/consumer/LocalFileOffsetStore.h | 57 ++ src/consumer/MQConsumerInner.h | 7 +- src/consumer/MessageQueueLock.hpp | 18 +- src/consumer/OffsetStore.cpp | 328 ---------- src/consumer/OffsetStore.h | 103 ---- src/consumer/ProcessQueue.cpp | 190 +++--- src/consumer/ProcessQueue.h | 78 +-- src/consumer/PullAPIWrapper.cpp | 46 +- src/consumer/PullAPIWrapper.h | 18 +- src/consumer/PullMessageService.hpp | 28 +- src/consumer/PullRequest.cpp | 52 +- src/consumer/PullRequest.h | 44 +- src/consumer/PullResult.cpp | 4 +- .../{PullResultExt.h => PullResultExt.hpp} | 6 +- src/consumer/RebalanceImpl.cpp | 192 +++--- src/consumer/RebalanceImpl.h | 42 +- src/consumer/RebalancePullImpl.h | 2 +- src/consumer/RebalancePushImpl.cpp | 53 +- src/consumer/RebalancePushImpl.h | 10 +- src/consumer/RebalanceService.h | 12 +- src/consumer/RemoteBrokerOffsetStore.cpp | 153 +++++ src/consumer/RemoteBrokerOffsetStore.h | 54 ++ src/consumer/SubscriptionData.cpp | 70 +-- ...ErrorContainer.cpp => CErrorContainer.cpp} | 18 +- .../CErrorContainer.h} | 17 +- src/extern/CErrorMessage.cpp | 4 +- src/extern/CProducer.cpp | 102 ++-- src/extern/CPullConsumer.cpp | 20 +- src/extern/CPushConsumer.cpp | 54 +- src/log/Logging.cpp | 95 ++- src/log/Logging.h | 79 +-- src/message/MQMessageExt.cpp | 56 +- ...{MessageAccessor.h => MessageAccessor.hpp} | 6 +- src/message/MessageBatch.cpp | 2 +- src/message/MessageBatch.h | 12 +- src/message/MessageClientIDSetter.cpp | 16 +- src/message/MessageClientIDSetter.h | 29 +- src/message/MessageDecoder.cpp | 17 +- src/message/MessageDecoder.h | 12 +- src/message/MessageUtil.cpp | 2 +- src/producer/CorrelationIdUtil.hpp | 6 +- src/producer/DefaultMQProducer.cpp | 11 +- src/producer/DefaultMQProducerConfigImpl.cpp | 88 --- src/producer/DefaultMQProducerConfigImpl.h | 63 -- src/producer/DefaultMQProducerConfigImpl.hpp | 84 +++ src/producer/DefaultMQProducerImpl.cpp | 383 ++++++------ src/producer/DefaultMQProducerImpl.h | 56 +- src/producer/LatencyFaultTolerancyImpl.cpp | 64 +- src/producer/LatencyFaultTolerancyImpl.h | 52 +- src/producer/MQFaultStrategy.cpp | 6 +- src/producer/MQFaultStrategy.h | 8 +- src/producer/MQProducerInner.h | 6 +- src/producer/RequestFutureTable.cpp | 16 +- src/producer/RequestFutureTable.h | 10 +- src/producer/RequestResponseFuture.cpp | 70 +-- src/producer/RequestResponseFuture.h | 35 +- src/producer/SendResult.cpp | 69 +-- src/producer/TopicPublishInfo.h | 111 ---- src/producer/TopicPublishInfo.hpp | 111 ++++ src/producer/TransactionMQProducer.cpp | 34 +- .../TransactionMQProducerConfigImpl.cpp | 31 - ....h => TransactionMQProducerConfigImpl.hpp} | 18 +- src/protocol/ConsumerRunningInfo.cpp | 54 +- src/protocol/ConsumerRunningInfo.h | 57 +- src/protocol/MQProtos.h | 6 +- src/protocol/MessageQueue.cpp | 6 +- src/protocol/RemotingCommand.cpp | 10 +- src/protocol/RemotingSerializable.cpp | 2 +- src/protocol/RemotingSerializable.h | 6 +- src/protocol/RequestCode.h | 6 +- src/protocol/ResponseCode.h | 6 +- src/protocol/TopicRouteData.h | 149 ----- src/protocol/TopicRouteData.hpp | 189 ++++++ src/protocol/header/CommandHeader.cpp | 2 +- src/protocol/header/CommandHeader.h | 8 +- src/transport/EventLoop.cpp | 110 ++-- src/transport/EventLoop.h | 51 +- src/transport/RequestProcessor.h | 6 +- src/transport/ResponseFuture.cpp | 82 +-- src/transport/ResponseFuture.h | 38 +- src/transport/SocketUtil.cpp | 2 +- src/transport/SocketUtil.h | 6 +- src/transport/TcpRemotingClient.cpp | 196 +++--- src/transport/TcpRemotingClient.h | 38 +- src/transport/TcpTransport.cpp | 72 +-- src/transport/TcpTransport.h | 24 +- test/src/common/NamesrvConfigTest.cpp | 47 -- test/src/common/TopicConfigTest.cpp | 50 +- test/src/common/ValidatorsTest.cpp | 8 +- test/src/extern/CPullConsumerTest.cpp | 2 +- test/src/message/MQMessageQueueTest.cpp | 44 +- test/src/protocol/CommandHeaderTest.cpp | 2 +- test/src/protocol/MessageQueueTest.cpp | 6 +- test/src/protocol/RemotingCommandTest.cpp | 20 +- test/src/protocol/TopicRouteDataTest.cpp | 21 +- .../transport/ClientRemotingProcessorTest.cpp | 2 +- test/src/transport/ResponseFutureTest.cpp | 12 +- 226 files changed, 4192 insertions(+), 4578 deletions(-) rename include/{MQClientException.h => MQException.h} (79%) rename src/common/NamesrvConfig.h => include/OffsetStore.h (50%) delete mode 100644 src/MQClientConfigImpl.cpp delete mode 100644 src/MQClientConfigImpl.h create mode 100644 src/MQClientConfigImpl.hpp rename src/common/{FilterAPI.h => FilterAPI.hpp} (74%) rename src/consumer/{AllocateMQAveragely.h => AllocateMQAveragely.hpp} (93%) delete mode 100644 src/consumer/DefaultMQPushConsumerConfigImpl.cpp delete mode 100644 src/consumer/DefaultMQPushConsumerConfigImpl.h create mode 100644 src/consumer/DefaultMQPushConsumerConfigImpl.hpp rename src/{extern/MQClientErrorContainer.h => consumer/FindBrokerResult.hpp} (58%) create mode 100644 src/consumer/LocalFileOffsetStore.cpp create mode 100644 src/consumer/LocalFileOffsetStore.h delete mode 100644 src/consumer/OffsetStore.cpp delete mode 100644 src/consumer/OffsetStore.h rename src/consumer/{PullResultExt.h => PullResultExt.hpp} (93%) create mode 100644 src/consumer/RemoteBrokerOffsetStore.cpp create mode 100644 src/consumer/RemoteBrokerOffsetStore.h rename src/extern/{MQClientErrorContainer.cpp => CErrorContainer.cpp} (68%) rename src/{consumer/FindBrokerResult.h => extern/CErrorContainer.h} (71%) rename src/message/{MessageAccessor.h => MessageAccessor.hpp} (92%) delete mode 100644 src/producer/DefaultMQProducerConfigImpl.cpp delete mode 100644 src/producer/DefaultMQProducerConfigImpl.h create mode 100644 src/producer/DefaultMQProducerConfigImpl.hpp delete mode 100644 src/producer/TopicPublishInfo.h create mode 100644 src/producer/TopicPublishInfo.hpp delete mode 100644 src/producer/TransactionMQProducerConfigImpl.cpp rename src/producer/{TransactionMQProducerConfigImpl.h => TransactionMQProducerConfigImpl.hpp} (69%) delete mode 100644 src/protocol/TopicRouteData.h create mode 100644 src/protocol/TopicRouteData.hpp delete mode 100644 test/src/common/NamesrvConfigTest.cpp diff --git a/example/ArgHelper.cpp b/example/ArgHelper.cpp index 150623313..495825312 100644 --- a/example/ArgHelper.cpp +++ b/example/ArgHelper.cpp @@ -22,26 +22,26 @@ namespace rocketmq { ArgHelper::ArgHelper(int argc, char* argv[]) { for (int i = 0; i < argc; i++) { - m_args.push_back(argv[i]); + args_.push_back(argv[i]); } } ArgHelper::ArgHelper(std::string arg_str_) { std::vector v; UtilAll::Split(v, arg_str_, " "); - m_args.insert(m_args.end(), v.begin(), v.end()); + args_.insert(args_.end(), v.begin(), v.end()); } std::string ArgHelper::get_option(int idx_) const { - if ((size_t)idx_ >= m_args.size()) { + if ((size_t)idx_ >= args_.size()) { return ""; } - return m_args[idx_]; + return args_[idx_]; } bool ArgHelper::is_enable_option(std::string opt_) const { - for (size_t i = 0; i < m_args.size(); ++i) { - if (opt_ == m_args[i]) { + for (size_t i = 0; i < args_.size(); ++i) { + if (opt_ == args_[i]) { return true; } } @@ -50,13 +50,13 @@ bool ArgHelper::is_enable_option(std::string opt_) const { std::string ArgHelper::get_option_value(std::string opt_) const { std::string ret = ""; - for (size_t i = 0; i < m_args.size(); ++i) { - if (opt_ == m_args[i]) { + for (size_t i = 0; i < args_.size(); ++i) { + if (opt_ == args_[i]) { size_t value_idx = ++i; - if (value_idx >= m_args.size()) { + if (value_idx >= args_.size()) { return ret; } - ret = m_args[value_idx]; + ret = args_[value_idx]; return ret; } } diff --git a/example/ArgHelper.h b/example/ArgHelper.h index bd1e15d37..bf391ef54 100644 --- a/example/ArgHelper.h +++ b/example/ArgHelper.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __ARG_HELPER_H__ -#define __ARG_HELPER_H__ +#ifndef ROCKETMQ_EXAMPLE_ARGHELPER_H_ +#define ROCKETMQ_EXAMPLE_ARGHELPER_H_ #include #include @@ -28,14 +28,15 @@ class ROCKETMQCLIENT_API ArgHelper { public: ArgHelper(int argc, char* argv[]); ArgHelper(std::string arg_str_); + std::string get_option(int idx_) const; bool is_enable_option(std::string opt_) const; std::string get_option_value(std::string opt_) const; private: - std::vector m_args; + std::vector args_; }; } // namespace rocketmq -#endif // __ARG_HELPER_H__ +#endif // ROCKETMQ_EXAMPLE_ARGHELPER_H_ diff --git a/example/AsyncProducer.cpp b/example/AsyncProducer.cpp index 130bc6759..9a5ea4521 100644 --- a/example/AsyncProducer.cpp +++ b/example/AsyncProducer.cpp @@ -47,7 +47,7 @@ class MyAutoDeleteSendCallback : public AutoDeleteSendCallback { }; void AsyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) { - while (g_msgCount.fetch_sub(1) > 0) { + while (g_msg_count.fetch_sub(1) > 0) { MQMessage msg(info->topic, // topic "*", // tag info->body); // body @@ -75,14 +75,14 @@ int main(int argc, char* argv[]) { producer->setGroupName(info.groupname); producer->setSendMsgTimeout(3000); producer->setRetryTimes(info.retrytimes); - producer->setRetryTimes4Async(info.retrytimes); + producer->setRetryTimesForAsync(info.retrytimes); producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker); producer->setTcpTransportTryLockTimeout(1000); producer->setTcpTransportConnectTimeout(400); producer->start(); std::vector> work_pool; - int msgcount = g_msgCount.load(); + int msgcount = g_msg_count.load(); g_finish = new latch(msgcount); g_tps.start(); diff --git a/example/BatchProducer.cpp b/example/BatchProducer.cpp index 7ed4cb7e9..68883e3e3 100644 --- a/example/BatchProducer.cpp +++ b/example/BatchProducer.cpp @@ -22,7 +22,7 @@ using namespace rocketmq; TpsReportService g_tps; void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) { - while (g_msgCount.fetch_sub(1) > 0) { + while (g_msg_count.fetch_sub(1) > 0) { std::vector msgs; MQMessage msg1(info->topic, "*", info->body); msg1.putProperty("property1", "value1"); @@ -67,14 +67,14 @@ int main(int argc, char* argv[]) { producer->setGroupName(info.groupname); producer->setSendMsgTimeout(3000); producer->setRetryTimes(info.retrytimes); - producer->setRetryTimes4Async(info.retrytimes); + producer->setRetryTimesForAsync(info.retrytimes); producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker); producer->setTcpTransportTryLockTimeout(1000); producer->setTcpTransportConnectTimeout(400); producer->start(); std::vector> work_pool; - int msgcount = g_msgCount.load(); + int msgcount = g_msg_count.load(); g_tps.start(); auto start = std::chrono::system_clock::now(); diff --git a/example/OrderlyProducer.cpp b/example/OrderlyProducer.cpp index b0b602bd9..45538ba40 100644 --- a/example/OrderlyProducer.cpp +++ b/example/OrderlyProducer.cpp @@ -33,7 +33,7 @@ class SelectMessageQueueByHash : public MessageQueueSelector { SelectMessageQueueByHash g_mySelector; void ProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) { - while (g_msgCount.fetch_sub(1) > 0) { + while (g_msg_count.fetch_sub(1) > 0) { MQMessage msg(info->topic, // topic "*", // tag info->body); // body @@ -68,14 +68,14 @@ int main(int argc, char* argv[]) { producer->setGroupName(info.groupname); producer->setSendMsgTimeout(3000); producer->setRetryTimes(info.retrytimes); - producer->setRetryTimes4Async(info.retrytimes); + producer->setRetryTimesForAsync(info.retrytimes); producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker); producer->setTcpTransportTryLockTimeout(1000); producer->setTcpTransportConnectTimeout(400); producer->start(); std::vector> work_pool; - int msgcount = g_msgCount.load(); + int msgcount = g_msg_count.load(); g_tps.start(); auto start = std::chrono::system_clock::now(); diff --git a/example/OrderlyPushConsumer.cpp b/example/OrderlyPushConsumer.cpp index edb35636e..02887c6e9 100644 --- a/example/OrderlyPushConsumer.cpp +++ b/example/OrderlyPushConsumer.cpp @@ -29,7 +29,7 @@ class MyMsgListener : public MessageListenerOrderly { virtual ~MyMsgListener() {} virtual ConsumeStatus consumeMessage(std::vector& msgs) override { - auto old = g_msgCount.fetch_sub(msgs.size()); + auto old = g_msg_count.fetch_sub(msgs.size()); if (old > 0) { for (size_t i = 0; i < msgs.size(); ++i) { g_tps.Increment(); diff --git a/example/PullConsumer.cpp b/example/PullConsumer.cpp index d1eab5ea9..f37620177 100644 --- a/example/PullConsumer.cpp +++ b/example/PullConsumer.cpp @@ -78,7 +78,7 @@ int main(int argc, char* argv[]) { do { try { PullResult result = consumer.pull(mq, "*", getMessageQueueOffset(mq), 32); - g_msgCount += result.msg_found_list().size(); + g_msg_count += result.msg_found_list().size(); std::cout << result.msg_found_list().size() << std::endl; // if pull request timeout or received NULL response, pullStatus will be // setted to BROKER_TIMEOUT, @@ -110,8 +110,8 @@ int main(int argc, char* argv[]) { auto end = std::chrono::system_clock::now(); auto duration = std::chrono::duration_cast(end - start); - std::cout << "msg count: " << g_msgCount.load() << "\n"; - std::cout << "per msg time: " << duration.count() / (double)g_msgCount.load() << "ms \n" + std::cout << "msg count: " << g_msg_count.load() << "\n"; + std::cout << "per msg time: " << duration.count() / (double)g_msg_count.load() << "ms \n" << "========================finished==============================\n"; consumer.shutdown(); diff --git a/example/PushConsumer.cpp b/example/PushConsumer.cpp index aa3b9cb65..ff9c055b5 100644 --- a/example/PushConsumer.cpp +++ b/example/PushConsumer.cpp @@ -29,7 +29,7 @@ class MyMsgListener : public MessageListenerConcurrently { virtual ~MyMsgListener() = default; ConsumeStatus consumeMessage(std::vector& msgs) override { - auto old = g_msgCount.fetch_sub(msgs.size()); + auto old = g_msg_count.fetch_sub(msgs.size()); if (old > 0) { for (size_t i = 0; i < msgs.size(); ++i) { g_tps.Increment(); diff --git a/example/RequestReply.cpp b/example/RequestReply.cpp index 8fb7a3caa..656418382 100644 --- a/example/RequestReply.cpp +++ b/example/RequestReply.cpp @@ -63,7 +63,7 @@ int main(int argc, char* argv[]) { producer.setNamesrvAddr(info.namesrv); producer.setSendMsgTimeout(3000); producer.setRetryTimes(info.retrytimes); - producer.setRetryTimes4Async(info.retrytimes); + producer.setRetryTimesForAsync(info.retrytimes); producer.setSendLatencyFaultEnable(!info.selectUnactiveBroker); producer.setTcpTransportTryLockTimeout(1000); producer.setTcpTransportConnectTimeout(400); @@ -93,7 +93,7 @@ int main(int argc, char* argv[]) { // std::this_thread::sleep_for(std::chrono::seconds(10)); - int msg_count = g_msgCount.load(); + int msg_count = g_msg_count.load(); for (int count = 0; count < msg_count; count++) { try { MQMessage msg(info.topic, "Hello world"); diff --git a/example/SyncProducer.cpp b/example/SyncProducer.cpp index 69b71a803..69461ee99 100644 --- a/example/SyncProducer.cpp +++ b/example/SyncProducer.cpp @@ -22,7 +22,7 @@ using namespace rocketmq; TpsReportService g_tps; void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) { - while (g_msgCount.fetch_sub(1) > 0) { + while (g_msg_count.fetch_sub(1) > 0) { MQMessage msg(info->topic, // topic "*", // tag info->body); // body @@ -56,14 +56,14 @@ int main(int argc, char* argv[]) { producer->setGroupName(info.groupname); producer->setSendMsgTimeout(3000); producer->setRetryTimes(info.retrytimes); - producer->setRetryTimes4Async(info.retrytimes); + producer->setRetryTimesForAsync(info.retrytimes); producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker); producer->setTcpTransportTryLockTimeout(1000); producer->setTcpTransportConnectTimeout(400); producer->start(); std::vector> work_pool; - int msgcount = g_msgCount.load(); + int msgcount = g_msg_count.load(); g_tps.start(); auto start = std::chrono::system_clock::now(); diff --git a/example/TransactionProducer.cpp b/example/TransactionProducer.cpp index bddb55955..ac2e2864a 100644 --- a/example/TransactionProducer.cpp +++ b/example/TransactionProducer.cpp @@ -36,7 +36,7 @@ class MyTransactionListener : public TransactionListener { }; void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, TransactionMQProducer* producer) { - int old = g_msgCount.fetch_sub(1); + int old = g_msg_count.fetch_sub(1); while (old > 0) { MQMessage msg(info->topic, // topic "*", // tag @@ -57,7 +57,7 @@ void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, TransactionMQProducer } catch (const MQException& e) { std::cout << "send failed: " << e.what() << std::endl; } - old = g_msgCount.fetch_sub(1); + old = g_msg_count.fetch_sub(1); } } @@ -73,7 +73,7 @@ int main(int argc, char* argv[]) { producer->setGroupName(info.groupname); producer->setSendMsgTimeout(3000); producer->setRetryTimes(info.retrytimes); - producer->setRetryTimes4Async(info.retrytimes); + producer->setRetryTimesForAsync(info.retrytimes); producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker); producer->setTcpTransportTryLockTimeout(1000); producer->setTcpTransportConnectTimeout(400); @@ -84,7 +84,7 @@ int main(int argc, char* argv[]) { producer->start(); std::vector> work_pool; - int msgcount = g_msgCount.load(); + int msgcount = g_msg_count.load(); g_tps.start(); auto start = std::chrono::system_clock::now(); diff --git a/example/common.h b/example/common.h index 393fda072..e3435add6 100644 --- a/example/common.h +++ b/example/common.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef ROCKETMQ_CLIENT4CPP_EXAMPLE_COMMON_H_ -#define ROCKETMQ_CLIENT4CPP_EXAMPLE_COMMON_H_ +#ifndef ROCKETMQ_EXAMPLE_COMMON_H_ +#define ROCKETMQ_EXAMPLE_COMMON_H_ #include #include @@ -33,7 +33,7 @@ #include "PullResult.h" -static std::atomic g_msgCount(1); +static std::atomic g_msg_count(1); class RocketmqSendAndConsumerArgs { public: @@ -126,7 +126,7 @@ static void PrintRocketmqSendAndConsumerArgs(const RocketmqSendAndConsumerArgs& << "topic: " << info.topic << std::endl << "groupname: " << info.groupname << std::endl << "produce content: " << info.body << std::endl - << "msg count: " << g_msgCount.load() << std::endl + << "msg count: " << g_msg_count.load() << std::endl << "thread count: " << info.thread_count << std::endl; } @@ -160,7 +160,7 @@ static bool ParseArgs(int argc, char* argv[], RocketmqSendAndConsumerArgs* info) info->topic.insert(0, optarg); break; case 'm': - g_msgCount.store(atoi(optarg)); + g_msg_count.store(atoi(optarg)); break; case 'c': info->body.insert(0, optarg); @@ -208,7 +208,7 @@ static bool ParseArgs(int argc, char* argv[], RocketmqSendAndConsumerArgs* info) info->thread_count = thread_count; } info->printMoreInfo = atoi(arg_help.get_option_value("-v").c_str()); - g_msgCount = atoi(arg_help.get_option_value("-m").c_str()); + g_msg_count = atoi(arg_help.get_option_value("-m").c_str()); #endif if (info->groupname.empty() || info->topic.empty() || info->namesrv.empty()) { std::cout << "please use -g to setup groupname and -t setup topic \n"; @@ -218,4 +218,4 @@ static bool ParseArgs(int argc, char* argv[], RocketmqSendAndConsumerArgs* info) return true; } -#endif // ROCKETMQ_CLIENT4CPP_EXAMPLE_COMMON_H_ +#endif // ROCKETMQ_EXAMPLE_COMMON_H_ diff --git a/include/AllocateMQStrategy.h b/include/AllocateMQStrategy.h index 4f60b297c..56c497d40 100644 --- a/include/AllocateMQStrategy.h +++ b/include/AllocateMQStrategy.h @@ -25,7 +25,7 @@ namespace rocketmq { /** - * AllocateMQStrategy - Interface of allocate MessageQueue + * AllocateMQStrategy - Interface for allocate MessageQueue */ class ROCKETMQCLIENT_API AllocateMQStrategy { public: diff --git a/include/Array.h b/include/Array.h index daa48667e..c1059cffa 100644 --- a/include/Array.h +++ b/include/Array.h @@ -44,7 +44,7 @@ template using array_element_t = typename array_traits::element_type; template -class Array { +class ROCKETMQCLIENT_API Array { public: using element_type = array_element_t; diff --git a/include/ConsumeType.h b/include/ConsumeType.h index ab5482925..fe51bb14e 100644 --- a/include/ConsumeType.h +++ b/include/ConsumeType.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __CONSUME_TYPE_H__ -#define __CONSUME_TYPE_H__ +#ifndef ROCKETMQ_CONSUMETYPE_H_ +#define ROCKETMQ_CONSUMETYPE_H_ namespace rocketmq { @@ -60,4 +60,4 @@ enum MessageModel { } // namespace rocketmq -#endif // __CONSUME_TYPE_H__ +#endif // ROCKETMQ_CONSUMETYPE_H_ diff --git a/include/DefaultMQProducer.h b/include/DefaultMQProducer.h index f0baf01f2..6405d6475 100644 --- a/include/DefaultMQProducer.h +++ b/include/DefaultMQProducer.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __DEFAULT_MQ_PRODUCER_H__ -#define __DEFAULT_MQ_PRODUCER_H__ +#ifndef ROCKETMQ_DEFAULTMQPRODUCER_H_ +#define ROCKETMQ_DEFAULTMQPRODUCER_H_ #include "DefaultMQProducerConfigProxy.h" #include "MQProducer.h" @@ -23,7 +23,9 @@ namespace rocketmq { -class ROCKETMQCLIENT_API DefaultMQProducer : public MQProducer, public DefaultMQProducerConfigProxy { +class ROCKETMQCLIENT_API DefaultMQProducer : public DefaultMQProducerConfigProxy, // base + public MQProducer // interface +{ public: DefaultMQProducer(const std::string& groupname); DefaultMQProducer(const std::string& groupname, RPCHookPtr rpcHook); @@ -98,4 +100,4 @@ class ROCKETMQCLIENT_API DefaultMQProducer : public MQProducer, public DefaultMQ } // namespace rocketmq -#endif // __DEFAULT_MQ_PRODUCER_H__ +#endif // ROCKETMQ_DEFAULTMQPRODUCER_H_ diff --git a/include/DefaultMQProducerConfig.h b/include/DefaultMQProducerConfig.h index fe396ee80..dcee17af8 100644 --- a/include/DefaultMQProducerConfig.h +++ b/include/DefaultMQProducerConfig.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __DEFAULT_MQ_PRODUCER_CONFIG_H__ -#define __DEFAULT_MQ_PRODUCER_CONFIG_H__ +#ifndef ROCKETMQ_DEFAULTMQPRODUCERCONFIG_H_ +#define ROCKETMQ_DEFAULTMQPRODUCERCONFIG_H_ #include "MQClientConfig.h" @@ -24,7 +24,11 @@ namespace rocketmq { class DefaultMQProducerConfig; typedef std::shared_ptr DefaultMQProducerConfigPtr; -class ROCKETMQCLIENT_API DefaultMQProducerConfig : virtual public MQClientConfig { +/** + * DefaultMQProducerConfig - config interface for DefaultMQProducer + */ +class ROCKETMQCLIENT_API DefaultMQProducerConfig : virtual public MQClientConfig // base interface +{ public: virtual ~DefaultMQProducerConfig() = default; @@ -50,8 +54,8 @@ class ROCKETMQCLIENT_API DefaultMQProducerConfig : virtual public MQClientConfig virtual int getRetryTimes() const = 0; virtual void setRetryTimes(int times) = 0; - virtual int getRetryTimes4Async() const = 0; - virtual void setRetryTimes4Async(int times) = 0; + virtual int getRetryTimesForAsync() const = 0; + virtual void setRetryTimesForAsync(int times) = 0; virtual bool isRetryAnotherBrokerWhenNotStoreOK() const = 0; virtual void setRetryAnotherBrokerWhenNotStoreOK(bool retryAnotherBrokerWhenNotStoreOK) = 0; @@ -62,4 +66,4 @@ class ROCKETMQCLIENT_API DefaultMQProducerConfig : virtual public MQClientConfig } // namespace rocketmq -#endif // __DEFAULT_MQ_PRODUCER_CONFIG_H__ +#endif // ROCKETMQ_DEFAULTMQPRODUCERCONFIG_H_ diff --git a/include/DefaultMQProducerConfigProxy.h b/include/DefaultMQProducerConfigProxy.h index 522decf15..deeb87945 100644 --- a/include/DefaultMQProducerConfigProxy.h +++ b/include/DefaultMQProducerConfigProxy.h @@ -14,67 +14,95 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __DEFAULT_MQ_PRODUCER_CONFI_PROXY_H__ -#define __DEFAULT_MQ_PRODUCER_CONFI_PROXY_H__ +#ifndef ROCKETMQ_DEFAULTMQPRODUCERCONFIPROXY_H_ +#define ROCKETMQ_DEFAULTMQPRODUCERCONFIPROXY_H_ #include "DefaultMQProducerConfig.h" #include "MQClientConfigProxy.h" namespace rocketmq { -class ROCKETMQCLIENT_API DefaultMQProducerConfigProxy : virtual public DefaultMQProducerConfig, - public MQClientConfigProxy { +/** + * DefaultMQProducerConfigProxy - proxy for DefaultMQProducerConfig + */ +class ROCKETMQCLIENT_API DefaultMQProducerConfigProxy : public MQClientConfigProxy, // base + virtual public DefaultMQProducerConfig // interface +{ public: - DefaultMQProducerConfigProxy(DefaultMQProducerConfigPtr producerConfig) - : MQClientConfigProxy(producerConfig), m_producerConfig(producerConfig) {} + DefaultMQProducerConfigProxy(DefaultMQProducerConfigPtr producerConfig) : MQClientConfigProxy(producerConfig) {} virtual ~DefaultMQProducerConfigProxy() = default; - DefaultMQProducerConfigPtr getRealConfig() const { return m_producerConfig; } - - int getMaxMessageSize() const override { return m_producerConfig->getMaxMessageSize(); } + inline int getMaxMessageSize() const override { + return dynamic_cast(client_config_.get())->getMaxMessageSize(); + } - void setMaxMessageSize(int maxMessageSize) override { m_producerConfig->setMaxMessageSize(maxMessageSize); } + inline void setMaxMessageSize(int maxMessageSize) override { + dynamic_cast(client_config_.get())->setMaxMessageSize(maxMessageSize); + } - int getCompressMsgBodyOverHowmuch() const override { return m_producerConfig->getCompressMsgBodyOverHowmuch(); } + inline int getCompressMsgBodyOverHowmuch() const override { + return dynamic_cast(client_config_.get())->getCompressMsgBodyOverHowmuch(); + } - void setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch) override { - m_producerConfig->setCompressMsgBodyOverHowmuch(compressMsgBodyOverHowmuch); + inline void setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch) override { + dynamic_cast(client_config_.get()) + ->setCompressMsgBodyOverHowmuch(compressMsgBodyOverHowmuch); } - int getCompressLevel() const override { return m_producerConfig->getCompressLevel(); } + inline int getCompressLevel() const override { + return dynamic_cast(client_config_.get())->getCompressLevel(); + } - void setCompressLevel(int compressLevel) override { m_producerConfig->setCompressLevel(compressLevel); } + inline void setCompressLevel(int compressLevel) override { + dynamic_cast(client_config_.get())->setCompressLevel(compressLevel); + } - int getSendMsgTimeout() const override { return m_producerConfig->getSendMsgTimeout(); } + inline int getSendMsgTimeout() const override { + return dynamic_cast(client_config_.get())->getSendMsgTimeout(); + } - void setSendMsgTimeout(int sendMsgTimeout) override { m_producerConfig->setSendMsgTimeout(sendMsgTimeout); } + inline void setSendMsgTimeout(int sendMsgTimeout) override { + dynamic_cast(client_config_.get())->setSendMsgTimeout(sendMsgTimeout); + } - int getRetryTimes() const override { return m_producerConfig->getRetryTimes(); } + inline int getRetryTimes() const override { + return dynamic_cast(client_config_.get())->getRetryTimes(); + } - void setRetryTimes(int times) override { m_producerConfig->setRetryTimes(times); } + inline void setRetryTimes(int times) override { + dynamic_cast(client_config_.get())->setRetryTimes(times); + } - int getRetryTimes4Async() const override { return m_producerConfig->getRetryTimes4Async(); } + inline int getRetryTimesForAsync() const override { + return dynamic_cast(client_config_.get())->getRetryTimesForAsync(); + } - void setRetryTimes4Async(int times) override { m_producerConfig->setRetryTimes4Async(times); } + inline void setRetryTimesForAsync(int times) override { + dynamic_cast(client_config_.get())->setRetryTimesForAsync(times); + } - bool isRetryAnotherBrokerWhenNotStoreOK() const override { - return m_producerConfig->isRetryAnotherBrokerWhenNotStoreOK(); + inline bool isRetryAnotherBrokerWhenNotStoreOK() const override { + return dynamic_cast(client_config_.get())->isRetryAnotherBrokerWhenNotStoreOK(); } - void setRetryAnotherBrokerWhenNotStoreOK(bool retryAnotherBrokerWhenNotStoreOK) override { - m_producerConfig->setRetryAnotherBrokerWhenNotStoreOK(retryAnotherBrokerWhenNotStoreOK); + inline void setRetryAnotherBrokerWhenNotStoreOK(bool retryAnotherBrokerWhenNotStoreOK) override { + dynamic_cast(client_config_.get()) + ->setRetryAnotherBrokerWhenNotStoreOK(retryAnotherBrokerWhenNotStoreOK); } - bool isSendLatencyFaultEnable() const override { return m_producerConfig->isSendLatencyFaultEnable(); } + inline bool isSendLatencyFaultEnable() const override { + return dynamic_cast(client_config_.get())->isSendLatencyFaultEnable(); + } - void setSendLatencyFaultEnable(bool sendLatencyFaultEnable) override { - m_producerConfig->setSendLatencyFaultEnable(sendLatencyFaultEnable); + inline void setSendLatencyFaultEnable(bool sendLatencyFaultEnable) override { + dynamic_cast(client_config_.get())->setSendLatencyFaultEnable(sendLatencyFaultEnable); } - private: - DefaultMQProducerConfigPtr m_producerConfig; + inline DefaultMQProducerConfigPtr real_config() const { + return std::dynamic_pointer_cast(client_config_); + } }; } // namespace rocketmq -#endif // __DEFAULT_MQ_PRODUCER_CONFI_PROXY_H__ +#endif // ROCKETMQ_DEFAULTMQPRODUCERCONFIPROXY_H_ diff --git a/include/DefaultMQPullConsumer.h b/include/DefaultMQPullConsumer.h index 8b4c71981..2f39e9705 100755 --- a/include/DefaultMQPullConsumer.h +++ b/include/DefaultMQPullConsumer.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __DEFAULT_MQ_PULL_CONSUMER_H__ -#define __DEFAULT_MQ_PULL_CONSUMER_H__ +#ifndef ROCCKETMQ_DEFAULTMQPULLCONSUMER_H_ +#define ROCCKETMQ_DEFAULTMQPULLCONSUMER_H_ #include #include @@ -78,4 +78,4 @@ class ROCKETMQCLIENT_API DefaultMQPullConsumer : public MQPullConsumer, public D } // namespace rocketmq -#endif // __DEFAULT_MQ_PULL_CONSUMER_H__ +#endif // ROCCKETMQ_DEFAULTMQPULLCONSUMER_H_ diff --git a/include/DefaultMQPullConsumerConfig.h b/include/DefaultMQPullConsumerConfig.h index 835c0762d..056e6d970 100644 --- a/include/DefaultMQPullConsumerConfig.h +++ b/include/DefaultMQPullConsumerConfig.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __DEFAULT_MQ_PULL_CONSUMER_CONFIG_H__ -#define __DEFAULT_MQ_PULL_CONSUMER_CONFIG_H__ +#ifndef ROCKETMQ_DEFAULTMQPULLCONSUMERCONFIG_H_ +#define ROCKETMQ_DEFAULTMQPULLCONSUMERCONFIG_H_ #include "AllocateMQStrategy.h" #include "ConsumeType.h" @@ -39,4 +39,4 @@ class ROCKETMQCLIENT_API DefaultMQPullConsumerConfig : virtual public MQClientCo } // namespace rocketmq -#endif // __DEFAULT_MQ_PULL_CONSUMER_CONFIG_H__ +#endif // ROCKETMQ_DEFAULTMQPULLCONSUMERCONFIG_H_ diff --git a/include/DefaultMQPullConsumerConfigProxy.h b/include/DefaultMQPullConsumerConfigProxy.h index 101acf4bf..63c73ec0e 100644 --- a/include/DefaultMQPullConsumerConfigProxy.h +++ b/include/DefaultMQPullConsumerConfigProxy.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __DEFAULT_MQ_PULL_CONSUMER_CONFIG_PROXY_H__ -#define __DEFAULT_MQ_PULL_CONSUMER_CONFIG_PROXY_H__ +#ifndef ROCKETMQ_DEFAULTMQPULLCONSUMERCONFIGPROXY_H_ +#define ROCKETMQ_DEFAULTMQPULLCONSUMERCONFIGPROXY_H_ #include "DefaultMQPullConsumerConfig.h" #include "MQClientConfigProxy.h" @@ -45,4 +45,4 @@ class ROCKETMQCLIENT_API DefaultMQPullConsumerConfigProxy : virtual public Defau } // namespace rocketmq -#endif // __DEFAULT_MQ_PULL_CONSUMER_CONFIG_PROXY_H__ +#endif // ROCKETMQ_DEFAULTMQPULLCONSUMERCONFIGPROXY_H_ diff --git a/include/DefaultMQPushConsumer.h b/include/DefaultMQPushConsumer.h index 650571247..b6276b452 100755 --- a/include/DefaultMQPushConsumer.h +++ b/include/DefaultMQPushConsumer.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __DEFAULT_MQ_PUSH_CONSUMER_H__ -#define __DEFAULT_MQ_PUSH_CONSUMER_H__ +#ifndef ROCKETMQ_DEFAULTMQPUSHCONSUMER_H_ +#define ROCKETMQ_DEFAULTMQPUSHCONSUMER_H_ #include "DefaultMQPushConsumerConfigProxy.h" #include "MQPushConsumer.h" @@ -23,7 +23,9 @@ namespace rocketmq { -class ROCKETMQCLIENT_API DefaultMQPushConsumer : public MQPushConsumer, public DefaultMQPushConsumerConfigProxy { +class ROCKETMQCLIENT_API DefaultMQPushConsumer : public DefaultMQPushConsumerConfigProxy, // base + public MQPushConsumer // interface +{ public: DefaultMQPushConsumer(const std::string& groupname); DefaultMQPushConsumer(const std::string& groupname, RPCHookPtr rpcHook); @@ -58,4 +60,4 @@ class ROCKETMQCLIENT_API DefaultMQPushConsumer : public MQPushConsumer, public D } // namespace rocketmq -#endif // __DEFAULT_MQ_PUSH_CONSUMER_H__ +#endif // ROCKETMQ_DEFAULTMQPUSHCONSUMER_H_ diff --git a/include/DefaultMQPushConsumerConfig.h b/include/DefaultMQPushConsumerConfig.h index 0c571cc2e..c15400744 100644 --- a/include/DefaultMQPushConsumerConfig.h +++ b/include/DefaultMQPushConsumerConfig.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_H__ -#define __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_H__ +#ifndef ROCKETMQ_DEFAULTMQPUSHCONSUMERCONFIG_H_ +#define ROCKETMQ_DEFAULTMQPUSHCONSUMERCONFIG_H_ #include "AllocateMQStrategy.h" #include "ConsumeType.h" @@ -26,7 +26,11 @@ namespace rocketmq { class DefaultMQPushConsumerConfig; typedef std::shared_ptr DefaultMQPushConsumerConfigPtr; -class ROCKETMQCLIENT_API DefaultMQPushConsumerConfig : virtual public MQClientConfig { +/** + * DefaultMQPushConsumerConfig - config for DefaultMQPushConsumer + */ +class ROCKETMQCLIENT_API DefaultMQPushConsumerConfig : virtual public MQClientConfig // base interface +{ public: virtual ~DefaultMQPushConsumerConfig() = default; @@ -36,8 +40,8 @@ class ROCKETMQCLIENT_API DefaultMQPushConsumerConfig : virtual public MQClientCo virtual ConsumeFromWhere getConsumeFromWhere() const = 0; virtual void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) = 0; - virtual std::string getConsumeTimestamp() = 0; - virtual void setConsumeTimestamp(std::string consumeTimestamp) = 0; + virtual const std::string& getConsumeTimestamp() const = 0; + virtual void setConsumeTimestamp(const std::string& consumeTimestamp) = 0; /** * consuming thread count, default value is cpu cores @@ -73,4 +77,4 @@ class ROCKETMQCLIENT_API DefaultMQPushConsumerConfig : virtual public MQClientCo } // namespace rocketmq -#endif // __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_H__ +#endif // ROCKETMQ_DEFAULTMQPUSHCONSUMERCONFIG_H_ diff --git a/include/DefaultMQPushConsumerConfigProxy.h b/include/DefaultMQPushConsumerConfigProxy.h index ef0c4de54..3ff22b311 100644 --- a/include/DefaultMQPushConsumerConfigProxy.h +++ b/include/DefaultMQPushConsumerConfigProxy.h @@ -14,83 +14,109 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_PROXY_H__ -#define __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_PROXY_H__ +#ifndef ROCKETMQ_DEFAULTMQPUSHCONSUMERCONFIGPROXY_H_ +#define ROCKETMQ_DEFAULTMQPUSHCONSUMERCONFIGPROXY_H_ #include "DefaultMQPushConsumerConfig.h" #include "MQClientConfigProxy.h" namespace rocketmq { -class ROCKETMQCLIENT_API DefaultMQPushConsumerConfigProxy : virtual public DefaultMQPushConsumerConfig, - public MQClientConfigProxy { +class ROCKETMQCLIENT_API DefaultMQPushConsumerConfigProxy : public MQClientConfigProxy, // base + virtual public DefaultMQPushConsumerConfig // interface +{ public: DefaultMQPushConsumerConfigProxy(DefaultMQPushConsumerConfigPtr consumerConfig) - : MQClientConfigProxy(consumerConfig), m_consumerConfig(consumerConfig) {} + : MQClientConfigProxy(consumerConfig) {} virtual ~DefaultMQPushConsumerConfigProxy() = default; - DefaultMQPushConsumerConfigPtr getRealConfig() const { return m_consumerConfig; } - - MessageModel getMessageModel() const override { return m_consumerConfig->getMessageModel(); } + inline MessageModel getMessageModel() const override { + return dynamic_cast(client_config_.get())->getMessageModel(); + } - void setMessageModel(MessageModel messageModel) override { m_consumerConfig->setMessageModel(messageModel); } + inline void setMessageModel(MessageModel messageModel) override { + dynamic_cast(client_config_.get())->setMessageModel(messageModel); + } - ConsumeFromWhere getConsumeFromWhere() const override { return m_consumerConfig->getConsumeFromWhere(); } + inline ConsumeFromWhere getConsumeFromWhere() const override { + return dynamic_cast(client_config_.get())->getConsumeFromWhere(); + } - void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) override { - m_consumerConfig->setConsumeFromWhere(consumeFromWhere); + inline void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) override { + dynamic_cast(client_config_.get())->setConsumeFromWhere(consumeFromWhere); } - std::string getConsumeTimestamp() override { return m_consumerConfig->getConsumeTimestamp(); } + inline const std::string& getConsumeTimestamp() const override { + return dynamic_cast(client_config_.get())->getConsumeTimestamp(); + } - void setConsumeTimestamp(std::string consumeTimestamp) override { - m_consumerConfig->setConsumeTimestamp(consumeTimestamp); + inline void setConsumeTimestamp(const std::string& consumeTimestamp) override { + dynamic_cast(client_config_.get())->setConsumeTimestamp(consumeTimestamp); } - int getConsumeThreadNum() const override { return m_consumerConfig->getConsumeThreadNum(); } + inline int getConsumeThreadNum() const override { + return dynamic_cast(client_config_.get())->getConsumeThreadNum(); + } - void setConsumeThreadNum(int threadNum) override { return m_consumerConfig->setConsumeThreadNum(threadNum); } + inline void setConsumeThreadNum(int threadNum) override { + dynamic_cast(client_config_.get())->setConsumeThreadNum(threadNum); + } - int getConsumeMessageBatchMaxSize() const override { return m_consumerConfig->getConsumeMessageBatchMaxSize(); } + inline int getConsumeMessageBatchMaxSize() const override { + return dynamic_cast(client_config_.get())->getConsumeMessageBatchMaxSize(); + } - void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) override { - m_consumerConfig->setConsumeMessageBatchMaxSize(consumeMessageBatchMaxSize); + inline void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) override { + dynamic_cast(client_config_.get()) + ->setConsumeMessageBatchMaxSize(consumeMessageBatchMaxSize); } - int getMaxCacheMsgSizePerQueue() const override { return m_consumerConfig->getMaxCacheMsgSizePerQueue(); } + inline int getMaxCacheMsgSizePerQueue() const override { + return dynamic_cast(client_config_.get())->getMaxCacheMsgSizePerQueue(); + } - void setMaxCacheMsgSizePerQueue(int maxCacheSize) override { - m_consumerConfig->setMaxCacheMsgSizePerQueue(maxCacheSize); + inline void setMaxCacheMsgSizePerQueue(int maxCacheSize) override { + dynamic_cast(client_config_.get())->setMaxCacheMsgSizePerQueue(maxCacheSize); } - int getAsyncPullTimeout() const override { return m_consumerConfig->getAsyncPullTimeout(); } + inline int getAsyncPullTimeout() const override { + return dynamic_cast(client_config_.get())->getAsyncPullTimeout(); + } - void setAsyncPullTimeout(int asyncPullTimeout) override { m_consumerConfig->setAsyncPullTimeout(asyncPullTimeout); } + inline void setAsyncPullTimeout(int asyncPullTimeout) override { + dynamic_cast(client_config_.get())->setAsyncPullTimeout(asyncPullTimeout); + } - int getMaxReconsumeTimes() const override { return m_consumerConfig->getMaxReconsumeTimes(); } + inline int getMaxReconsumeTimes() const override { + return dynamic_cast(client_config_.get())->getMaxReconsumeTimes(); + } - void setMaxReconsumeTimes(int maxReconsumeTimes) override { - m_consumerConfig->setMaxReconsumeTimes(maxReconsumeTimes); + inline void setMaxReconsumeTimes(int maxReconsumeTimes) override { + dynamic_cast(client_config_.get())->setMaxReconsumeTimes(maxReconsumeTimes); } - long getPullTimeDelayMillsWhenException() const override { - return m_consumerConfig->getPullTimeDelayMillsWhenException(); + inline long getPullTimeDelayMillsWhenException() const override { + return dynamic_cast(client_config_.get())->getPullTimeDelayMillsWhenException(); } - void setPullTimeDelayMillsWhenException(long pullTimeDelayMillsWhenException) override { - m_consumerConfig->setPullTimeDelayMillsWhenException(pullTimeDelayMillsWhenException); + inline void setPullTimeDelayMillsWhenException(long pullTimeDelayMillsWhenException) override { + dynamic_cast(client_config_.get()) + ->setPullTimeDelayMillsWhenException(pullTimeDelayMillsWhenException); } - AllocateMQStrategy* getAllocateMQStrategy() const override { return m_consumerConfig->getAllocateMQStrategy(); } + inline AllocateMQStrategy* getAllocateMQStrategy() const override { + return dynamic_cast(client_config_.get())->getAllocateMQStrategy(); + } - void setAllocateMQStrategy(AllocateMQStrategy* strategy) override { - m_consumerConfig->setAllocateMQStrategy(strategy); + inline void setAllocateMQStrategy(AllocateMQStrategy* strategy) override { + dynamic_cast(client_config_.get())->setAllocateMQStrategy(strategy); } - private: - DefaultMQPushConsumerConfigPtr m_consumerConfig; + inline DefaultMQPushConsumerConfigPtr real_config() const { + return std::dynamic_pointer_cast(client_config_); + } }; } // namespace rocketmq -#endif // __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_PROXY_H__ +#endif // ROCKETMQ_DEFAULTMQPUSHCONSUMERCONFIGPROXY_H_ diff --git a/include/MQAdmin.h b/include/MQAdmin.h index eb681fb57..dff6f5111 100644 --- a/include/MQAdmin.h +++ b/include/MQAdmin.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_ADMIN_H__ -#define __MQ_ADMIN_H__ +#ifndef ROCKETMQ_MQADMIN_H_ +#define ROCKETMQ_MQADMIN_H_ #include "MQMessageExt.h" #include "MQMessageQueue.h" @@ -100,4 +100,4 @@ class ROCKETMQCLIENT_API MQAdmin { } // namespace rocketmq -#endif // __MQ_ADMIN_H__ +#endif // ROCKETMQ_MQADMIN_H_ diff --git a/include/MQClientConfig.h b/include/MQClientConfig.h index 9cc5bc636..c93dd2b18 100644 --- a/include/MQClientConfig.h +++ b/include/MQClientConfig.h @@ -14,11 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_CLIENT_CONFIG_H__ -#define __MQ_CLIENT_CONFIG_H__ +#ifndef ROCKETMQ_MQCLIENTCONFIG_H_ +#define ROCKETMQ_MQCLIENTCONFIG_H_ -#include -#include +#include // std::shared_ptr +#include // std::string #include "RocketMQClient.h" @@ -28,7 +28,7 @@ class MQClientConfig; typedef std::shared_ptr MQClientConfigPtr; /** - * MQ Client Config + * MQClientConfig - config interface for MQClient */ class ROCKETMQCLIENT_API MQClientConfig { public: @@ -72,4 +72,4 @@ class ROCKETMQCLIENT_API MQClientConfig { } // namespace rocketmq -#endif // __MQ_CLIENT_CONFIG_H__ +#endif // ROCKETMQ_MQCLIENTCONFIG_H_ diff --git a/include/MQClientConfigProxy.h b/include/MQClientConfigProxy.h index 5714aadab..2e3b33235 100644 --- a/include/MQClientConfigProxy.h +++ b/include/MQClientConfigProxy.h @@ -14,60 +14,72 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_CLIENT_CONFIG_PROXY_H__ -#define __MQ_CLIENT_CONFIG_PROXY_H__ +#ifndef ROCKETMQ_MQCLIENTCONFIGPROXY_H_ +#define ROCKETMQ_MQCLIENTCONFIGPROXY_H_ #include "MQClientConfig.h" namespace rocketmq { -class ROCKETMQCLIENT_API MQClientConfigProxy : virtual public MQClientConfig { +/** + * MQClientConfigProxy - proxy for MQClientConfig + */ +class ROCKETMQCLIENT_API MQClientConfigProxy : virtual public MQClientConfig // interface +{ public: - MQClientConfigProxy(MQClientConfigPtr clientConfig) : m_clientConfig(clientConfig) {} + MQClientConfigProxy(MQClientConfigPtr clientConfig) : client_config_(clientConfig) {} virtual ~MQClientConfigProxy() = default; - MQClientConfigPtr getRealConfig() const { return m_clientConfig; } - - std::string buildMQClientId() const override { return m_clientConfig->buildMQClientId(); } + inline std::string buildMQClientId() const override { return client_config_->buildMQClientId(); } - const std::string& getGroupName() const override { return m_clientConfig->getGroupName(); } + inline const std::string& getGroupName() const override { return client_config_->getGroupName(); } - void setGroupName(const std::string& groupname) override { m_clientConfig->setGroupName(groupname); } + inline void setGroupName(const std::string& groupname) override { client_config_->setGroupName(groupname); } - const std::string& getNamesrvAddr() const override { return m_clientConfig->getNamesrvAddr(); } + inline const std::string& getNamesrvAddr() const override { return client_config_->getNamesrvAddr(); } - void setNamesrvAddr(const std::string& namesrvAddr) override { m_clientConfig->setNamesrvAddr(namesrvAddr); } + inline void setNamesrvAddr(const std::string& namesrvAddr) override { client_config_->setNamesrvAddr(namesrvAddr); } - const std::string& getInstanceName() const override { return m_clientConfig->getInstanceName(); } + inline const std::string& getInstanceName() const override { return client_config_->getInstanceName(); } - void setInstanceName(const std::string& instanceName) override { m_clientConfig->setInstanceName(instanceName); } + inline void setInstanceName(const std::string& instanceName) override { + client_config_->setInstanceName(instanceName); + } - void changeInstanceNameToPID() override { m_clientConfig->changeInstanceNameToPID(); } + inline void changeInstanceNameToPID() override { client_config_->changeInstanceNameToPID(); } - const std::string& getUnitName() const override { return m_clientConfig->getUnitName(); } + inline const std::string& getUnitName() const override { return client_config_->getUnitName(); } - void setUnitName(std::string unitName) override { m_clientConfig->setUnitName(unitName); } + inline void setUnitName(std::string unitName) override { client_config_->setUnitName(unitName); } - int getTcpTransportWorkerThreadNum() const override { return m_clientConfig->getTcpTransportWorkerThreadNum(); } + inline int getTcpTransportWorkerThreadNum() const override { + return client_config_->getTcpTransportWorkerThreadNum(); + } - void setTcpTransportWorkerThreadNum(int num) override { m_clientConfig->setTcpTransportWorkerThreadNum(num); } + inline void setTcpTransportWorkerThreadNum(int num) override { client_config_->setTcpTransportWorkerThreadNum(num); } - uint64_t getTcpTransportConnectTimeout() const override { return m_clientConfig->getTcpTransportConnectTimeout(); } + inline uint64_t getTcpTransportConnectTimeout() const override { + return client_config_->getTcpTransportConnectTimeout(); + } - void setTcpTransportConnectTimeout(uint64_t timeout) override { - m_clientConfig->setTcpTransportConnectTimeout(timeout); + inline void setTcpTransportConnectTimeout(uint64_t timeout) override { + client_config_->setTcpTransportConnectTimeout(timeout); } - uint64_t getTcpTransportTryLockTimeout() const override { return m_clientConfig->getTcpTransportTryLockTimeout(); } + inline uint64_t getTcpTransportTryLockTimeout() const override { + return client_config_->getTcpTransportTryLockTimeout(); + } - void setTcpTransportTryLockTimeout(uint64_t timeout) override { - m_clientConfig->setTcpTransportTryLockTimeout(timeout); + inline void setTcpTransportTryLockTimeout(uint64_t timeout) override { + client_config_->setTcpTransportTryLockTimeout(timeout); } - private: - MQClientConfigPtr m_clientConfig; + inline MQClientConfigPtr real_config() const { return client_config_; } + + protected: + MQClientConfigPtr client_config_; }; } // namespace rocketmq -#endif // __MQ_CLIENT_CONFIG_PROXY_H__ +#endif // ROCKETMQ_MQCLIENTCONFIGPROXY_H_ diff --git a/include/MQConsumer.h b/include/MQConsumer.h index 54ff57605..49c0b4837 100755 --- a/include/MQConsumer.h +++ b/include/MQConsumer.h @@ -14,18 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_CONSUMER_H__ -#define __MQ_CONSUMER_H__ - -#include -#include +#ifndef ROCKETMQ_MQCONSUMER_H_ +#define ROCKETMQ_MQCONSUMER_H_ #include "MQMessageExt.h" namespace rocketmq { /** - * MQ Consumer API + * MQConsumer - interface for consumer */ class ROCKETMQCLIENT_API MQConsumer { public: @@ -42,4 +39,4 @@ class ROCKETMQCLIENT_API MQConsumer { } // namespace rocketmq -#endif // __MQ_CONSUMER_H__ +#endif // ROCKETMQ_MQCONSUMER_H_ diff --git a/include/MQClientException.h b/include/MQException.h similarity index 79% rename from include/MQClientException.h rename to include/MQException.h index 4e2498dbb..c3f14dbc4 100644 --- a/include/MQClientException.h +++ b/include/MQException.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_CLIENT_EXCEPTION_H__ -#define __MQ_CLIENT_EXCEPTION_H__ +#ifndef ROCKETMQ_MQEXCEPTION_H_ +#define ROCKETMQ_MQEXCEPTION_H_ #include #include @@ -26,6 +26,9 @@ namespace rocketmq { +/** + * MQException - base exception + */ class ROCKETMQCLIENT_API MQException : public std::exception { public: MQException(const std::string& msg, int error, const char* file, int line) noexcept @@ -39,47 +42,47 @@ class ROCKETMQCLIENT_API MQException : public std::exception { int error, std::exception_ptr cause, const char* file, - int line) noexcept : m_type(type), - m_msg(msg), - m_error(error), - m_cause(cause), - m_file(file), - m_line(line) {} + int line) noexcept : type_(type), + msg_(msg), + error_(error), + cause_(cause), + file_(file), + line_(line) {} virtual ~MQException() noexcept = default; const char* what() const noexcept override { - if (m_what_.empty()) { + if (what_.empty()) { std::stringstream ss; - ss << "[" << m_type << "] msg: " << m_msg << ", error: " << m_error << ", in <" << m_file << ":" << m_line << ">"; - m_what_ = ss.str(); + ss << "[" << type_ << "] msg: " << msg_ << ", error: " << error_ << ", in <" << file_ << ":" << line_ << ">"; + what_ = ss.str(); } - return m_what_.c_str(); + return what_.c_str(); } - const char* GetType() const noexcept { return m_type.c_str(); } + const char* GetType() const noexcept { return type_.c_str(); } - const std::string& GetErrorMessage() const noexcept { return m_msg; } - const char* GetMsg() const noexcept { return m_msg.c_str(); } + const std::string& GetErrorMessage() const noexcept { return msg_; } + const char* GetMsg() const noexcept { return msg_.c_str(); } - int GetError() const noexcept { return m_error; } + int GetError() const noexcept { return error_; } - std::exception_ptr GetCause() const { return m_cause; } + std::exception_ptr GetCause() const { return cause_; } - const char* GetFile() const noexcept { return m_file.c_str(); } - int GetLine() const noexcept { return m_line; } + const char* GetFile() const noexcept { return file_.c_str(); } + int GetLine() const noexcept { return line_; } protected: - std::string m_type; - std::string m_msg; - int m_error; + std::string type_; + std::string msg_; + int error_; - std::exception_ptr m_cause; + std::exception_ptr cause_; - std::string m_file; - int m_line; + std::string file_; + int line_; - mutable std::string m_what_; + mutable std::string what_; }; inline std::ostream& operator<<(std::ostream& os, const MQException& e) { @@ -126,4 +129,4 @@ DEFINE_MQEXCEPTION(RequestTimeoutException) } // namespace rocketmq -#endif // __MQ_CLIENT_EXCEPTION_H__ +#endif // ROCKETMQ_MQEXCEPTION_H_ diff --git a/include/MQMessage.h b/include/MQMessage.h index 5fc577612..c0786a726 100644 --- a/include/MQMessage.h +++ b/include/MQMessage.h @@ -25,7 +25,7 @@ namespace rocketmq { /** - * MQMessage - Reference of Message + * MQMessage - wrapper for Message */ class ROCKETMQCLIENT_API MQMessage : virtual public Message // interface { diff --git a/include/MQMessageConst.h b/include/MQMessageConst.h index 071d94d86..a12561c1e 100644 --- a/include/MQMessageConst.h +++ b/include/MQMessageConst.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_MESSAGE_CONST_H__ -#define __MQ_MESSAGE_CONST_H__ +#ifndef ROCKETMQ_MQMESSAGECONST_H_ +#define ROCKETMQ_MQMESSAGECONST_H_ #include // std::string @@ -68,4 +68,4 @@ class ROCKETMQCLIENT_API MQMessageConst { } // namespace rocketmq -#endif // __MQ_MESSAGE_CONST_H__ +#endif // ROCKETMQ_MQMESSAGECONST_H_ diff --git a/include/MQMessageExt.h b/include/MQMessageExt.h index a6d872328..8d499179e 100644 --- a/include/MQMessageExt.h +++ b/include/MQMessageExt.h @@ -23,7 +23,7 @@ namespace rocketmq { /** - * MQMessageExt - Reference of MessageExt + * MQMessageExt - wrapper for MessageExt */ class ROCKETMQCLIENT_API MQMessageExt : public MQMessage, // base virtual public MessageExt // interface diff --git a/include/MQMessageListener.h b/include/MQMessageListener.h index 11287f9ee..7db5c383a 100644 --- a/include/MQMessageListener.h +++ b/include/MQMessageListener.h @@ -14,10 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MESSAGE_LISTENER_H__ -#define __MESSAGE_LISTENER_H__ - -#include +#ifndef ROCKETMQ_MQMESSAGELISTENER_H_ +#define ROCKETMQ_MQMESSAGELISTENER_H_ #include "MQMessageExt.h" @@ -32,6 +30,9 @@ enum ConsumeStatus { enum MessageListenerType { messageListenerDefaultly = 0, messageListenerOrderly = 1, messageListenerConcurrently = 2 }; +/** + * MQMessageListener - listener interface for MQPushConsumer + */ class ROCKETMQCLIENT_API MQMessageListener { public: virtual ~MQMessageListener() = default; @@ -41,11 +42,17 @@ class ROCKETMQCLIENT_API MQMessageListener { virtual ConsumeStatus consumeMessage(std::vector& msgs) { return RECONSUME_LATER; }; }; +/** + * MessageListenerConcurrently - listener interface for MQPushConsumer in Concurrently mode + */ class ROCKETMQCLIENT_API MessageListenerConcurrently : virtual public MQMessageListener { public: MessageListenerType getMessageListenerType() override final { return messageListenerConcurrently; } }; +/** + * MessageListenerOrderly - listener interface for MQPushConsumer in Orderly mode + */ class ROCKETMQCLIENT_API MessageListenerOrderly : virtual public MQMessageListener { public: MessageListenerType getMessageListenerType() override final { return messageListenerOrderly; } @@ -53,4 +60,4 @@ class ROCKETMQCLIENT_API MessageListenerOrderly : virtual public MQMessageListen } // namespace rocketmq -#endif // __MESSAGE_LISTENER_H__ +#endif // ROCKETMQ_MQMESSAGELISTENER_H_ diff --git a/include/MQMessageQueue.h b/include/MQMessageQueue.h index bfe9fb901..42bd6e45f 100644 --- a/include/MQMessageQueue.h +++ b/include/MQMessageQueue.h @@ -43,14 +43,14 @@ class ROCKETMQCLIENT_API MQMessageQueue { std::string toString() const; public: - inline const std::string& getTopic() const { return topic_; }; - inline void setTopic(const std::string& topic) { topic_ = topic; }; + inline const std::string& topic() const { return topic_; }; + inline void set_topic(const std::string& topic) { topic_ = topic; }; - inline const std::string& getBrokerName() const { return broker_name_; }; - inline void setBrokerName(const std::string& broker_name) { broker_name_ = broker_name; }; + inline const std::string& broker_name() const { return broker_name_; }; + inline void set_broker_name(const std::string& broker_name) { broker_name_ = broker_name; }; - inline int getQueueId() const { return queue_id_; }; - inline void setQueueId(int queue_id) { queue_id_ = queue_id; }; + inline int queue_id() const { return queue_id_; }; + inline void set_queue_id(int queue_id) { queue_id_ = queue_id; }; private: std::string topic_; diff --git a/include/MQProducer.h b/include/MQProducer.h index 69caaecf8..6fc281e81 100644 --- a/include/MQProducer.h +++ b/include/MQProducer.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_PRODUCER_H__ -#define __MQ_PRODUCER_H__ +#ifndef ROCKETMQ_MQPRODUCER_H_ +#define ROCKETMQ_MQPRODUCER_H_ #include "MQSelector.h" #include "RequestCallback.h" @@ -26,7 +26,7 @@ namespace rocketmq { /** - * MQ Producer API + * MQProducer - interface for producer */ class ROCKETMQCLIENT_API MQProducer { public: @@ -87,4 +87,4 @@ class ROCKETMQCLIENT_API MQProducer { } // namespace rocketmq -#endif // __MQ_PRODUCER_H__ +#endif // ROCKETMQ_MQPRODUCER_H_ diff --git a/include/MQPullConsumer.h b/include/MQPullConsumer.h index 557143127..2545116d6 100644 --- a/include/MQPullConsumer.h +++ b/include/MQPullConsumer.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_PULL_CONSUMER_H__ -#define __MQ_PULL_CONSUMER_H__ +#ifndef ROCKETMQ_MQPULLCONSUMER_H_ +#define ROCKETMQ_MQPULLCONSUMER_H_ #include "MQConsumer.h" #include "MQueueListener.h" @@ -100,4 +100,4 @@ class ROCKETMQCLIENT_API MQPullConsumer : public MQConsumer { } // namespace rocketmq -#endif // __MQ_PULL_CONSUMER_H__ +#endif // ROCKETMQ_MQPULLCONSUMER_H_ diff --git a/include/MQPushConsumer.h b/include/MQPushConsumer.h index 8d59f09f4..0ee8aaa7e 100644 --- a/include/MQPushConsumer.h +++ b/include/MQPushConsumer.h @@ -14,15 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_PUSH_CONSUMER_H__ -#define __MQ_PUSH_CONSUMER_H__ +#ifndef ROCKETMQ_MQPUSHCONSUMER_H_ +#define ROCKETMQ_MQPUSHCONSUMER_H_ #include "MQConsumer.h" #include "MQMessageListener.h" namespace rocketmq { -class ROCKETMQCLIENT_API MQPushConsumer : public MQConsumer { +/** + * MQPushConsumer - interface for push consumer + */ +class ROCKETMQCLIENT_API MQPushConsumer : public MQConsumer // base interface +{ public: // MQPushConsumer in Java // [[deprecated]] virtual void registerMessageListener(MQMessageListener* messageListener) = 0; @@ -40,4 +44,4 @@ class ROCKETMQCLIENT_API MQPushConsumer : public MQConsumer { } // namespace rocketmq -#endif // __MQ_PUSH_CONSUMER_H__ +#endif // ROCKETMQ_MQPUSHCONSUMER_H_ diff --git a/include/MQSelector.h b/include/MQSelector.h index f5de65452..1a5a88fb9 100644 --- a/include/MQSelector.h +++ b/include/MQSelector.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_SELECTOR_H__ -#define __MQ_SELECTOR_H__ +#ifndef ROCKETMQ_MQSELECTOR_H_ +#define ROCKETMQ_MQSELECTOR_H_ #include "MQMessage.h" #include "MQMessageQueue.h" @@ -23,7 +23,7 @@ namespace rocketmq { /** - * MQ Selector Interface + * MessageQueueSelector - interface for MessageQueue selector */ class ROCKETMQCLIENT_API MessageQueueSelector { public: @@ -34,4 +34,4 @@ class ROCKETMQCLIENT_API MessageQueueSelector { } // namespace rocketmq -#endif // __MQ_SELECTOR_H__ +#endif // ROCKETMQ_MQSELECTOR_H_ diff --git a/include/Message.h b/include/Message.h index e4f21c483..fe6bd3cef 100644 --- a/include/Message.h +++ b/include/Message.h @@ -30,7 +30,7 @@ class Message; typedef std::shared_ptr MessagePtr; /** - * Message Interface + * Message - interface for messgae */ class ROCKETMQCLIENT_API Message { public: diff --git a/include/MessageExt.h b/include/MessageExt.h index 172aa9244..44b37a854 100644 --- a/include/MessageExt.h +++ b/include/MessageExt.h @@ -34,7 +34,7 @@ class MessageExt; typedef std::shared_ptr MessageExtPtr; /** - * MessageExt - Message extend class, which was generated on broker + * MessageExt - Message extend interface, which was generated on broker */ class ROCKETMQCLIENT_API MessageExt : virtual public Message // base interface { diff --git a/include/MessageUtil.h b/include/MessageUtil.h index ba21b70a1..f26d085ab 100644 --- a/include/MessageUtil.h +++ b/include/MessageUtil.h @@ -17,11 +17,14 @@ #ifndef ROCKETMQ_MESSAGEUTIL_H_ #define ROCKETMQ_MESSAGEUTIL_H_ -#include "MQClientException.h" +#include "MQException.h" #include "MQMessage.h" namespace rocketmq { +/** + * MessageUtil - util for Request-Reply mode + */ class ROCKETMQCLIENT_API MessageUtil { public: static MQMessage createReplyMessage(const Message& requestMessage, const std::string& body); diff --git a/src/common/NamesrvConfig.h b/include/OffsetStore.h similarity index 50% rename from src/common/NamesrvConfig.h rename to include/OffsetStore.h index e74a6b35e..05ae0b4fa 100644 --- a/src/common/NamesrvConfig.h +++ b/include/OffsetStore.h @@ -14,37 +14,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __NAMESRV_CONFIG_H__ -#define __NAMESRV_CONFIG_H__ +#ifndef ROCKETMQ_OFFSETSTORE_H_ +#define ROCKETMQ_OFFSETSTORE_H_ -#include +#include // std::vector -#include "UtilAll.h" +#include "MQMessageQueue.h" namespace rocketmq { -class NamesrvConfig { - public: - NamesrvConfig() { - char* home = std::getenv(ROCKETMQ_HOME_ENV.c_str()); - if (home != nullptr) { - m_rocketmqHome = home; - } - } - - const std::string& getRocketmqHome() const { return m_rocketmqHome; } - - void setRocketmqHome(const std::string& rocketmqHome) { m_rocketmqHome = rocketmqHome; } - - const std::string& getKvConfigPath() const { return m_kvConfigPath; } - - void setKvConfigPath(const std::string& kvConfigPath) { m_kvConfigPath = kvConfigPath; } +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, +}; - private: - std::string m_rocketmqHome; - std::string m_kvConfigPath; +class ROCKETMQCLIENT_API OffsetStore { + public: + virtual ~OffsetStore() = default; + + virtual void load() = 0; + virtual void updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) = 0; + virtual int64_t readOffset(const MQMessageQueue& mq, ReadOffsetType type) = 0; + virtual void persist(const MQMessageQueue& mq) = 0; + virtual void persistAll(const std::vector& mq) = 0; + virtual void removeOffset(const MQMessageQueue& mq) = 0; }; } // namespace rocketmq -#endif // __NAMESRV_CONFIG_H__ +#endif // ROCKETMQ_CONSUMER_OFFSETSTORE_H_ diff --git a/include/PullCallback.h b/include/PullCallback.h index 16fe81e05..2e733e18e 100755 --- a/include/PullCallback.h +++ b/include/PullCallback.h @@ -14,16 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __PULL_CALLBACK_H__ -#define __PULL_CALLBACK_H__ +#ifndef ROCKETMQ_PULLCALLBACK_H_ +#define ROCKETMQ_PULLCALLBACK_H_ -#include "MQClientException.h" +#include "MQException.h" #include "PullResult.h" namespace rocketmq { enum PullCallbackType { PULL_CALLBACK_TYPE_SIMPLE = 0, PULL_CALLBACK_TYPE_AUTO_DELETE = 1 }; +/** + * PullCallback - callback interface for async pull + */ class ROCKETMQCLIENT_API PullCallback { public: virtual ~PullCallback() = default; @@ -34,6 +37,11 @@ class ROCKETMQCLIENT_API PullCallback { virtual PullCallbackType getPullCallbackType() const { return PULL_CALLBACK_TYPE_SIMPLE; } }; +/** + * AutoDeletePullCallback - callback interface for async pull + * + * the object of AutoDeletePullCallback will be deleted automatically by SDK after invoke callback interface + */ class ROCKETMQCLIENT_API AutoDeletePullCallback : public PullCallback { public: PullCallbackType getPullCallbackType() const override final { return PULL_CALLBACK_TYPE_AUTO_DELETE; } @@ -41,4 +49,4 @@ class ROCKETMQCLIENT_API AutoDeletePullCallback : public PullCallback { } // namespace rocketmq -#endif // __PULL_CALLBACK_H__ +#endif // ROCKETMQ_PULLCALLBACK_H_ diff --git a/include/QueryResult.h b/include/QueryResult.h index 1939fd33b..b24d9e0d1 100644 --- a/include/QueryResult.h +++ b/include/QueryResult.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __QUERY_RESULT_H__ -#define __QUERY_RESULT_H__ +#ifndef ROCKETMQ_QUERYRESULT_H_ +#define ROCKETMQ_QUERYRESULT_H_ #include "MQMessageExt.h" @@ -39,4 +39,4 @@ class ROCKETMQCLIENT_API QueryResult { } // namespace rocketmq -#endif // __QUERY_RESULT_H__ +#endif // ROCKETMQ_QUERYRESULT_H_ diff --git a/include/RemotingCommand.h b/include/RemotingCommand.h index 6ad14e867..68847b3b8 100644 --- a/include/RemotingCommand.h +++ b/include/RemotingCommand.h @@ -25,10 +25,13 @@ #include "ByteArray.h" #include "CommandCustomHeader.h" -#include "MQClientException.h" +#include "MQException.h" namespace rocketmq { +/** + * RemotingCommand - rocketmq rpc protocol + */ class ROCKETMQCLIENT_API RemotingCommand { public: static int32_t createNewRequestId(); diff --git a/include/RequestCallback.h b/include/RequestCallback.h index d79e95594..a6dfec4ed 100644 --- a/include/RequestCallback.h +++ b/include/RequestCallback.h @@ -14,30 +14,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __REQUEST_CALLBACK_H__ -#define __REQUEST_CALLBACK_H__ +#ifndef ROCKETMQ_REQUESTCALLBACK_H_ +#define ROCKETMQ_REQUESTCALLBACK_H_ -#include "MQClientException.h" +#include "MQException.h" #include "MQMessage.h" namespace rocketmq { enum RequestCallbackType { REQUEST_CALLBACK_TYPE_SIMPLE = 0, REQUEST_CALLBACK_TYPE_AUTO_DELETE = 1 }; +/** + * RequestCallback - callback interface for async request + */ class ROCKETMQCLIENT_API RequestCallback { public: virtual ~RequestCallback() = default; - virtual void onSuccess(MessagePtr message) { onSuccess(MQMessage(message)); } - - // SDK will be responsible for the lifecycle of message. virtual void onSuccess(MQMessage message) = 0; - virtual void onException(MQException& e) noexcept = 0; virtual RequestCallbackType getRequestCallbackType() const { return REQUEST_CALLBACK_TYPE_SIMPLE; } }; +/** + * AutoDeleteRequestCallback - callback interface for async request + * + * the object of AutoDeleteRequestCallback will be deleted automatically by SDK after invoke callback interface + */ class ROCKETMQCLIENT_API AutoDeleteRequestCallback : public RequestCallback { public: RequestCallbackType getRequestCallbackType() const override final { return REQUEST_CALLBACK_TYPE_AUTO_DELETE; } @@ -45,4 +49,4 @@ class ROCKETMQCLIENT_API AutoDeleteRequestCallback : public RequestCallback { } // namespace rocketmq -#endif // __REQUEST_CALLBACK_H__ +#endif // ROCKETMQ_REQUESTCALLBACK_H_ diff --git a/include/SendCallback.h b/include/SendCallback.h index e01f513e5..480189142 100755 --- a/include/SendCallback.h +++ b/include/SendCallback.h @@ -14,16 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __SEND_CALLBACK_H__ -#define __SEND_CALLBACK_H__ +#ifndef ROCKETMQ_SENDCALLBACK_H_ +#define ROCKETMQ_SENDCALLBACK_H_ -#include "MQClientException.h" +#include "MQException.h" #include "SendResult.h" namespace rocketmq { enum SendCallbackType { SEND_CALLBACK_TYPE_SIMPLE = 0, SEND_CALLBACK_TYPE_AUTO_DELETE = 1 }; +/** + * SendCallback - callback interface for async send + */ class ROCKETMQCLIENT_API SendCallback { public: virtual ~SendCallback() = default; @@ -34,12 +37,17 @@ class ROCKETMQCLIENT_API SendCallback { virtual SendCallbackType getSendCallbackType() const { return SEND_CALLBACK_TYPE_SIMPLE; } }; -// async SendCallback will be deleted automatically by rocketmq cpp after invoke callback interface -class ROCKETMQCLIENT_API AutoDeleteSendCallback : public SendCallback { +/** + * AutoDeleteSendCallback - callback interface for async send + * + * the object of AutoDeleteSendCallback will be deleted automatically by SDK after invoke callback interface + */ +class ROCKETMQCLIENT_API AutoDeleteSendCallback : public SendCallback // base interface +{ public: SendCallbackType getSendCallbackType() const override final { return SEND_CALLBACK_TYPE_AUTO_DELETE; } }; } // namespace rocketmq -#endif // __SEND_CALLBACK_H__ +#endif // ROCKETMQ_SENDCALLBACK_H_ diff --git a/include/SendResult.h b/include/SendResult.h index 1a713bac6..918822224 100644 --- a/include/SendResult.h +++ b/include/SendResult.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __SEND_RESULT_H__ -#define __SEND_RESULT_H__ +#ifndef ROCKETMQ_SENDRESULT_H_ +#define ROCKETMQ_SENDRESULT_H_ #include "MQMessageQueue.h" @@ -26,38 +26,64 @@ enum SendStatus { SEND_OK, SEND_FLUSH_DISK_TIMEOUT, SEND_FLUSH_SLAVE_TIMEOUT, SE class ROCKETMQCLIENT_API SendResult { public: - SendResult(); + SendResult() : send_status_(SEND_OK), queue_offset_(0) {} + SendResult(const SendStatus& sendStatus, const std::string& msgId, const std::string& offsetMsgId, const MQMessageQueue& messageQueue, - int64_t queueOffset); + int64_t queueOffset) + : send_status_(sendStatus), + msg_id_(msgId), + offset_msg_id_(offsetMsgId), + message_queue_(messageQueue), + queue_offset_(queueOffset) {} + + SendResult(const SendResult& other) { + send_status_ = other.send_status_; + msg_id_ = other.msg_id_; + offset_msg_id_ = other.offset_msg_id_; + message_queue_ = other.message_queue_; + queue_offset_ = other.queue_offset_; + } + + SendResult& operator=(const SendResult& other) { + if (this != &other) { + send_status_ = other.send_status_; + msg_id_ = other.msg_id_; + offset_msg_id_ = other.offset_msg_id_; + message_queue_ = other.message_queue_; + queue_offset_ = other.queue_offset_; + } + return *this; + } + + virtual ~SendResult() = default; + + inline SendStatus getSendStatus() const { return send_status_; } + + inline const std::string& getMsgId() const { return msg_id_; } - SendResult(const SendResult& other); - SendResult& operator=(const SendResult& other); + inline const std::string& getOffsetMsgId() const { return offset_msg_id_; } - virtual ~SendResult(); + inline const MQMessageQueue& getMessageQueue() const { return message_queue_; } - SendStatus getSendStatus() const; - const std::string& getMsgId() const; - const std::string& getOffsetMsgId() const; - const MQMessageQueue& getMessageQueue() const; - int64_t getQueueOffset() const; + inline int64_t getQueueOffset() const { return queue_offset_; } - const std::string& getTransactionId() const { return m_transactionId; } - void setTransactionId(const std::string& id) { m_transactionId = id; } + inline const std::string& getTransactionId() const { return transaction_id_; } + inline void setTransactionId(const std::string& id) { transaction_id_ = id; } std::string toString() const; private: - SendStatus m_sendStatus; - std::string m_msgId; - std::string m_offsetMsgId; - MQMessageQueue m_messageQueue; - int64_t m_queueOffset; - std::string m_transactionId; + SendStatus send_status_; + std::string msg_id_; + std::string offset_msg_id_; + MQMessageQueue message_queue_; + int64_t queue_offset_; + std::string transaction_id_; }; } // namespace rocketmq -#endif // __SEND_RESULT_H__ +#endif // ROCKETMQ_SENDRESULT_H_ diff --git a/include/SessionCredentials.h b/include/SessionCredentials.h index 15dd25ab5..2d03f2a9f 100644 --- a/include/SessionCredentials.h +++ b/include/SessionCredentials.h @@ -14,10 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __SESSION_CREDENTIALS_H__ -#define __SESSION_CREDENTIALS_H__ +#ifndef ROCKETMQ_SESSIONCREDENTIALS_H_ +#define ROCKETMQ_SESSIONCREDENTIALS_H_ -#include +#include // std::string #include "RocketMQClient.h" @@ -25,49 +25,43 @@ namespace rocketmq { class ROCKETMQCLIENT_API SessionCredentials { public: - static const std::string AccessKey; - static const std::string SecretKey; - static const std::string Signature; - static const std::string SignatureMethod; - static const std::string ONSChannelKey; - - SessionCredentials() : authChannel_("ALIYUN") {} + SessionCredentials() : auth_channel_("ALIYUN") {} SessionCredentials(const std::string& accessKey, const std::string& secretKey, const std::string& authChannel) - : accessKey_(accessKey), secretKey_(secretKey), authChannel_(authChannel) {} + : access_key_(accessKey), secret_key_(secretKey), auth_channel_(authChannel) {} SessionCredentials(const SessionCredentials& other) - : accessKey_(other.accessKey_), - secretKey_(other.secretKey_), + : access_key_(other.access_key_), + secret_key_(other.secret_key_), signature_(other.signature_), - signatureMethod_(other.signatureMethod_), - authChannel_(other.authChannel_) {} + signature_method_(other.signature_method_), + auth_channel_(other.auth_channel_) {} ~SessionCredentials() = default; - const std::string& getAccessKey() const { return accessKey_; } - void setAccessKey(const std::string& accessKey) { accessKey_ = accessKey; } + inline const std::string& getAccessKey() const { return access_key_; } + inline void setAccessKey(const std::string& accessKey) { access_key_ = accessKey; } - const std::string& getSecretKey() const { return secretKey_; } - void setSecretKey(const std::string& secretKey) { secretKey_ = secretKey; } + inline const std::string& getSecretKey() const { return secret_key_; } + inline void setSecretKey(const std::string& secretKey) { secret_key_ = secretKey; } - const std::string& getSignature() const { return signature_; } - void setSignature(const std::string& signature) { signature_ = signature; } + inline const std::string& getSignature() const { return signature_; } + inline void setSignature(const std::string& signature) { signature_ = signature; } - const std::string& getSignatureMethod() const { return signatureMethod_; } - void setSignatureMethod(const std::string& signatureMethod) { signatureMethod_ = signatureMethod; } + inline const std::string& getSignatureMethod() const { return signature_method_; } + inline void setSignatureMethod(const std::string& signatureMethod) { signature_method_ = signatureMethod; } - const std::string& getAuthChannel() const { return authChannel_; } - void setAuthChannel(const std::string& channel) { authChannel_ = channel; } + inline const std::string& getAuthChannel() const { return auth_channel_; } + inline void setAuthChannel(const std::string& channel) { auth_channel_ = channel; } - bool isValid() const { return !accessKey_.empty() && !secretKey_.empty() && !authChannel_.empty(); } + bool isValid() const { return !access_key_.empty() && !secret_key_.empty() && !auth_channel_.empty(); } private: - std::string accessKey_; - std::string secretKey_; + std::string access_key_; + std::string secret_key_; std::string signature_; - std::string signatureMethod_; - std::string authChannel_; + std::string signature_method_; + std::string auth_channel_; }; } // namespace rocketmq -#endif // __SESSION_CREDENTIALS_H__ +#endif // ROCKETMQ_SESSIONCREDENTIALS_H_ diff --git a/include/TransactionListener.h b/include/TransactionListener.h index 3af087cba..cc4d537fc 100644 --- a/include/TransactionListener.h +++ b/include/TransactionListener.h @@ -14,14 +14,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __TRANSACTION_LISTENER_H__ -#define __TRANSACTION_LISTENER_H__ +#ifndef ROCKETMQ_TRANSACTIONLISTENER_H_ +#define ROCKETMQ_TRANSACTIONLISTENER_H_ #include "MQMessageExt.h" #include "TransactionSendResult.h" namespace rocketmq { +/** + * TransactionListener - listener interface for TransactionMQProducer + */ class ROCKETMQCLIENT_API TransactionListener { public: virtual ~TransactionListener() = default; @@ -47,4 +50,4 @@ class ROCKETMQCLIENT_API TransactionListener { } // namespace rocketmq -#endif // __TRANSACTION_LISTENER_H__ +#endif // ROCKETMQ_TRANSACTIONLISTENER_H_ diff --git a/include/TransactionMQProducer.h b/include/TransactionMQProducer.h index 4efe26df1..3e2222a2b 100644 --- a/include/TransactionMQProducer.h +++ b/include/TransactionMQProducer.h @@ -14,32 +14,39 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __TRANSACTION_MQ_PRODUCER_H__ -#define __TRANSACTION_MQ_PRODUCER_H__ +#ifndef ROCKETMQ_TRANSACTIONMQPRODUCER_H_ +#define ROCKETMQ_TRANSACTIONMQPRODUCER_H_ #include "DefaultMQProducer.h" #include "TransactionMQProducerConfig.h" namespace rocketmq { -class ROCKETMQCLIENT_API TransactionMQProducer : public DefaultMQProducer, virtual public TransactionMQProducerConfig { +class ROCKETMQCLIENT_API TransactionMQProducer : public DefaultMQProducer, // base + virtual public TransactionMQProducerConfig // interface +{ public: TransactionMQProducer(const std::string& groupname); TransactionMQProducer(const std::string& groupname, RPCHookPtr rpcHook); virtual ~TransactionMQProducer(); - public: // TransactionMQProducerConfig - TransactionListener* getTransactionListener() const override; - void setTransactionListener(TransactionListener* transactionListener) override; - public: // MQProducer void start() override; void shutdown() override; - // Transaction: don't delete msg object, until callback occur. + // Transaction TransactionSendResult sendMessageInTransaction(MQMessage& msg, void* arg) override; + + public: // TransactionMQProducerConfig + TransactionListener* getTransactionListener() const override; + void setTransactionListener(TransactionListener* transactionListener) override; + + public: // DefaultMQProducerConfigProxy + inline TransactionMQProducerConfigPtr real_config() const { + return std::dynamic_pointer_cast(client_config_); + } }; } // namespace rocketmq -#endif // __TRANSACTION_MQ_PRODUCER_H__ +#endif // ROCKETMQ_TRANSACTIONMQPRODUCER_H_ diff --git a/include/TransactionMQProducerConfig.h b/include/TransactionMQProducerConfig.h index e341aa2be..fab3f0710 100644 --- a/include/TransactionMQProducerConfig.h +++ b/include/TransactionMQProducerConfig.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __TRANSACTION_MQ_PRODUCER_CONFIG_H__ -#define __TRANSACTION_MQ_PRODUCER_CONFIG_H__ +#ifndef ROCKETMQ_TRANSACTIONMQPRODUCERCONFIG_H_ +#define ROCKETMQ_TRANSACTIONMQPRODUCERCONFIG_H_ #include "DefaultMQProducerConfig.h" #include "TransactionListener.h" @@ -25,6 +25,9 @@ namespace rocketmq { class TransactionMQProducerConfig; typedef std::shared_ptr TransactionMQProducerConfigPtr; +/** + * TransactionMQProducerConfig - config interface for TransactionMQProducer + */ class ROCKETMQCLIENT_API TransactionMQProducerConfig : virtual public DefaultMQProducerConfig { public: virtual ~TransactionMQProducerConfig() = default; @@ -36,4 +39,4 @@ class ROCKETMQCLIENT_API TransactionMQProducerConfig : virtual public DefaultMQP } // namespace rocketmq -#endif // __TRANSACTION_MQ_PRODUCER_CONFIG_H__ +#endif // ROCKETMQ_TRANSACTIONMQPRODUCERCONFIG_H_ diff --git a/include/TransactionSendResult.h b/include/TransactionSendResult.h index 03d626f18..7219d16ba 100644 --- a/include/TransactionSendResult.h +++ b/include/TransactionSendResult.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __TRANSACTION_SEND_RESULT_H__ -#define __TRANSACTION_SEND_RESULT_H__ +#ifndef ROCKETMQ_TRANSACTIONSENDRESULT_H_ +#define ROCKETMQ_TRANSACTIONSENDRESULT_H_ #include "SendResult.h" @@ -25,18 +25,18 @@ enum LocalTransactionState { COMMIT_MESSAGE, ROLLBACK_MESSAGE, UNKNOWN }; class ROCKETMQCLIENT_API TransactionSendResult : public SendResult { public: - TransactionSendResult(const SendResult& sendResult) : SendResult(sendResult), m_localTransactionState(UNKNOWN) {} + TransactionSendResult(const SendResult& sendResult) : SendResult(sendResult), local_transaction_state_(UNKNOWN) {} - LocalTransactionState getLocalTransactionState() { return m_localTransactionState; } + inline LocalTransactionState getLocalTransactionState() const { return local_transaction_state_; } - void setLocalTransactionState(LocalTransactionState localTransactionState) { - m_localTransactionState = localTransactionState; + inline void setLocalTransactionState(LocalTransactionState localTransactionState) { + local_transaction_state_ = localTransactionState; } private: - LocalTransactionState m_localTransactionState; + LocalTransactionState local_transaction_state_; }; } // namespace rocketmq -#endif // __TRANSACTION_SEND_RESULT_H__ +#endif // ROCKETMQ_TRANSACTIONSENDRESULT_H_ diff --git a/include/c/CBatchMessage.h b/include/c/CBatchMessage.h index 1b4da7e9f..eafa24c68 100644 --- a/include/c/CBatchMessage.h +++ b/include/c/CBatchMessage.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __C_BATCH_MESSAGE_H__ -#define __C_BATCH_MESSAGE_H__ +#ifndef ROCKETMQ_C_CBATCHMESSAGE_H_ +#define ROCKETMQ_C_CBATCHMESSAGE_H_ #include "CCommon.h" #include "CMessage.h" @@ -34,4 +34,4 @@ ROCKETMQCLIENT_API int DestroyBatchMessage(CBatchMessage* batchMsg); } #endif -#endif // __C_BATCH_MESSAGE_H__ +#endif // ROCKETMQ_C_CBATCHMESSAGE_H_ diff --git a/include/c/CCommon.h b/include/c/CCommon.h index 167f645cd..ae7adf0d4 100644 --- a/include/c/CCommon.h +++ b/include/c/CCommon.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __C_COMMON_H__ -#define __C_COMMON_H__ +#ifndef ROCKETMQ_C_CCOMMON_H_ +#define ROCKETMQ_C_CCOMMON_H_ #ifdef __cplusplus extern "C" { @@ -84,4 +84,4 @@ typedef enum _CMessageModel_ { BROADCASTING, CLUSTERING } CMessageModel; } #endif -#endif // __C_COMMON_H__ +#endif // ROCKETMQ_C_CCOMMON_H_ diff --git a/include/c/CErrorMessage.h b/include/c/CErrorMessage.h index 928950cf2..56e89db4e 100644 --- a/include/c/CErrorMessage.h +++ b/include/c/CErrorMessage.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __C_ERROR_MESSAGE_H__ -#define __C_ERROR_MESSAGE_H__ +#ifndef ROCCKETMQ_C_CERRORMESSAGE_H_ +#define ROCCKETMQ_C_CERRORMESSAGE_H_ #include "CCommon.h" @@ -29,4 +29,4 @@ ROCKETMQCLIENT_API const char* GetLatestErrorMessage(); // Return the last erro } #endif -#endif // __C_ERROR_MESSAGE_H__ +#endif // ROCCKETMQ_C_CERRORMESSAGE_H_ diff --git a/include/c/CMQException.h b/include/c/CMQException.h index 7e2f498af..2fb4a7e73 100644 --- a/include/c/CMQException.h +++ b/include/c/CMQException.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __C_MQEXCPTION_H__ -#define __C_MQEXCPTION_H__ +#ifndef ROCKETMQ_C_CMQEXCPTION_H_ +#define ROCKETMQ_C_CMQEXCPTION_H_ #include "CCommon.h" @@ -39,4 +39,4 @@ typedef struct _CMQException_ { } #endif -#endif +#endif // ROCKETMQ_C_CMQEXCPTION_H_ diff --git a/include/c/CMessage.h b/include/c/CMessage.h index 7c16f15bc..7bbba3adc 100644 --- a/include/c/CMessage.h +++ b/include/c/CMessage.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __C_MESSAGE_H__ -#define __C_MESSAGE_H__ +#ifndef ROCKETMQ_C_CMESSAGE_H_ +#define ROCKETMQ_C_CMESSAGE_H_ #include "CCommon.h" @@ -23,7 +23,7 @@ extern "C" { #endif -typedef struct CMessage CMessage; +typedef struct CMessage CMessage; // alias as MQMessage ROCKETMQCLIENT_API CMessage* CreateMessage(const char* topic); ROCKETMQCLIENT_API int DestroyMessage(CMessage* msg); @@ -45,4 +45,4 @@ ROCKETMQCLIENT_API int GetOriginDelayTimeLevel(CMessage* msg); } #endif -#endif // __C_MESSAGE_H__ +#endif // ROCKETMQ_C_CMESSAGE_H_ diff --git a/include/c/CMessageExt.h b/include/c/CMessageExt.h index bfd43438b..4b4c7dfc2 100644 --- a/include/c/CMessageExt.h +++ b/include/c/CMessageExt.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __C_MESSAGE_EXT_H__ -#define __C_MESSAGE_EXT_H__ +#ifndef ROCKETMQ_C_CMESSAGEEXT_H_ +#define ROCKETMQ_C_CMESSAGEEXT_H_ #include "CCommon.h" @@ -23,7 +23,7 @@ extern "C" { #endif -typedef struct CMessageExt CMessageExt; +typedef struct CMessageExt CMessageExt; // alias for MQMessageExt ROCKETMQCLIENT_API const char* GetMessageTopic(CMessageExt* msgExt); ROCKETMQCLIENT_API const char* GetMessageTags(CMessageExt* msgExt); @@ -45,4 +45,4 @@ ROCKETMQCLIENT_API long long GetMessagePreparedTransactionOffset(CMessageExt* ms } #endif -#endif // __C_MESSAGE_EXT_H__ +#endif // ROCKETMQ_C_CMESSAGEEXT_H_ diff --git a/include/c/CMessageQueue.h b/include/c/CMessageQueue.h index bd6da3784..e83248ff9 100644 --- a/include/c/CMessageQueue.h +++ b/include/c/CMessageQueue.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __C_MESSAGE_QUEUE_H__ -#define __C_MESSAGE_QUEUE_H__ +#ifndef ROCKETMQ_C_CMESSAGEQUEUE_H_ +#define ROCKETMQ_C_CMESSAGEQUEUE_H_ #include "CCommon.h" @@ -33,4 +33,4 @@ typedef struct _CMessageQueue_ { } #endif -#endif // __C_MESSAGE_H__ +#endif // ROCKETMQ_C_CMESSAGEQUEUE_H_ diff --git a/include/c/CProducer.h b/include/c/CProducer.h index ed8800c42..6c797b0ed 100644 --- a/include/c/CProducer.h +++ b/include/c/CProducer.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __C_PRODUCER_H__ -#define __C_PRODUCER_H__ +#ifndef ROCKETMQ_C_CPRODUCER_H_ +#define ROCKETMQ_C_CPRODUCER_H_ #include "CBatchMessage.h" #include "CMQException.h" @@ -28,7 +28,8 @@ extern "C" { #endif -typedef struct CProducer CProducer; +typedef struct CProducer CProducer; // alias for DefaultMQProducer + typedef int (*QueueSelectorCallback)(int size, CMessage* msg, void* arg); typedef void (*CSendSuccessCallback)(CSendResult result); typedef void (*CSendExceptionCallback)(CMQException e); @@ -105,4 +106,4 @@ ROCKETMQCLIENT_API int SendMessageTransaction(CProducer* producer, } #endif -#endif // __C_PRODUCER_H__ +#endif // ROCKETMQ_C_CPRODUCER_H_ diff --git a/include/c/CPullConsumer.h b/include/c/CPullConsumer.h index 41ebbb9ba..852e17f29 100644 --- a/include/c/CPullConsumer.h +++ b/include/c/CPullConsumer.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __C_PULL_CONSUMER_H__ -#define __C_PULL_CONSUMER_H__ +#ifndef ROCKETMQ_C_CPULLCONSUMER_H_ +#define ROCKETMQ_C_CPULLCONSUMER_H_ #include "CCommon.h" #include "CMessageExt.h" @@ -58,4 +58,4 @@ ROCKETMQCLIENT_API int ReleasePullResult(CPullResult pullResult); } #endif -#endif // __C_PUSH_CONSUMER_H__ +#endif // ROCKETMQ_C_CPULLCONSUMER_H_ diff --git a/include/c/CPullResult.h b/include/c/CPullResult.h index 2f5803081..6fc45e9ca 100644 --- a/include/c/CPullResult.h +++ b/include/c/CPullResult.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __C_PULL_RESULT_H__ -#define __C_PULL_RESULT_H__ +#ifndef ROCCKETMQ_C_CPULLRESULT_H_ +#define ROCCKETMQ_C_CPULLRESULT_H_ #include "CCommon.h" #include "CMessageExt.h" @@ -46,4 +46,4 @@ typedef struct _CPullResult_ { } #endif -#endif // __C_PULL_RESULT_H__ +#endif // ROCCKETMQ_C_CPULLRESULT_H_ diff --git a/include/c/CPushConsumer.h b/include/c/CPushConsumer.h index 4a8bd1400..8b7987ef1 100644 --- a/include/c/CPushConsumer.h +++ b/include/c/CPushConsumer.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __C_PUSH_CONSUMER_H__ -#define __C_PUSH_CONSUMER_H__ +#ifndef ROCKETMQ_C_CPUSHCONSUMER_H_ +#define ROCKETMQ_C_CPUSHCONSUMER_H_ #include "CCommon.h" #include "CMessageExt.h" @@ -24,7 +24,7 @@ extern "C" { #endif -typedef struct CPushConsumer CPushConsumer; +typedef struct CPushConsumer CPushConsumer; // alias for DefaultMQPushConssumer typedef enum E_CConsumeStatus { E_CONSUME_SUCCESS = 0, E_RECONSUME_LATER = 1 } CConsumeStatus; @@ -61,4 +61,4 @@ ROCKETMQCLIENT_API int SetPushConsumerMaxCacheMessageSizeInMb(CPushConsumer* con } #endif -#endif // __C_PUSH_CONSUMER_H__ +#endif // ROCKETMQ_C_CPUSHCONSUMER_H_ diff --git a/include/c/CSendResult.h b/include/c/CSendResult.h index 3ac2fcd74..bf22e6a9c 100644 --- a/include/c/CSendResult.h +++ b/include/c/CSendResult.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __C_SEND_RESULT_H__ -#define __C_SEND_RESULT_H__ +#ifndef ROCKETMQ_C_CSENDRESULT_H_ +#define ROCKETMQ_C_CSENDRESULT_H_ #include "CCommon.h" @@ -40,4 +40,4 @@ typedef struct _SendResult_ { } #endif -#endif // __C_PRODUCER_H__ +#endif // ROCKETMQ_C_CSENDRESULT_H_ diff --git a/include/c/CTransactionStatus.h b/include/c/CTransactionStatus.h index f0bff3c97..a46b8275b 100644 --- a/include/c/CTransactionStatus.h +++ b/include/c/CTransactionStatus.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __C_TRANSACTION_STATUS_H__ -#define __C_TRANSACTION_STATUS_H__ +#ifndef ROCKETMQ_C_CTRANSACTIONSTATUS_H_ +#define ROCKETMQ_C_CTRANSACTIONSTATUS_H_ #ifdef __cplusplus extern "C" { @@ -31,4 +31,4 @@ typedef enum E_CTransactionStatus { } #endif -#endif // __C_TRANSACTION_STATUS_H__ +#endif // ROCKETMQ_C_CTRANSACTIONSTATUS_H_ diff --git a/src/ClientRemotingProcessor.cpp b/src/ClientRemotingProcessor.cpp index 63616280d..aa742ba85 100644 --- a/src/ClientRemotingProcessor.cpp +++ b/src/ClientRemotingProcessor.cpp @@ -19,7 +19,7 @@ #include "ConsumerRunningInfo.h" #include "MessageDecoder.h" #include "MQProtos.h" -#include "MessageAccessor.h" +#include "MessageAccessor.hpp" #include "MessageSysFlag.h" #include "RequestFutureTable.h" #include "SocketUtil.h" @@ -29,7 +29,7 @@ namespace rocketmq { -ClientRemotingProcessor::ClientRemotingProcessor(MQClientInstance* clientInstance) : m_clientInstance(clientInstance) {} +ClientRemotingProcessor::ClientRemotingProcessor(MQClientInstance* clientInstance) : client_instance_(clientInstance) {} ClientRemotingProcessor::~ClientRemotingProcessor() = default; @@ -74,7 +74,7 @@ RemotingCommand* ClientRemotingProcessor::checkTransactionState(const std::strin } const auto& group = messageExt->getProperty(MQMessageConst::PROPERTY_PRODUCER_GROUP); if (!group.empty()) { - auto* producer = m_clientInstance->selectProducer(group); + auto* producer = client_instance_->selectProducer(group); if (producer != nullptr) { producer->checkTransactionState(addr, messageExt, requestHeader); } else { @@ -96,7 +96,7 @@ RemotingCommand* ClientRemotingProcessor::checkTransactionState(const std::strin RemotingCommand* ClientRemotingProcessor::notifyConsumerIdsChanged(RemotingCommand* request) { auto* requestHeader = request->decodeCommandCustomHeader(); LOG_INFO_NEW("notifyConsumerIdsChanged, group:{}", requestHeader->getConsumerGroup()); - m_clientInstance->rebalanceImmediately(); + client_instance_->rebalanceImmediately(); return nullptr; } @@ -106,7 +106,7 @@ RemotingCommand* ClientRemotingProcessor::resetOffset(RemotingCommand* request) if (requestBody != nullptr && requestBody->size() > 0) { std::unique_ptr body(ResetOffsetBody::Decode(*requestBody)); if (body != nullptr) { - m_clientInstance->resetOffset(responseHeader->getGroup(), responseHeader->getTopic(), body->getOffsetTable()); + client_instance_->resetOffset(responseHeader->getGroup(), responseHeader->getTopic(), body->getOffsetTable()); } else { LOG_ERROR("resetOffset failed as received data could not be unserialized"); } @@ -122,7 +122,7 @@ RemotingCommand* ClientRemotingProcessor::getConsumerRunningInfo(const std::stri new RemotingCommand(MQResponseCode::SYSTEM_ERROR, "not set any response code")); std::unique_ptr runningInfo( - m_clientInstance->consumerRunningInfo(requestHeader->getConsumerGroup())); + client_instance_->consumerRunningInfo(requestHeader->getConsumerGroup())); if (runningInfo != nullptr) { if (requestHeader->isJstackEnable()) { /*string jstack = UtilAll::jstack(); diff --git a/src/ClientRemotingProcessor.h b/src/ClientRemotingProcessor.h index e758cbcd8..ca28297b0 100644 --- a/src/ClientRemotingProcessor.h +++ b/src/ClientRemotingProcessor.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __CLIENT_REMOTING_PROCESSOR_H__ -#define __CLIENT_REMOTING_PROCESSOR_H__ +#ifndef ROCKETMQ_CLIENTREMOTINGPROCESSOR_H_ +#define ROCKETMQ_CLIENTREMOTINGPROCESSOR_H_ #include "MQClientInstance.h" #include "MQMessageQueue.h" @@ -40,9 +40,9 @@ class ClientRemotingProcessor : public RequestProcessor { void processReplyMessage(std::unique_ptr replyMsg); private: - MQClientInstance* m_clientInstance; + MQClientInstance* client_instance_; }; } // namespace rocketmq -#endif // __CLIENT_REMOTING_PROCESSOR_H__ +#endif // ROCKETMQ_CLIENTREMOTINGPROCESSOR_H_ diff --git a/src/MQAdminImpl.cpp b/src/MQAdminImpl.cpp index 5f334a2d9..217c51747 100644 --- a/src/MQAdminImpl.cpp +++ b/src/MQAdminImpl.cpp @@ -18,7 +18,7 @@ #include "MQClientAPIImpl.h" #include "MQClientInstance.h" -#include "TopicPublishInfo.h" +#include "TopicPublishInfo.hpp" namespace rocketmq { @@ -27,9 +27,9 @@ void MQAdminImpl::createTopic(const std::string& key, const std::string& newTopi void MQAdminImpl::fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) { try { TopicRouteDataPtr topicRouteData( - m_clientInstance->getMQClientAPIImpl()->getTopicRouteInfoFromNameServer(topic, 1000 * 3)); + client_instance_->getMQClientAPIImpl()->getTopicRouteInfoFromNameServer(topic, 1000 * 3)); if (topicRouteData != nullptr) { - mqs = m_clientInstance->topicRouteData2TopicSubscribeInfo(topic, topicRouteData); + mqs = client_instance_->topicRouteData2TopicSubscribeInfo(topic, topicRouteData); if (!mqs.empty()) { return; } else { @@ -45,15 +45,15 @@ void MQAdminImpl::fetchSubscribeMessageQueues(const std::string& topic, std::vec } int64_t MQAdminImpl::searchOffset(const MQMessageQueue& mq, int64_t timestamp) { - std::string brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); + std::string brokerAddr = client_instance_->findBrokerAddressInPublish(mq.broker_name()); if (brokerAddr.empty()) { - m_clientInstance->updateTopicRouteInfoFromNameServer(mq.getTopic()); - brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); + client_instance_->updateTopicRouteInfoFromNameServer(mq.topic()); + brokerAddr = client_instance_->findBrokerAddressInPublish(mq.broker_name()); } if (!brokerAddr.empty()) { try { - return m_clientInstance->getMQClientAPIImpl()->searchOffset(brokerAddr, mq.getTopic(), mq.getQueueId(), timestamp, + return client_instance_->getMQClientAPIImpl()->searchOffset(brokerAddr, mq.topic(), mq.queue_id(), timestamp, 1000 * 3); } catch (MQException& e) { THROW_MQEXCEPTION(MQClientException, "Invoke Broker exception", -1); @@ -63,15 +63,15 @@ int64_t MQAdminImpl::searchOffset(const MQMessageQueue& mq, int64_t timestamp) { } int64_t MQAdminImpl::maxOffset(const MQMessageQueue& mq) { - std::string brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); + std::string brokerAddr = client_instance_->findBrokerAddressInPublish(mq.broker_name()); if (brokerAddr.empty()) { - m_clientInstance->updateTopicRouteInfoFromNameServer(mq.getTopic()); - brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); + client_instance_->updateTopicRouteInfoFromNameServer(mq.topic()); + brokerAddr = client_instance_->findBrokerAddressInPublish(mq.broker_name()); } if (!brokerAddr.empty()) { try { - return m_clientInstance->getMQClientAPIImpl()->getMaxOffset(brokerAddr, mq.getTopic(), mq.getQueueId(), 1000 * 3); + return client_instance_->getMQClientAPIImpl()->getMaxOffset(brokerAddr, mq.topic(), mq.queue_id(), 1000 * 3); } catch (MQException& e) { THROW_MQEXCEPTION(MQClientException, "Invoke Broker exception", -1); } @@ -80,33 +80,33 @@ int64_t MQAdminImpl::maxOffset(const MQMessageQueue& mq) { } int64_t MQAdminImpl::minOffset(const MQMessageQueue& mq) { - std::string brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); + std::string brokerAddr = client_instance_->findBrokerAddressInPublish(mq.broker_name()); if (brokerAddr.empty()) { - m_clientInstance->updateTopicRouteInfoFromNameServer(mq.getTopic()); - brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); + client_instance_->updateTopicRouteInfoFromNameServer(mq.topic()); + brokerAddr = client_instance_->findBrokerAddressInPublish(mq.broker_name()); } if (!brokerAddr.empty()) { try { - return m_clientInstance->getMQClientAPIImpl()->getMinOffset(brokerAddr, mq.getTopic(), mq.getQueueId(), 1000 * 3); + return client_instance_->getMQClientAPIImpl()->getMinOffset(brokerAddr, mq.topic(), mq.queue_id(), 1000 * 3); } catch (const std::exception& e) { THROW_MQEXCEPTION(MQClientException, "Invoke Broker[" + brokerAddr + "] exception", -1); } } - THROW_MQEXCEPTION(MQClientException, "The broker[" + mq.getBrokerName() + "] not exist", -1); + THROW_MQEXCEPTION(MQClientException, "The broker[" + mq.broker_name() + "] not exist", -1); } int64_t MQAdminImpl::earliestMsgStoreTime(const MQMessageQueue& mq) { - std::string brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); + std::string brokerAddr = client_instance_->findBrokerAddressInPublish(mq.broker_name()); if (brokerAddr.empty()) { - m_clientInstance->updateTopicRouteInfoFromNameServer(mq.getTopic()); - brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); + client_instance_->updateTopicRouteInfoFromNameServer(mq.topic()); + brokerAddr = client_instance_->findBrokerAddressInPublish(mq.broker_name()); } if (!brokerAddr.empty()) { try { - return m_clientInstance->getMQClientAPIImpl()->getEarliestMsgStoretime(brokerAddr, mq.getTopic(), mq.getQueueId(), + return client_instance_->getMQClientAPIImpl()->getEarliestMsgStoretime(brokerAddr, mq.topic(), mq.queue_id(), 1000 * 3); } catch (MQException& e) { THROW_MQEXCEPTION(MQClientException, "Invoke Broker exception", -1); diff --git a/src/MQAdminImpl.h b/src/MQAdminImpl.h index 27949c77a..c85c989e4 100644 --- a/src/MQAdminImpl.h +++ b/src/MQAdminImpl.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_ADMIN_IMPL_H___ -#define __MQ_ADMIN_IMPL_H___ +#ifndef ROCKETMQ_MQADMINIMPL_H_ +#define ROCKETMQ_MQADMINIMPL_H_ #include #include @@ -29,7 +29,7 @@ namespace rocketmq { class MQAdminImpl { public: - MQAdminImpl(MQClientInstance* clientInstance) : m_clientInstance(clientInstance) {} + MQAdminImpl(MQClientInstance* clientInstance) : client_instance_(clientInstance) {} void createTopic(const std::string& key, const std::string& newTopic, int queueNum); @@ -44,9 +44,9 @@ class MQAdminImpl { QueryResult queryMessage(const std::string& topic, const std::string& key, int maxNum, int64_t begin, int64_t end); private: - MQClientInstance* m_clientInstance; + MQClientInstance* client_instance_; }; } // namespace rocketmq -#endif // __MQ_ADMIN_IMPL_H___ +#endif // ROCKETMQ_MQADMINIMPL_H_ diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index 42c9f6f03..429ff1745 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -25,7 +25,7 @@ #include "MessageBatch.h" #include "MessageClientIDSetter.h" #include "PullCallbackWrap.h" -#include "PullResultExt.h" +#include "PullResultExt.hpp" #include "SendCallbackWrap.h" #include "TcpRemotingClient.h" @@ -34,45 +34,46 @@ namespace rocketmq { MQClientAPIImpl::MQClientAPIImpl(ClientRemotingProcessor* clientRemotingProcessor, RPCHookPtr rpcHook, const MQClientConfig& clientConfig) - : m_remotingClient(new TcpRemotingClient(clientConfig.getTcpTransportWorkerThreadNum(), + : remoting_client_(new TcpRemotingClient(clientConfig.getTcpTransportWorkerThreadNum(), clientConfig.getTcpTransportConnectTimeout(), clientConfig.getTcpTransportTryLockTimeout())) { - m_remotingClient->registerRPCHook(rpcHook); - m_remotingClient->registerProcessor(CHECK_TRANSACTION_STATE, clientRemotingProcessor); - m_remotingClient->registerProcessor(NOTIFY_CONSUMER_IDS_CHANGED, clientRemotingProcessor); - m_remotingClient->registerProcessor(RESET_CONSUMER_CLIENT_OFFSET, clientRemotingProcessor); - m_remotingClient->registerProcessor(GET_CONSUMER_STATUS_FROM_CLIENT, clientRemotingProcessor); - m_remotingClient->registerProcessor(GET_CONSUMER_RUNNING_INFO, clientRemotingProcessor); - m_remotingClient->registerProcessor(CONSUME_MESSAGE_DIRECTLY, clientRemotingProcessor); - m_remotingClient->registerProcessor(PUSH_REPLY_MESSAGE_TO_CLIENT, clientRemotingProcessor); + remoting_client_->registerRPCHook(rpcHook); + remoting_client_->registerProcessor(CHECK_TRANSACTION_STATE, clientRemotingProcessor); + remoting_client_->registerProcessor(NOTIFY_CONSUMER_IDS_CHANGED, clientRemotingProcessor); + remoting_client_->registerProcessor(RESET_CONSUMER_CLIENT_OFFSET, clientRemotingProcessor); + remoting_client_->registerProcessor(GET_CONSUMER_STATUS_FROM_CLIENT, clientRemotingProcessor); + remoting_client_->registerProcessor(GET_CONSUMER_RUNNING_INFO, clientRemotingProcessor); + remoting_client_->registerProcessor(CONSUME_MESSAGE_DIRECTLY, clientRemotingProcessor); + remoting_client_->registerProcessor(PUSH_REPLY_MESSAGE_TO_CLIENT, clientRemotingProcessor); } MQClientAPIImpl::~MQClientAPIImpl() = default; void MQClientAPIImpl::start() { - m_remotingClient->start(); + remoting_client_->start(); } void MQClientAPIImpl::shutdown() { - m_remotingClient->shutdown(); + remoting_client_->shutdown(); } -void MQClientAPIImpl::updateNameServerAddr(const std::string& addrs) { - m_remotingClient->updateNameServerAddressList(addrs); +void MQClientAPIImpl::updateNameServerAddressList(const std::string& addrs) { + // TODO: split addrs + remoting_client_->updateNameServerAddressList(addrs); } void MQClientAPIImpl::createTopic(const std::string& addr, const std::string& defaultTopic, TopicConfig topicConfig) { auto* requestHeader = new CreateTopicRequestHeader(); - requestHeader->topic = topicConfig.getTopicName(); + requestHeader->topic = topicConfig.topic_name(); requestHeader->defaultTopic = defaultTopic; - requestHeader->readQueueNums = topicConfig.getReadQueueNums(); - requestHeader->writeQueueNums = topicConfig.getWriteQueueNums(); - requestHeader->perm = topicConfig.getPerm(); - requestHeader->topicFilterType = topicConfig.getTopicFilterType(); + requestHeader->readQueueNums = topicConfig.read_queue_nums(); + requestHeader->writeQueueNums = topicConfig.write_queue_nums(); + requestHeader->perm = topicConfig.perm(); + requestHeader->topicFilterType = topicConfig.topic_filter_type(); RemotingCommand request(UPDATE_AND_CREATE_TOPIC, requestHeader); - std::unique_ptr response(m_remotingClient->invokeSync(addr, request)); + std::unique_ptr response(remoting_client_->invokeSync(addr, request)); assert(response != nullptr); switch (response->code()) { case SUCCESS: { @@ -131,7 +132,7 @@ SendResult* MQClientAPIImpl::sendMessage(const std::string& addr, switch (communicationMode) { case CommunicationMode::ONEWAY: - m_remotingClient->invokeOneway(addr, request); + remoting_client_->invokeOneway(addr, request); return nullptr; case CommunicationMode::ASYNC: sendMessageAsync(addr, brokerName, msg, std::move(request), sendCallback, topicPublishInfo, instance, @@ -172,7 +173,7 @@ void MQClientAPIImpl::sendMessageAsync(const std::string& addr, void MQClientAPIImpl::sendMessageAsyncImpl(SendCallbackWrap* cbw, int64_t timeoutMillis) { const auto& addr = cbw->getAddr(); auto& request = cbw->getRemotingCommand(); - m_remotingClient->invokeAsync(addr, request, cbw, timeoutMillis); + remoting_client_->invokeAsync(addr, request, cbw, timeoutMillis); } SendResult* MQClientAPIImpl::sendMessageSync(const std::string& addr, @@ -181,7 +182,7 @@ SendResult* MQClientAPIImpl::sendMessageSync(const std::string& addr, RemotingCommand& request, int timeoutMillis) { // block until response - std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + std::unique_ptr response(remoting_client_->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); return processSendResponse(brokerName, msg, response.get()); } @@ -217,7 +218,7 @@ SendResult* MQClientAPIImpl::processSendResponse(const std::string& brokerName, // MessageBatch if (msg->isBatch()) { - const auto& messages = std::dynamic_pointer_cast(msg)->getMessages(); + const auto& messages = dynamic_cast(msg.get())->messages(); uniqMsgId.clear(); uniqMsgId.reserve(33 * messages.size() + 1); for (const auto& message : messages) { @@ -263,7 +264,7 @@ void MQClientAPIImpl::pullMessageAsync(const std::string& addr, auto* cbw = new PullCallbackWrap(pullCallback, this); try { - m_remotingClient->invokeAsync(addr, request, cbw, timeoutMillis); + remoting_client_->invokeAsync(addr, request, cbw, timeoutMillis); } catch (RemotingException& e) { deleteAndZero(cbw); throw e; @@ -271,7 +272,7 @@ void MQClientAPIImpl::pullMessageAsync(const std::string& addr, } PullResult* MQClientAPIImpl::pullMessageSync(const std::string& addr, RemotingCommand& request, int timeoutMillis) { - std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + std::unique_ptr response(remoting_client_->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); return processPullResponse(response.get()); } @@ -313,7 +314,7 @@ MQMessageExt MQClientAPIImpl::viewMessage(const std::string& addr, int64_t phyof RemotingCommand request(VIEW_MESSAGE_BY_ID, requestHeader); - std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + std::unique_ptr response(remoting_client_->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->code()) { case SUCCESS: { @@ -338,7 +339,7 @@ int64_t MQClientAPIImpl::searchOffset(const std::string& addr, RemotingCommand request(SEARCH_OFFSET_BY_TIMESTAMP, requestHeader); - std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + std::unique_ptr response(remoting_client_->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->code()) { case SUCCESS: { @@ -363,7 +364,7 @@ int64_t MQClientAPIImpl::getMaxOffset(const std::string& addr, RemotingCommand request(GET_MAX_OFFSET, requestHeader); - std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + std::unique_ptr response(remoting_client_->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->code()) { case SUCCESS: { @@ -387,7 +388,7 @@ int64_t MQClientAPIImpl::getMinOffset(const std::string& addr, RemotingCommand request(GET_MIN_OFFSET, requestHeader); - std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + std::unique_ptr response(remoting_client_->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->code()) { case SUCCESS: { @@ -412,7 +413,7 @@ int64_t MQClientAPIImpl::getEarliestMsgStoretime(const std::string& addr, RemotingCommand request(GET_EARLIEST_MSG_STORETIME, requestHeader); - std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + std::unique_ptr response(remoting_client_->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->code()) { case SUCCESS: { @@ -436,7 +437,7 @@ void MQClientAPIImpl::getConsumerIdListByGroup(const std::string& addr, RemotingCommand request(GET_CONSUMER_LIST_BY_GROUP, requestHeader); - std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + std::unique_ptr response(remoting_client_->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->code()) { case SUCCESS: { @@ -462,7 +463,7 @@ int64_t MQClientAPIImpl::queryConsumerOffset(const std::string& addr, int timeoutMillis) { RemotingCommand request(QUERY_CONSUMER_OFFSET, requestHeader); - std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + std::unique_ptr response(remoting_client_->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->code()) { case SUCCESS: { @@ -482,7 +483,7 @@ void MQClientAPIImpl::updateConsumerOffset(const std::string& addr, int timeoutMillis) { RemotingCommand request(UPDATE_CONSUMER_OFFSET, requestHeader); - std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + std::unique_ptr response(remoting_client_->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->code()) { case SUCCESS: { @@ -500,14 +501,14 @@ void MQClientAPIImpl::updateConsumerOffsetOneway(const std::string& addr, int timeoutMillis) { RemotingCommand request(UPDATE_CONSUMER_OFFSET, requestHeader); - m_remotingClient->invokeOneway(addr, request); + remoting_client_->invokeOneway(addr, request); } void MQClientAPIImpl::sendHearbeat(const std::string& addr, HeartbeatData* heartbeatData, long timeoutMillis) { RemotingCommand request(HEART_BEAT, nullptr); request.set_body(heartbeatData->encode()); - std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + std::unique_ptr response(remoting_client_->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->code()) { case SUCCESS: { @@ -528,7 +529,7 @@ void MQClientAPIImpl::unregisterClient(const std::string& addr, LOG_INFO("unregisterClient to broker:%s", addr.c_str()); RemotingCommand request(UNREGISTER_CLIENT, new UnregisterClientRequestHeader(clientID, producerGroup, consumerGroup)); - std::unique_ptr response(m_remotingClient->invokeSync(addr, request)); + std::unique_ptr response(remoting_client_->invokeSync(addr, request)); assert(response != nullptr); switch (response->code()) { case SUCCESS: @@ -548,7 +549,7 @@ void MQClientAPIImpl::endTransactionOneway(const std::string& addr, RemotingCommand request(END_TRANSACTION, requestHeader); request.set_remark(remark); - m_remotingClient->invokeOneway(addr, request); + remoting_client_->invokeOneway(addr, request); } void MQClientAPIImpl::consumerSendMessageBack(const std::string& addr, @@ -567,7 +568,7 @@ void MQClientAPIImpl::consumerSendMessageBack(const std::string& addr, RemotingCommand request(CONSUMER_SEND_MSG_BACK, requestHeader); - std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + std::unique_ptr response(remoting_client_->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->code()) { case SUCCESS: { @@ -587,7 +588,7 @@ void MQClientAPIImpl::lockBatchMQ(const std::string& addr, RemotingCommand request(LOCK_BATCH_MQ, nullptr); request.set_body(requestBody->encode()); - std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + std::unique_ptr response(remoting_client_->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->code()) { case SUCCESS: { @@ -615,9 +616,9 @@ void MQClientAPIImpl::unlockBatchMQ(const std::string& addr, request.set_body(requestBody->encode()); if (oneway) { - m_remotingClient->invokeOneway(addr, request); + remoting_client_->invokeOneway(addr, request); } else { - std::unique_ptr response(m_remotingClient->invokeSync(addr, request, timeoutMillis)); + std::unique_ptr response(remoting_client_->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); switch (response->code()) { case SUCCESS: { @@ -634,7 +635,7 @@ void MQClientAPIImpl::unlockBatchMQ(const std::string& addr, TopicRouteData* MQClientAPIImpl::getTopicRouteInfoFromNameServer(const std::string& topic, int timeoutMillis) { RemotingCommand request(GET_ROUTEINTO_BY_TOPIC, new GetRouteInfoRequestHeader(topic)); - std::unique_ptr response(m_remotingClient->invokeSync(null, request, timeoutMillis)); + std::unique_ptr response(remoting_client_->invokeSync(null, request, timeoutMillis)); assert(response != nullptr); switch (response->code()) { case SUCCESS: { @@ -654,7 +655,7 @@ TopicRouteData* MQClientAPIImpl::getTopicRouteInfoFromNameServer(const std::stri TopicList* MQClientAPIImpl::getTopicListFromNameServer() { RemotingCommand request(GET_ALL_TOPIC_LIST_FROM_NAMESERVER, nullptr); - std::unique_ptr response(m_remotingClient->invokeSync(null, request)); + std::unique_ptr response(remoting_client_->invokeSync(null, request)); assert(response != nullptr); switch (response->code()) { case SUCCESS: { diff --git a/src/MQClientAPIImpl.h b/src/MQClientAPIImpl.h index c77399103..c94769286 100644 --- a/src/MQClientAPIImpl.h +++ b/src/MQClientAPIImpl.h @@ -14,14 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_CLIENT_API_IMPL_H__ -#define __MQ_CLIENT_API_IMPL_H__ +#ifndef ROCKETMQ_MQCLIENTAPIIMPL_H_ +#define ROCKETMQ_MQCLIENTAPIIMPL_H_ #include "CommunicationMode.h" #include "DefaultMQProducerImpl.h" #include "HeartbeatData.h" #include "KVTable.h" -#include "MQClientException.h" +#include "MQException.h" #include "MQClientInstance.h" #include "MQMessageExt.h" #include "PullCallback.h" @@ -29,8 +29,8 @@ #include "SendResult.h" #include "TopicConfig.h" #include "TopicList.h" -#include "TopicPublishInfo.h" -#include "TopicRouteData.h" +#include "TopicPublishInfo.hpp" +#include "TopicRouteData.hpp" #include "protocol/body/LockBatchBody.h" #include "protocol/header/CommandHeader.h" @@ -54,7 +54,7 @@ class MQClientAPIImpl { void start(); void shutdown(); - void updateNameServerAddr(const std::string& addrs); + void updateNameServerAddressList(const std::string& addrs); void createTopic(const std::string& addr, const std::string& defaultTopic, TopicConfig topicConfig); @@ -159,7 +159,7 @@ class MQClientAPIImpl { KVTable getKVListByNamespace(const std::string& projectNamespace, int timeoutMillis); public: - TcpRemotingClient* getRemotingClient() { return m_remotingClient.get(); } + TcpRemotingClient* getRemotingClient() { return remoting_client_.get(); } private: friend class SendCallbackWrap; @@ -191,9 +191,9 @@ class MQClientAPIImpl { PullCallback* pullCallback); private: - std::unique_ptr m_remotingClient; + std::unique_ptr remoting_client_; }; } // namespace rocketmq -#endif // __MQ_CLIENT_API_IMPL_H__ +#endif // ROCKETMQ_MQCLIENTAPIIMPL_H_ diff --git a/src/MQClientConfigImpl.cpp b/src/MQClientConfigImpl.cpp deleted file mode 100644 index b8a24f810..000000000 --- a/src/MQClientConfigImpl.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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 "MQClientConfigImpl.h" - -#include -#include - -#include "NameSpaceUtil.h" -#include "UtilAll.h" - -namespace rocketmq { - -static const std::string DEFAULT_INSTANCE_NAME = "DEFAULT"; - -MQClientConfigImpl::MQClientConfigImpl() - : m_instanceName(DEFAULT_INSTANCE_NAME), - m_tcpWorkerThreadNum(std::min(4, (int)std::thread::hardware_concurrency())), - m_tcpConnectTimeout(3000), - m_tcpTransportTryLockTimeout(3) { - const char* addr = std::getenv(ROCKETMQ_NAMESRV_ADDR_ENV.c_str()); - if (addr != nullptr) { - m_namesrvAddr = addr; - } -} - -std::string MQClientConfigImpl::buildMQClientId() const { - std::string clientId; - clientId.append(UtilAll::getLocalAddress()); // clientIP - clientId.append("@"); - clientId.append(m_instanceName); // instanceName - if (!m_unitName.empty()) { - clientId.append("@"); - clientId.append(m_unitName); // unitName - } - return clientId; -} - -const std::string& MQClientConfigImpl::getGroupName() const { - return m_groupName; -} - -void MQClientConfigImpl::setGroupName(const std::string& groupname) { - m_groupName = groupname; -} - -const std::string& MQClientConfigImpl::getNamesrvAddr() const { - return m_namesrvAddr; -} - -void MQClientConfigImpl::setNamesrvAddr(const std::string& namesrvAddr) { - m_namesrvAddr = NameSpaceUtil::formatNameServerURL(namesrvAddr); -} - -const std::string& MQClientConfigImpl::getInstanceName() const { - return m_instanceName; -} - -void MQClientConfigImpl::setInstanceName(const std::string& instanceName) { - m_instanceName = instanceName; -} - -void MQClientConfigImpl::changeInstanceNameToPID() { - if (m_instanceName == DEFAULT_INSTANCE_NAME) { - m_instanceName = UtilAll::to_string(UtilAll::getProcessId()); - } -} - -const std::string& MQClientConfigImpl::getUnitName() const { - return m_unitName; -} - -void MQClientConfigImpl::setUnitName(std::string unitName) { - m_unitName = unitName; -} - -int MQClientConfigImpl::getTcpTransportWorkerThreadNum() const { - return m_tcpWorkerThreadNum; -} - -void MQClientConfigImpl::setTcpTransportWorkerThreadNum(int num) { - if (num > m_tcpWorkerThreadNum) { - m_tcpWorkerThreadNum = num; - } -} - -uint64_t MQClientConfigImpl::getTcpTransportConnectTimeout() const { - return m_tcpConnectTimeout; -} - -void MQClientConfigImpl::setTcpTransportConnectTimeout(uint64_t timeout) { - m_tcpConnectTimeout = timeout; -} - -uint64_t MQClientConfigImpl::getTcpTransportTryLockTimeout() const { - return m_tcpTransportTryLockTimeout; -} - -void MQClientConfigImpl::setTcpTransportTryLockTimeout(uint64_t timeout) { - m_tcpTransportTryLockTimeout = std::max(1000, timeout) / 1000; -} - -} // namespace rocketmq diff --git a/src/MQClientConfigImpl.h b/src/MQClientConfigImpl.h deleted file mode 100644 index a4e522c9b..000000000 --- a/src/MQClientConfigImpl.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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_CONFIG_IMPL_H__ -#define __MQ_CLIENT_CONFIG_IMPL_H__ - -#include "MQClientConfig.h" - -namespace rocketmq { - -/** - * MQ Client Config - */ -class MQClientConfigImpl : virtual public MQClientConfig { - public: - MQClientConfigImpl(); - virtual ~MQClientConfigImpl() = default; - - std::string buildMQClientId() const override; - - const std::string& getGroupName() const override; - void setGroupName(const std::string& groupname) override; - - const std::string& getNamesrvAddr() const override; - void setNamesrvAddr(const std::string& namesrvAddr) override; - - const std::string& getInstanceName() const override; - void setInstanceName(const std::string& instanceName) override; - - void changeInstanceNameToPID() override; - - const std::string& getUnitName() const override; - void setUnitName(std::string unitName) override; - - int getTcpTransportWorkerThreadNum() const override; - void setTcpTransportWorkerThreadNum(int num) override; - - uint64_t getTcpTransportConnectTimeout() const override; - void setTcpTransportConnectTimeout(uint64_t timeout) override; // ms - - uint64_t getTcpTransportTryLockTimeout() const override; - void setTcpTransportTryLockTimeout(uint64_t timeout) override; // ms - - protected: - std::string m_namesrvAddr; - std::string m_instanceName; - std::string m_groupName; - std::string m_unitName; - - int m_tcpWorkerThreadNum; - uint64_t m_tcpConnectTimeout; // ms - uint64_t m_tcpTransportTryLockTimeout; // s -}; - -} // namespace rocketmq - -#endif // __MQ_CLIENT_CONFIG_H__ diff --git a/src/MQClientConfigImpl.hpp b/src/MQClientConfigImpl.hpp new file mode 100644 index 000000000..9eec2393e --- /dev/null +++ b/src/MQClientConfigImpl.hpp @@ -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 ROCKETMQ_MQCLIENTCONFIGIMPL_HPP_ +#define ROCKETMQ_MQCLIENTCONFIGIMPL_HPP_ + +#include // std::min, std::max +#include // std::thread::hardware_concurrency + +#include "MQClientConfig.h" +#include "NameSpaceUtil.h" +#include "UtilAll.h" + +namespace rocketmq { + +/** + * MQ Client Config + */ +class MQClientConfigImpl : virtual public MQClientConfig { + public: + MQClientConfigImpl() + : instance_name_("DEFAULT"), + tcp_worker_thread_num_(std::min(4, (int)std::thread::hardware_concurrency())), + tcp_connect_timeout(3000), + tcp_transport_try_lock_timeout_(3) { + const char* addr = std::getenv(ROCKETMQ_NAMESRV_ADDR_ENV.c_str()); + if (addr != nullptr) { + namesrv_addr_ = addr; + } + } + virtual ~MQClientConfigImpl() = default; + + std::string buildMQClientId() const override { + std::string clientId; + clientId.append(UtilAll::getLocalAddress()); // clientIP + clientId.append("@"); + clientId.append(instance_name_); // instanceName + if (!unit_name_.empty()) { + clientId.append("@"); + clientId.append(unit_name_); // unitName + } + return clientId; + } + + const std::string& getGroupName() const override { return group_name_; } + void setGroupName(const std::string& groupname) override { group_name_ = groupname; } + + const std::string& getNamesrvAddr() const override { return namesrv_addr_; } + void setNamesrvAddr(const std::string& namesrvAddr) override { + namesrv_addr_ = NameSpaceUtil::formatNameServerURL(namesrvAddr); + } + + const std::string& getInstanceName() const override { return instance_name_; } + void setInstanceName(const std::string& instanceName) override { instance_name_ = instanceName; } + + void changeInstanceNameToPID() override { + if (instance_name_ == "DEFAULT") { + instance_name_ = UtilAll::to_string(UtilAll::getProcessId()); + } + } + + const std::string& getUnitName() const override { return unit_name_; } + void setUnitName(std::string unitName) override { unit_name_ = unitName; } + + int getTcpTransportWorkerThreadNum() const override { return tcp_worker_thread_num_; } + void setTcpTransportWorkerThreadNum(int num) override { + if (num > tcp_worker_thread_num_) { + tcp_worker_thread_num_ = num; + } + } + + uint64_t getTcpTransportConnectTimeout() const override { return tcp_connect_timeout; } + void setTcpTransportConnectTimeout(uint64_t millisec) override { tcp_connect_timeout = millisec; } + + uint64_t getTcpTransportTryLockTimeout() const override { return tcp_transport_try_lock_timeout_; } + void setTcpTransportTryLockTimeout(uint64_t millisec) override { + tcp_transport_try_lock_timeout_ = std::max(1000, millisec) / 1000; + } + + protected: + std::string namesrv_addr_; + std::string instance_name_; + std::string group_name_; + std::string unit_name_; + + int tcp_worker_thread_num_; + uint64_t tcp_connect_timeout; // ms + uint64_t tcp_transport_try_lock_timeout_; // s +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_MQCLIENTCONFIGIMPL_HPP_ diff --git a/src/MQClientImpl.cpp b/src/MQClientImpl.cpp index 83b110cd6..195e6800f 100644 --- a/src/MQClientImpl.cpp +++ b/src/MQClientImpl.cpp @@ -19,7 +19,7 @@ #include "Logging.h" #include "MQAdminImpl.h" #include "MQClientManager.h" -#include "TopicPublishInfo.h" +#include "TopicPublishInfo.hpp" #include "UtilAll.h" namespace rocketmq { @@ -31,48 +31,48 @@ namespace rocketmq { const char* rocketmq_build_time = "VERSION: " ROCKETMQCPP_VERSION ", BUILD DATE: " BUILD_DATE; void MQClientImpl::start() { - if (nullptr == m_clientInstance) { - if (nullptr == m_clientConfig) { + if (nullptr == client_instance_) { + if (nullptr == client_config_) { THROW_MQEXCEPTION(MQClientException, "have not clientConfig for create clientInstance.", -1); } - m_clientInstance = MQClientManager::getInstance()->getOrCreateMQClientInstance(*m_clientConfig, m_rpcHook); + client_instance_ = MQClientManager::getInstance()->getOrCreateMQClientInstance(*client_config_, rpc_hook_); } - LOG_INFO_NEW("MQClientImpl start, clientId:{}, real nameservAddr:{}", m_clientInstance->getClientId(), - m_clientInstance->getNamesrvAddr()); + LOG_INFO_NEW("MQClientImpl start, clientId:{}, real nameservAddr:{}", client_instance_->getClientId(), + client_instance_->getNamesrvAddr()); } void MQClientImpl::shutdown() { - m_clientInstance = nullptr; + client_instance_ = nullptr; } void MQClientImpl::createTopic(const std::string& key, const std::string& newTopic, int queueNum) { try { - m_clientInstance->getMQAdminImpl()->createTopic(key, newTopic, queueNum); + client_instance_->getMQAdminImpl()->createTopic(key, newTopic, queueNum); } catch (MQException& e) { LOG_ERROR(e.what()); } } int64_t MQClientImpl::searchOffset(const MQMessageQueue& mq, uint64_t timestamp) { - return m_clientInstance->getMQAdminImpl()->searchOffset(mq, timestamp); + return client_instance_->getMQAdminImpl()->searchOffset(mq, timestamp); } int64_t MQClientImpl::maxOffset(const MQMessageQueue& mq) { - return m_clientInstance->getMQAdminImpl()->maxOffset(mq); + return client_instance_->getMQAdminImpl()->maxOffset(mq); } int64_t MQClientImpl::minOffset(const MQMessageQueue& mq) { - return m_clientInstance->getMQAdminImpl()->minOffset(mq); + return client_instance_->getMQAdminImpl()->minOffset(mq); } int64_t MQClientImpl::earliestMsgStoreTime(const MQMessageQueue& mq) { - return m_clientInstance->getMQAdminImpl()->earliestMsgStoreTime(mq); + return client_instance_->getMQAdminImpl()->earliestMsgStoreTime(mq); } MQMessageExt MQClientImpl::viewMessage(const std::string& msgId) { - return m_clientInstance->getMQAdminImpl()->viewMessage(msgId); + return client_instance_->getMQAdminImpl()->viewMessage(msgId); } QueryResult MQClientImpl::queryMessage(const std::string& topic, @@ -80,20 +80,20 @@ QueryResult MQClientImpl::queryMessage(const std::string& topic, int maxNum, int64_t begin, int64_t end) { - return m_clientInstance->getMQAdminImpl()->queryMessage(topic, key, maxNum, begin, end); + return client_instance_->getMQAdminImpl()->queryMessage(topic, key, maxNum, begin, end); } bool MQClientImpl::isServiceStateOk() { - return m_serviceState == RUNNING; + return service_state_ == RUNNING; } MQClientInstancePtr MQClientImpl::getClientInstance() const { - return m_clientInstance; + return client_instance_; } void MQClientImpl::setClientInstance(MQClientInstancePtr clientInstance) { - if (m_serviceState == CREATE_JUST) { - m_clientInstance = clientInstance; + if (service_state_ == CREATE_JUST) { + client_instance_ = clientInstance; } else { THROW_MQEXCEPTION(MQClientException, "Client already start, can not reset clientInstance!", -1); } diff --git a/src/MQClientImpl.h b/src/MQClientImpl.h index 08078189c..879f471ce 100644 --- a/src/MQClientImpl.h +++ b/src/MQClientImpl.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_CLIENT_IMPL_H__ -#define __MQ_CLIENT_IMPL_H__ +#ifndef ROCKETMQ_MQCLIENTIMPL_H_ +#define ROCKETMQ_MQCLIENTIMPL_H_ #include "MQAdmin.h" #include "MQClientConfig.h" @@ -27,7 +27,7 @@ namespace rocketmq { class MQClientImpl : public MQAdmin { public: MQClientImpl(MQClientConfigPtr config, RPCHookPtr rpcHook) - : m_clientConfig(config), m_rpcHook(rpcHook), m_serviceState(CREATE_JUST), m_clientInstance(nullptr) {} + : client_config_(config), rpc_hook_(rpcHook), service_state_(CREATE_JUST), client_instance_(nullptr) {} public: // MQAdmin void createTopic(const std::string& key, const std::string& newTopic, int queueNum) override; @@ -51,16 +51,16 @@ class MQClientImpl : public MQAdmin { MQClientInstancePtr getClientInstance() const; void setClientInstance(MQClientInstancePtr clientInstance); - RPCHookPtr getRPCHook() { return m_rpcHook; } - void setRPCHook(RPCHookPtr rpcHook) { m_rpcHook = rpcHook; } + RPCHookPtr getRPCHook() { return rpc_hook_; } + void setRPCHook(RPCHookPtr rpcHook) { rpc_hook_ = rpcHook; } protected: - MQClientConfigPtr m_clientConfig; - RPCHookPtr m_rpcHook; - volatile ServiceState m_serviceState; - MQClientInstancePtr m_clientInstance; + MQClientConfigPtr client_config_; + RPCHookPtr rpc_hook_; + volatile ServiceState service_state_; + MQClientInstancePtr client_instance_; }; } // namespace rocketmq -#endif // __MQ_CLIENT_IMPL_H__ +#endif // ROCKETMQ_MQCLIENTIMPL_H_ diff --git a/src/MQClientInstance.cpp b/src/MQClientInstance.cpp index 213d74b64..fa58bde71 100644 --- a/src/MQClientInstance.cpp +++ b/src/MQClientInstance.cpp @@ -31,13 +31,9 @@ #include "RebalanceImpl.h" #include "RebalanceService.h" #include "TcpRemotingClient.h" -#include "TopicPublishInfo.h" +#include "TopicPublishInfo.hpp" #include "UtilAll.h" -#define MAX_BUFF_SIZE 8192 -#define PROCESS_NAME_BUF_SIZE 256 -#define SAFE_BUFF_SIZE (MAX_BUFF_SIZE - PROCESS_NAME_BUF_SIZE) // 8192 - 256 = 7936 - namespace rocketmq { static const long LOCK_TIMEOUT_MILLIS = 3000L; @@ -46,44 +42,44 @@ MQClientInstance::MQClientInstance(const MQClientConfig& clientConfig, const std : MQClientInstance(clientConfig, clientId, nullptr) {} MQClientInstance::MQClientInstance(const MQClientConfig& clientConfig, const std::string& clientId, RPCHookPtr rpcHook) - : m_clientId(clientId), - m_rebalanceService(new RebalanceService(this)), - m_pullMessageService(new PullMessageService(this)), - m_scheduledExecutorService("MQClient", false) { + : client_id_(clientId), + rebalance_service_(new RebalanceService(this)), + pull_message_service_(new PullMessageService(this)), + scheduled_executor_service_("MQClient", false) { // default Topic register TopicPublishInfoPtr defaultTopicInfo(new TopicPublishInfo()); - m_topicPublishInfoTable[AUTO_CREATE_TOPIC_KEY_TOPIC] = defaultTopicInfo; + topic_publish_info_table_[AUTO_CREATE_TOPIC_KEY_TOPIC] = defaultTopicInfo; - m_clientRemotingProcessor.reset(new ClientRemotingProcessor(this)); - m_mqClientAPIImpl.reset(new MQClientAPIImpl(m_clientRemotingProcessor.get(), rpcHook, clientConfig)); + client_remoting_processor_.reset(new ClientRemotingProcessor(this)); + mq_client_api_impl_.reset(new MQClientAPIImpl(client_remoting_processor_.get(), rpcHook, clientConfig)); std::string namesrvAddr = clientConfig.getNamesrvAddr(); if (!namesrvAddr.empty()) { - m_mqClientAPIImpl->updateNameServerAddr(namesrvAddr); + mq_client_api_impl_->updateNameServerAddressList(namesrvAddr); LOG_INFO_NEW("user specified name server address: {}", namesrvAddr); } - m_mqAdminImpl.reset(new MQAdminImpl(this)); + mq_admin_impl_.reset(new MQAdminImpl(this)); - m_serviceState = CREATE_JUST; + service_state_ = CREATE_JUST; LOG_DEBUG_NEW("MQClientInstance construct"); } MQClientInstance::~MQClientInstance() { - LOG_INFO_NEW("MQClientInstance:{} destruct", m_clientId); + LOG_INFO_NEW("MQClientInstance:{} destruct", client_id_); // UNNECESSARY: - m_producerTable.clear(); - m_consumerTable.clear(); - m_topicPublishInfoTable.clear(); - m_topicRouteTable.clear(); - m_brokerAddrTable.clear(); + producer_table_.clear(); + consumer_table_.clear(); + topic_publish_info_table_.clear(); + topic_route_table_.clear(); + broker_addr_table_.clear(); - m_mqClientAPIImpl = nullptr; + mq_client_api_impl_ = nullptr; } std::string MQClientInstance::getNamesrvAddr() const { - auto namesrvAddrs = m_mqClientAPIImpl->getRemotingClient()->getNameServerAddressList(); + auto namesrvAddrs = mq_client_api_impl_->getRemotingClient()->getNameServerAddressList(); std::ostringstream oss; for (const auto& addr : namesrvAddrs) { oss << addr << ";"; @@ -98,7 +94,7 @@ TopicPublishInfoPtr MQClientInstance::topicRouteData2TopicPublishInfo(const std: auto& mqList = const_cast(info->getMessageQueueList()); - std::string orderTopicConf = route->getOrderTopicConf(); + std::string orderTopicConf = route->order_topic_conf(); if (!orderTopicConf.empty()) { // order msg // "broker-a:8";"broker-b:8" std::vector brokers; @@ -113,38 +109,38 @@ TopicPublishInfoPtr MQClientInstance::topicRouteData2TopicPublishInfo(const std: } info->setOrderTopic(true); } else { // no order msg - const auto& qds = route->getQueueDatas(); + const auto& qds = route->queue_datas(); for (const auto& qd : qds) { - if (PermName::isWriteable(qd.perm)) { + if (PermName::isWriteable(qd.perm())) { const BrokerData* brokerData = nullptr; - for (const auto& bd : route->getBrokerDatas()) { - if (bd.brokerName == qd.brokerName) { + for (const auto& bd : route->broker_datas()) { + if (bd.broker_name() == qd.broker_name()) { brokerData = &bd; break; } } if (nullptr == brokerData) { - LOG_WARN_NEW("MQClientInstance: broker:{} of topic:{} have not data", qd.brokerName, topic); + LOG_WARN_NEW("MQClientInstance: broker:{} of topic:{} have not data", qd.broker_name(), topic); continue; } - if (brokerData->brokerAddrs.find(MASTER_ID) == brokerData->brokerAddrs.end()) { - LOG_WARN_NEW("MQClientInstance: broker:{} of topic:{} have not master node", qd.brokerName, topic); + if (brokerData->broker_addrs().find(MASTER_ID) == brokerData->broker_addrs().end()) { + LOG_WARN_NEW("MQClientInstance: broker:{} of topic:{} have not master node", qd.broker_name(), topic); continue; } - for (int i = 0; i < qd.writeQueueNums; i++) { - mqList.emplace_back(topic, qd.brokerName, i); + for (int i = 0; i < qd.write_queue_nums(); i++) { + mqList.emplace_back(topic, qd.broker_name(), i); } } } // sort, make brokerName is staggered. std::sort(mqList.begin(), mqList.end(), [](const MQMessageQueue& a, const MQMessageQueue& b) { - auto result = a.getQueueId() - b.getQueueId(); + auto result = a.queue_id() - b.queue_id(); if (result == 0) { - result = a.getBrokerName().compare(b.getBrokerName()); + result = a.broker_name().compare(b.broker_name()); } return result < 0; }); @@ -158,11 +154,11 @@ TopicPublishInfoPtr MQClientInstance::topicRouteData2TopicPublishInfo(const std: std::vector MQClientInstance::topicRouteData2TopicSubscribeInfo(const std::string& topic, TopicRouteDataPtr route) { std::vector mqList; - const auto& queueDatas = route->getQueueDatas(); + const auto& queueDatas = route->queue_datas(); for (const auto& qd : queueDatas) { - if (PermName::isReadable(qd.perm)) { - for (int i = 0; i < qd.readQueueNums; i++) { - MQMessageQueue mq(topic, qd.brokerName, i); + if (PermName::isReadable(qd.perm())) { + for (int i = 0; i < qd.read_queue_nums(); i++) { + MQMessageQueue mq(topic, qd.broker_name(), i); mqList.push_back(mq); } } @@ -171,31 +167,31 @@ std::vector MQClientInstance::topicRouteData2TopicSubscribeInfo( } void MQClientInstance::start() { - switch (m_serviceState) { + switch (service_state_) { case CREATE_JUST: - LOG_INFO_NEW("the client instance [{}] is starting", m_clientId); - m_serviceState = START_FAILED; + LOG_INFO_NEW("the client instance [{}] is starting", client_id_); + service_state_ = START_FAILED; - m_mqClientAPIImpl->start(); + mq_client_api_impl_->start(); // start various schedule tasks startScheduledTask(); // start pull service - m_pullMessageService->start(); + pull_message_service_->start(); // start rebalance service - m_rebalanceService->start(); + rebalance_service_->start(); - LOG_INFO_NEW("the client instance [{}] start OK", m_clientId); - m_serviceState = RUNNING; + LOG_INFO_NEW("the client instance [{}] start OK", client_id_); + service_state_ = RUNNING; break; case RUNNING: - LOG_INFO_NEW("the client instance [{}] already running.", m_clientId, m_serviceState); + LOG_INFO_NEW("the client instance [{}] already running.", client_id_, service_state_); break; case SHUTDOWN_ALREADY: case START_FAILED: - LOG_INFO_NEW("the client instance [{}] start failed with fault state:{}", m_clientId, m_serviceState); + LOG_INFO_NEW("the client instance [{}] start failed with fault state:{}", client_id_, service_state_); break; default: break; @@ -211,18 +207,18 @@ void MQClientInstance::shutdown() { return; } - switch (m_serviceState) { + switch (service_state_) { case CREATE_JUST: break; case RUNNING: { - m_serviceState = SHUTDOWN_ALREADY; - m_pullMessageService->shutdown(); - m_scheduledExecutorService.shutdown(); - m_mqClientAPIImpl->shutdown(); - m_rebalanceService->shutdown(); - - MQClientManager::getInstance()->removeMQClientInstance(m_clientId); - LOG_INFO_NEW("the client instance [{}] shutdown OK", m_clientId); + service_state_ = SHUTDOWN_ALREADY; + pull_message_service_->shutdown(); + scheduled_executor_service_.shutdown(); + mq_client_api_impl_->shutdown(); + rebalance_service_->shutdown(); + + MQClientManager::getInstance()->removeMQClientInstance(client_id_); + LOG_INFO_NEW("the client instance [{}] shutdown OK", client_id_); } break; case SHUTDOWN_ALREADY: break; @@ -232,32 +228,32 @@ void MQClientInstance::shutdown() { } bool MQClientInstance::isRunning() { - return m_serviceState == RUNNING; + return service_state_ == RUNNING; } void MQClientInstance::startScheduledTask() { - LOG_INFO_NEW("start scheduled task:{}", m_clientId); - m_scheduledExecutorService.startup(); + LOG_INFO_NEW("start scheduled task:{}", client_id_); + scheduled_executor_service_.startup(); // updateTopicRouteInfoFromNameServer - m_scheduledExecutorService.schedule(std::bind(&MQClientInstance::updateTopicRouteInfoPeriodically, this), 10, - time_unit::milliseconds); + scheduled_executor_service_.schedule(std::bind(&MQClientInstance::updateTopicRouteInfoPeriodically, this), 10, + time_unit::milliseconds); // sendHeartbeatToAllBroker - m_scheduledExecutorService.schedule(std::bind(&MQClientInstance::sendHeartbeatToAllBrokerPeriodically, this), 1000, - time_unit::milliseconds); + scheduled_executor_service_.schedule(std::bind(&MQClientInstance::sendHeartbeatToAllBrokerPeriodically, this), 1000, + time_unit::milliseconds); // persistAllConsumerOffset - m_scheduledExecutorService.schedule(std::bind(&MQClientInstance::persistAllConsumerOffsetPeriodically, this), - 1000 * 10, time_unit::milliseconds); + scheduled_executor_service_.schedule(std::bind(&MQClientInstance::persistAllConsumerOffsetPeriodically, this), + 1000 * 10, time_unit::milliseconds); } void MQClientInstance::updateTopicRouteInfoPeriodically() { updateTopicRouteInfoFromNameServer(); // next round - m_scheduledExecutorService.schedule(std::bind(&MQClientInstance::updateTopicRouteInfoPeriodically, this), 1000 * 30, - time_unit::milliseconds); + scheduled_executor_service_.schedule(std::bind(&MQClientInstance::updateTopicRouteInfoPeriodically, this), 1000 * 30, + time_unit::milliseconds); } void MQClientInstance::sendHeartbeatToAllBrokerPeriodically() { @@ -265,20 +261,20 @@ void MQClientInstance::sendHeartbeatToAllBrokerPeriodically() { sendHeartbeatToAllBrokerWithLock(); // next round - m_scheduledExecutorService.schedule(std::bind(&MQClientInstance::sendHeartbeatToAllBrokerPeriodically, this), - 1000 * 30, time_unit::milliseconds); + scheduled_executor_service_.schedule(std::bind(&MQClientInstance::sendHeartbeatToAllBrokerPeriodically, this), + 1000 * 30, time_unit::milliseconds); } void MQClientInstance::persistAllConsumerOffsetPeriodically() { persistAllConsumerOffset(); // next round - m_scheduledExecutorService.schedule(std::bind(&MQClientInstance::persistAllConsumerOffsetPeriodically, this), - 1000 * 5, time_unit::milliseconds); + scheduled_executor_service_.schedule(std::bind(&MQClientInstance::persistAllConsumerOffsetPeriodically, this), + 1000 * 5, time_unit::milliseconds); } const std::string& MQClientInstance::getClientId() const { - return m_clientId; + return client_id_; } void MQClientInstance::updateTopicRouteInfoFromNameServer() { @@ -299,8 +295,8 @@ void MQClientInstance::updateTopicRouteInfoFromNameServer() { } void MQClientInstance::cleanOfflineBroker() { - if (UtilAll::try_lock_for(m_lockNamesrv, LOCK_TIMEOUT_MILLIS)) { - std::lock_guard lock(m_lockNamesrv, std::adopt_lock); + if (UtilAll::try_lock_for(lock_namesrv_, LOCK_TIMEOUT_MILLIS)) { + std::lock_guard lock(lock_namesrv_, std::adopt_lock); std::set offlineBrokers; BrokerAddrMAP updatedTable(getBrokerAddrTable()); @@ -330,10 +326,10 @@ void MQClientInstance::cleanOfflineBroker() { if (offlineBrokers.size() > 0) { resetBrokerAddrTable(std::move(updatedTable)); - std::lock_guard lock(m_topicBrokerAddrTableMutex); - for (auto it = m_topicBrokerAddrTable.begin(); it != m_topicBrokerAddrTable.end();) { + std::lock_guard lock(topic_broker_addr_table_mutex_); + for (auto it = topic_broker_addr_table_.begin(); it != topic_broker_addr_table_.end();) { if (offlineBrokers.find(it->second.first) != offlineBrokers.end()) { - it = m_topicBrokerAddrTable.erase(it); + it = topic_broker_addr_table_.erase(it); } else { it++; } @@ -345,12 +341,12 @@ void MQClientInstance::cleanOfflineBroker() { } bool MQClientInstance::isBrokerAddrExistInTopicRouteTable(const std::string& addr) { - std::lock_guard lock(m_topicRouteTableMutex); - for (const auto& it : m_topicRouteTable) { + std::lock_guard lock(topic_route_table_mutex_); + for (const auto& it : topic_route_table_) { const auto topicRouteData = it.second; - const auto& bds = topicRouteData->getBrokerDatas(); + const auto& bds = topicRouteData->broker_datas(); for (const auto& bd : bds) { - for (const auto& itAddr : bd.brokerAddrs) { + for (const auto& itAddr : bd.broker_addrs()) { if (itAddr.second == addr) { return true; } @@ -361,8 +357,8 @@ bool MQClientInstance::isBrokerAddrExistInTopicRouteTable(const std::string& add } void MQClientInstance::sendHeartbeatToAllBrokerWithLock() { - if (m_lockHeartbeat.try_lock()) { - std::lock_guard lock(m_lockHeartbeat, std::adopt_lock); + if (lock_heartbeat_.try_lock()) { + std::lock_guard lock(lock_heartbeat_, std::adopt_lock); sendHeartbeatToAllBroker(); } else { LOG_WARN_NEW("lock heartBeat, but failed."); @@ -370,9 +366,9 @@ void MQClientInstance::sendHeartbeatToAllBrokerWithLock() { } void MQClientInstance::persistAllConsumerOffset() { - std::lock_guard lock(m_consumerTableMutex); - for (const auto& it : m_consumerTable) { - LOG_DEBUG_NEW("the client instance [{}] start persistAllConsumerOffset", m_clientId); + std::lock_guard lock(consumer_table_mutex_); + for (const auto& it : consumer_table_) { + LOG_DEBUG_NEW("the client instance [{}] start persistAllConsumerOffset", client_id_); it.second->persistConsumerOffset(); } } @@ -399,7 +395,7 @@ void MQClientInstance::sendHeartbeatToAllBroker() { } try { - m_mqClientAPIImpl->sendHearbeat(addr, heartbeatData.get(), 3000); + mq_client_api_impl_->sendHearbeat(addr, heartbeatData.get(), 3000); } catch (const MQException& e) { LOG_ERROR_NEW("{}", e.what()); } @@ -412,25 +408,26 @@ void MQClientInstance::sendHeartbeatToAllBroker() { } bool MQClientInstance::updateTopicRouteInfoFromNameServer(const std::string& topic, bool isDefault) { - if (UtilAll::try_lock_for(m_lockNamesrv, LOCK_TIMEOUT_MILLIS)) { - std::lock_guard lock(m_lockNamesrv, std::adopt_lock); + if (UtilAll::try_lock_for(lock_namesrv_, LOCK_TIMEOUT_MILLIS)) { + std::lock_guard lock(lock_namesrv_, std::adopt_lock); LOG_DEBUG_NEW("updateTopicRouteInfoFromNameServer start:{}", topic); try { TopicRouteDataPtr topicRouteData; if (isDefault) { - topicRouteData.reset(m_mqClientAPIImpl->getTopicRouteInfoFromNameServer(AUTO_CREATE_TOPIC_KEY_TOPIC, 1000 * 3)); + topicRouteData.reset( + mq_client_api_impl_->getTopicRouteInfoFromNameServer(AUTO_CREATE_TOPIC_KEY_TOPIC, 1000 * 3)); if (topicRouteData != nullptr) { - auto& queueDatas = topicRouteData->getQueueDatas(); + auto& queueDatas = topicRouteData->queue_datas(); for (auto& qd : queueDatas) { - int queueNums = std::min(4, qd.readQueueNums); - qd.readQueueNums = queueNums; - qd.writeQueueNums = queueNums; + int queueNums = std::min(4, qd.read_queue_nums()); + qd.set_read_queue_nums(queueNums); + qd.set_write_queue_nums(queueNums); } } LOG_DEBUG_NEW("getTopicRouteInfoFromNameServer is null for topic: {}", topic); } else { - topicRouteData.reset(m_mqClientAPIImpl->getTopicRouteInfoFromNameServer(topic, 1000 * 3)); + topicRouteData.reset(mq_client_api_impl_->getTopicRouteInfoFromNameServer(topic, 1000 * 3)); } if (topicRouteData != nullptr) { LOG_INFO_NEW("updateTopicRouteInfoFromNameServer has data"); @@ -441,10 +438,10 @@ bool MQClientInstance::updateTopicRouteInfoFromNameServer(const std::string& top LOG_INFO_NEW("updateTopicRouteInfoFromNameServer changed:{}", topic); // update broker addr - const auto& brokerDatas = topicRouteData->getBrokerDatas(); + const auto& brokerDatas = topicRouteData->broker_datas(); for (const auto& bd : brokerDatas) { - LOG_INFO_NEW("updateTopicRouteInfoFromNameServer changed with broker name:{}", bd.brokerName); - addBrokerToAddrTable(bd.brokerName, bd.brokerAddrs); + LOG_INFO_NEW("updateTopicRouteInfoFromNameServer changed with broker name:{}", bd.broker_name()); + addBrokerToAddrTable(bd.broker_name(), bd.broker_addrs()); } // update publish info @@ -484,7 +481,7 @@ HeartbeatData* MQClientInstance::prepareHeartbeatData() { HeartbeatData* pHeartbeatData = new HeartbeatData(); // clientID - pHeartbeatData->setClientID(m_clientId); + pHeartbeatData->setClientID(client_id_); // Consumer insertConsumerInfoToHeartBeatData(pHeartbeatData); @@ -496,8 +493,8 @@ HeartbeatData* MQClientInstance::prepareHeartbeatData() { } void MQClientInstance::insertConsumerInfoToHeartBeatData(HeartbeatData* pHeartbeatData) { - std::lock_guard lock(m_consumerTableMutex); - for (const auto& it : m_consumerTable) { + std::lock_guard lock(consumer_table_mutex_); + for (const auto& it : consumer_table_) { const auto* consumer = it.second; ConsumerData consumerData; consumerData.groupName = consumer->groupName(); @@ -513,8 +510,8 @@ void MQClientInstance::insertConsumerInfoToHeartBeatData(HeartbeatData* pHeartbe } void MQClientInstance::insertProducerInfoToHeartBeatData(HeartbeatData* pHeartbeatData) { - std::lock_guard lock(m_producerTableMutex); - for (const auto& it : m_producerTable) { + std::lock_guard lock(producer_table_mutex_); + for (const auto& it : producer_table_) { ProducerData producerData; producerData.groupName = it.first; pHeartbeatData->insertDataToProducerDataSet(producerData); @@ -529,17 +526,17 @@ bool MQClientInstance::topicRouteDataIsChange(TopicRouteData* olddata, TopicRout } TopicRouteDataPtr MQClientInstance::getTopicRouteData(const std::string& topic) { - std::lock_guard lock(m_topicRouteTableMutex); - const auto& it = m_topicRouteTable.find(topic); - if (it != m_topicRouteTable.end()) { + std::lock_guard lock(topic_route_table_mutex_); + const auto& it = topic_route_table_.find(topic); + if (it != topic_route_table_.end()) { return it->second; } return nullptr; } void MQClientInstance::addTopicRouteData(const std::string& topic, TopicRouteDataPtr topicRouteData) { - std::lock_guard lock(m_topicRouteTableMutex); - m_topicRouteTable[topic] = topicRouteData; + std::lock_guard lock(topic_route_table_mutex_); + topic_route_table_[topic] = topicRouteData; } bool MQClientInstance::registerConsumer(const std::string& group, MQConsumerInner* consumer) { @@ -562,8 +559,8 @@ void MQClientInstance::unregisterConsumer(const std::string& group) { } void MQClientInstance::unregisterClientWithLock(const std::string& producerGroup, const std::string& consumerGroup) { - if (UtilAll::try_lock_for(m_lockHeartbeat, LOCK_TIMEOUT_MILLIS)) { - std::lock_guard lock(m_lockHeartbeat, std::adopt_lock); + if (UtilAll::try_lock_for(lock_heartbeat_, LOCK_TIMEOUT_MILLIS)) { + std::lock_guard lock(lock_heartbeat_, std::adopt_lock); try { unregisterClient(producerGroup, consumerGroup); @@ -584,7 +581,7 @@ void MQClientInstance::unregisterClient(const std::string& producerGroup, const const auto& index = it2.first; const auto& addr = it2.second; try { - m_mqClientAPIImpl->unregisterClient(addr, m_clientId, producerGroup, consumerGroup); + mq_client_api_impl_->unregisterClient(addr, client_id_, producerGroup, consumerGroup); LOG_INFO_NEW("unregister client[Producer: {} Consumer: {}] from broker[{} {} {}] success", producerGroup, consumerGroup, brokerName, index, addr); } catch (const std::exception& e) { @@ -614,26 +611,26 @@ void MQClientInstance::unregisterProducer(const std::string& group) { } void MQClientInstance::rebalanceImmediately() { - m_rebalanceService->wakeup(); + rebalance_service_->wakeup(); } void MQClientInstance::doRebalance() { - LOG_INFO_NEW("the client instance:{} start doRebalance", m_clientId); + LOG_INFO_NEW("the client instance:{} start doRebalance", client_id_); if (getConsumerTableSize() > 0) { - std::lock_guard lock(m_consumerTableMutex); - for (auto& it : m_consumerTable) { + std::lock_guard lock(consumer_table_mutex_); + for (auto& it : consumer_table_) { it.second->doRebalance(); } } - LOG_INFO_NEW("the client instance [{}] finish doRebalance", m_clientId); + LOG_INFO_NEW("the client instance [{}] finish doRebalance", client_id_); } void MQClientInstance::doRebalanceByConsumerGroup(const std::string& consumerGroup) { - std::lock_guard lock(m_consumerTableMutex); - const auto& it = m_consumerTable.find(consumerGroup); - if (it != m_consumerTable.end()) { + std::lock_guard lock(consumer_table_mutex_); + const auto& it = consumer_table_.find(consumerGroup); + if (it != consumer_table_.end()) { try { - LOG_INFO_NEW("the client instance [{}] start doRebalance for consumer [{}]", m_clientId, consumerGroup); + LOG_INFO_NEW("the client instance [{}] start doRebalance for consumer [{}]", client_id_, consumerGroup); auto* consumer = it->second; consumer->doRebalance(); } catch (const std::exception& e) { @@ -643,40 +640,40 @@ void MQClientInstance::doRebalanceByConsumerGroup(const std::string& consumerGro } MQProducerInner* MQClientInstance::selectProducer(const std::string& producerName) { - std::lock_guard lock(m_producerTableMutex); - const auto& it = m_producerTable.find(producerName); - if (it != m_producerTable.end()) { + std::lock_guard lock(producer_table_mutex_); + const auto& it = producer_table_.find(producerName); + if (it != producer_table_.end()) { return it->second; } return nullptr; } bool MQClientInstance::addProducerToTable(const std::string& producerName, MQProducerInner* producer) { - std::lock_guard lock(m_producerTableMutex); - if (m_producerTable.find(producerName) != m_producerTable.end()) { + std::lock_guard lock(producer_table_mutex_); + if (producer_table_.find(producerName) != producer_table_.end()) { return false; } else { - m_producerTable[producerName] = producer; + producer_table_[producerName] = producer; return true; } } void MQClientInstance::eraseProducerFromTable(const std::string& producerName) { - std::lock_guard lock(m_producerTableMutex); - const auto& it = m_producerTable.find(producerName); - if (it != m_producerTable.end()) { - m_producerTable.erase(it); + std::lock_guard lock(producer_table_mutex_); + const auto& it = producer_table_.find(producerName); + if (it != producer_table_.end()) { + producer_table_.erase(it); } } int MQClientInstance::getProducerTableSize() { - std::lock_guard lock(m_producerTableMutex); - return m_producerTable.size(); + std::lock_guard lock(producer_table_mutex_); + return producer_table_.size(); } void MQClientInstance::getTopicListFromTopicPublishInfo(std::set& topicList) { - std::lock_guard lock(m_topicPublishInfoTableMutex); - for (const auto& it : m_topicPublishInfoTable) { + std::lock_guard lock(topic_publish_info_table_mutex_); + for (const auto& it : topic_publish_info_table_) { topicList.insert(it.first); } } @@ -686,82 +683,82 @@ void MQClientInstance::updateProducerTopicPublishInfo(const std::string& topic, } MQConsumerInner* MQClientInstance::selectConsumer(const std::string& group) { - std::lock_guard lock(m_consumerTableMutex); - const auto& it = m_consumerTable.find(group); - if (it != m_consumerTable.end()) { + std::lock_guard lock(consumer_table_mutex_); + const auto& it = consumer_table_.find(group); + if (it != consumer_table_.end()) { return it->second; } return nullptr; } bool MQClientInstance::addConsumerToTable(const std::string& consumerName, MQConsumerInner* consumer) { - std::lock_guard lock(m_consumerTableMutex); - if (m_consumerTable.find(consumerName) != m_consumerTable.end()) { + std::lock_guard lock(consumer_table_mutex_); + if (consumer_table_.find(consumerName) != consumer_table_.end()) { return false; } else { - m_consumerTable[consumerName] = consumer; + consumer_table_[consumerName] = consumer; return true; } } void MQClientInstance::eraseConsumerFromTable(const std::string& consumerName) { - std::lock_guard lock(m_consumerTableMutex); - const auto& it = m_consumerTable.find(consumerName); - if (it != m_consumerTable.end()) { - m_consumerTable.erase(it); // do not need free consumer, as it was allocated by user + std::lock_guard lock(consumer_table_mutex_); + const auto& it = consumer_table_.find(consumerName); + if (it != consumer_table_.end()) { + consumer_table_.erase(it); // do not need free consumer, as it was allocated by user } else { LOG_WARN_NEW("could not find consumer:{} from table", consumerName); } } int MQClientInstance::getConsumerTableSize() { - std::lock_guard lock(m_consumerTableMutex); - return m_consumerTable.size(); + std::lock_guard lock(consumer_table_mutex_); + return consumer_table_.size(); } void MQClientInstance::getTopicListFromConsumerSubscription(std::set& topicList) { - std::lock_guard lock(m_consumerTableMutex); - for (const auto& it : m_consumerTable) { + std::lock_guard lock(consumer_table_mutex_); + for (const auto& it : consumer_table_) { std::vector result = it.second->subscriptions(); for (const auto& sd : result) { - topicList.insert(sd.getTopic()); + topicList.insert(sd.topic()); } } } void MQClientInstance::updateConsumerTopicSubscribeInfo(const std::string& topic, std::vector subscribeInfo) { - std::lock_guard lock(m_consumerTableMutex); - for (auto& it : m_consumerTable) { + std::lock_guard lock(consumer_table_mutex_); + for (auto& it : consumer_table_) { it.second->updateTopicSubscribeInfo(topic, subscribeInfo); } } void MQClientInstance::addTopicInfoToTable(const std::string& topic, TopicPublishInfoPtr topicPublishInfo) { - std::lock_guard lock(m_topicPublishInfoTableMutex); - m_topicPublishInfoTable[topic] = topicPublishInfo; + std::lock_guard lock(topic_publish_info_table_mutex_); + topic_publish_info_table_[topic] = topicPublishInfo; } void MQClientInstance::eraseTopicInfoFromTable(const std::string& topic) { - std::lock_guard lock(m_topicPublishInfoTableMutex); - const auto& it = m_topicPublishInfoTable.find(topic); - if (it != m_topicPublishInfoTable.end()) { - m_topicPublishInfoTable.erase(it); + std::lock_guard lock(topic_publish_info_table_mutex_); + const auto& it = topic_publish_info_table_.find(topic); + if (it != topic_publish_info_table_.end()) { + topic_publish_info_table_.erase(it); } } TopicPublishInfoPtr MQClientInstance::getTopicPublishInfoFromTable(const std::string& topic) { - std::lock_guard lock(m_topicPublishInfoTableMutex); - const auto& it = m_topicPublishInfoTable.find(topic); - if (it != m_topicPublishInfoTable.end()) { + std::lock_guard lock(topic_publish_info_table_mutex_); + const auto& it = topic_publish_info_table_.find(topic); + if (it != topic_publish_info_table_.end()) { return it->second; } return nullptr; } bool MQClientInstance::isTopicInfoValidInTable(const std::string& topic) { - std::lock_guard lock(m_topicPublishInfoTableMutex); - return m_topicPublishInfoTable.find(topic) != m_topicPublishInfoTable.end(); + std::lock_guard lock(topic_publish_info_table_mutex_); + return topic_publish_info_table_.find(topic) != topic_publish_info_table_.end(); } TopicPublishInfoPtr MQClientInstance::tryToFindTopicPublishInfo(const std::string& topic) { @@ -870,9 +867,9 @@ void MQClientInstance::findConsumerIds(const std::string& topic, // find consumerIds from same broker every 40s { - std::lock_guard lock(m_topicBrokerAddrTableMutex); - const auto& it = m_topicBrokerAddrTable.find(topic); - if (it != m_topicBrokerAddrTable.end()) { + std::lock_guard lock(topic_broker_addr_table_mutex_); + const auto& it = topic_broker_addr_table_.find(topic); + if (it != topic_broker_addr_table_.end()) { if (UtilAll::currentTimeMillis() < it->second.second + 120000) { brokerAddr = it->second.first; } @@ -888,20 +885,20 @@ void MQClientInstance::findConsumerIds(const std::string& topic, } if (!brokerAddr.empty()) { - std::lock_guard lock(m_topicBrokerAddrTableMutex); - m_topicBrokerAddrTable[topic] = std::make_pair(brokerAddr, UtilAll::currentTimeMillis()); + std::lock_guard lock(topic_broker_addr_table_mutex_); + topic_broker_addr_table_[topic] = std::make_pair(brokerAddr, UtilAll::currentTimeMillis()); } } if (!brokerAddr.empty()) { try { LOG_INFO_NEW("getConsumerIdList from broker:{}", brokerAddr); - return m_mqClientAPIImpl->getConsumerIdListByGroup(brokerAddr, group, cids, 5000); + return mq_client_api_impl_->getConsumerIdListByGroup(brokerAddr, group, cids, 5000); } catch (const MQException& e) { LOG_ERROR_NEW("encounter exception when getConsumerIdList: {}", e.what()); - std::lock_guard lock(m_topicBrokerAddrTableMutex); - m_topicBrokerAddrTable.erase(topic); + std::lock_guard lock(topic_broker_addr_table_mutex_); + topic_broker_addr_table_.erase(topic); } } } @@ -931,9 +928,9 @@ void MQClientInstance::resetOffset(const std::string& group, auto processQueueTable = consumer->getRebalanceImpl()->getProcessQueueTable(); for (const auto& it : processQueueTable) { const auto& mq = it.first; - if (topic == mq.getTopic() && offsetTable.find(mq) != offsetTable.end()) { + if (topic == mq.topic() && offsetTable.find(mq) != offsetTable.end()) { auto pq = it.second; - pq->setDropped(true); + pq->set_dropped(true); pq->clearAllMsgs(); } } @@ -976,7 +973,7 @@ ConsumerRunningInfo* MQClientInstance::consumerRunningInfo(const std::string& co } runningInfo->setProperty(ConsumerRunningInfo::PROP_CLIENT_VERSION, - MQVersion::GetVersionDesc(MQVersion::s_CurrentVersion)); + MQVersion::GetVersionDesc(MQVersion::CURRENT_VERSION)); return runningInfo.release(); } @@ -988,23 +985,23 @@ ConsumerRunningInfo* MQClientInstance::consumerRunningInfo(const std::string& co void MQClientInstance::addBrokerToAddrTable(const std::string& brokerName, const std::map& brokerAddrs) { - std::lock_guard lock(m_brokerAddrTableMutex); - m_brokerAddrTable[brokerName] = brokerAddrs; + std::lock_guard lock(broker_addr_table_mutex_); + broker_addr_table_[brokerName] = brokerAddrs; } void MQClientInstance::resetBrokerAddrTable(BrokerAddrMAP&& table) { - std::lock_guard lock(m_brokerAddrTableMutex); - m_brokerAddrTable = std::forward(table); + std::lock_guard lock(broker_addr_table_mutex_); + broker_addr_table_ = std::forward(table); } void MQClientInstance::clearBrokerAddrTable() { - std::lock_guard lock(m_brokerAddrTableMutex); - m_brokerAddrTable.clear(); + std::lock_guard lock(broker_addr_table_mutex_); + broker_addr_table_.clear(); } MQClientInstance::BrokerAddrMAP MQClientInstance::getBrokerAddrTable() { - std::lock_guard lock(m_brokerAddrTableMutex); - return m_brokerAddrTable; + std::lock_guard lock(broker_addr_table_mutex_); + return broker_addr_table_; } } // namespace rocketmq diff --git a/src/MQClientInstance.h b/src/MQClientInstance.h index 77ee4b6aa..dc583efd4 100644 --- a/src/MQClientInstance.h +++ b/src/MQClientInstance.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_CLIENT_INSTANCE_H__ -#define __MQ_CLIENT_INSTANCE_H__ +#ifndef ROCKETMQ_MQCLIENTINSTANCE_H_ +#define ROCKETMQ_MQCLIENTINSTANCE_H_ #include #include @@ -23,16 +23,16 @@ #include #include "ConsumerRunningInfo.h" -#include "FindBrokerResult.h" +#include "FindBrokerResult.hpp" #include "HeartbeatData.h" #include "MQClientConfig.h" -#include "MQClientException.h" +#include "MQException.h" #include "MQConsumerInner.h" #include "MQMessageQueue.h" #include "MQProducerInner.h" #include "ServiceState.h" -#include "TopicPublishInfo.h" -#include "TopicRouteData.h" +#include "TopicPublishInfo.hpp" +#include "TopicRouteData.hpp" #include "concurrent/executor.hpp" namespace rocketmq { @@ -103,9 +103,9 @@ class MQClientInstance { TopicRouteDataPtr getTopicRouteData(const std::string& topic); public: - MQClientAPIImpl* getMQClientAPIImpl() const { return m_mqClientAPIImpl.get(); } - MQAdminImpl* getMQAdminImpl() const { return m_mqAdminImpl.get(); } - PullMessageService* getPullMessageService() const { return m_pullMessageService.get(); } + MQClientAPIImpl* getMQClientAPIImpl() const { return mq_client_api_impl_.get(); } + MQAdminImpl* getMQAdminImpl() const { return mq_admin_impl_.get(); } + PullMessageService* getPullMessageService() const { return pull_message_service_.get(); } private: typedef std::map> BrokerAddrMAP; @@ -164,50 +164,50 @@ class MQClientInstance { bool isTopicInfoValidInTable(const std::string& topic); private: - std::string m_clientId; - volatile ServiceState m_serviceState; + std::string client_id_; + volatile ServiceState service_state_; // group -> MQProducer typedef std::map MQPMAP; - MQPMAP m_producerTable; - std::mutex m_producerTableMutex; + MQPMAP producer_table_; + std::mutex producer_table_mutex_; // group -> MQConsumer typedef std::map MQCMAP; - MQCMAP m_consumerTable; - std::mutex m_consumerTableMutex; + MQCMAP consumer_table_; + std::mutex consumer_table_mutex_; // Topic -> TopicRouteData typedef std::map TRDMAP; - TRDMAP m_topicRouteTable; - std::mutex m_topicRouteTableMutex; + TRDMAP topic_route_table_; + std::mutex topic_route_table_mutex_; // brokerName -> [ brokerid : addr ] - BrokerAddrMAP m_brokerAddrTable; - std::mutex m_brokerAddrTableMutex; + BrokerAddrMAP broker_addr_table_; + std::mutex broker_addr_table_mutex_; // topic -> TopicPublishInfo typedef std::map TPMAP; - TPMAP m_topicPublishInfoTable; - std::mutex m_topicPublishInfoTableMutex; + TPMAP topic_publish_info_table_; + std::mutex topic_publish_info_table_mutex_; // topic -> typedef std::map> TBAMAP; - TBAMAP m_topicBrokerAddrTable; - std::mutex m_topicBrokerAddrTableMutex; + TBAMAP topic_broker_addr_table_; + std::mutex topic_broker_addr_table_mutex_; - std::timed_mutex m_lockNamesrv; - std::timed_mutex m_lockHeartbeat; + std::timed_mutex lock_namesrv_; + std::timed_mutex lock_heartbeat_; - std::unique_ptr m_mqClientAPIImpl; - std::unique_ptr m_mqAdminImpl; - std::unique_ptr m_clientRemotingProcessor; + std::unique_ptr mq_client_api_impl_; + std::unique_ptr mq_admin_impl_; + std::unique_ptr client_remoting_processor_; - std::unique_ptr m_rebalanceService; - std::unique_ptr m_pullMessageService; - scheduled_thread_pool_executor m_scheduledExecutorService; + std::unique_ptr rebalance_service_; + std::unique_ptr pull_message_service_; + scheduled_thread_pool_executor scheduled_executor_service_; }; } // namespace rocketmq -#endif // __MQ_CLIENT_INSTANCE_H__ +#endif // ROCKETMQ_MQCLIENTINSTANCE_H_ diff --git a/src/MQClientManager.cpp b/src/MQClientManager.cpp index a0b0fac3a..49fb19e04 100644 --- a/src/MQClientManager.cpp +++ b/src/MQClientManager.cpp @@ -35,24 +35,24 @@ MQClientInstancePtr MQClientManager::getOrCreateMQClientInstance(const MQClientC MQClientInstancePtr MQClientManager::getOrCreateMQClientInstance(const MQClientConfig& clientConfig, RPCHookPtr rpcHook) { std::string clientId = clientConfig.buildMQClientId(); - std::lock_guard lock(m_mutex); - const auto& it = m_instanceTable.find(clientId); - if (it != m_instanceTable.end()) { + std::lock_guard lock(mutex_); + const auto& it = instance_table_.find(clientId); + if (it != instance_table_.end()) { return it->second; } else { // Clone clientConfig in Java, but we don't now. auto instance = std::make_shared(clientConfig, clientId, rpcHook); - m_instanceTable[clientId] = instance; + instance_table_[clientId] = instance; LOG_INFO_NEW("Created new MQClientInstance for clientId:[{}]", clientId); return instance; } } void MQClientManager::removeMQClientInstance(const std::string& clientId) { - std::lock_guard lock(m_mutex); - const auto& it = m_instanceTable.find(clientId); - if (it != m_instanceTable.end()) { - m_instanceTable.erase(it); + std::lock_guard lock(mutex_); + const auto& it = instance_table_.find(clientId); + if (it != instance_table_.end()) { + instance_table_.erase(it); } } diff --git a/src/MQClientManager.h b/src/MQClientManager.h index 7ecec156f..4327b603e 100644 --- a/src/MQClientManager.h +++ b/src/MQClientManager.h @@ -14,12 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_CLIENT_MANAGER_H__ -#define __MQ_CLIENT_MANAGER_H__ +#ifndef ROCKETMQ_MQCLIENTMANAGER_H_ +#define ROCKETMQ_MQCLIENTMANAGER_H_ -#include -#include -#include +#include // std::map +#include // std::string #include "MQClientInstance.h" @@ -40,10 +39,10 @@ class MQClientManager { MQClientManager(); private: - std::map m_instanceTable; - std::mutex m_mutex; + std::map instance_table_; + std::mutex mutex_; }; } // namespace rocketmq -#endif // __MQ_CLIENT_MANAGER_H__ +#endif // ROCKETMQ_MQCLIENTMANAGER_H_ diff --git a/src/common/ClientErrorCode.h b/src/common/ClientErrorCode.h index d43e90ff0..dd60d799c 100644 --- a/src/common/ClientErrorCode.h +++ b/src/common/ClientErrorCode.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __CLIENT_ERROR_CODE_H__ -#define __CLIENT_ERROR_CODE_H__ +#ifndef ROCKETMQ_COMMON_CLIENTERRORCODE_H_ +#define ROCKETMQ_COMMON_CLIENTERRORCODE_H_ namespace rocketmq { @@ -32,4 +32,4 @@ class ClientErrorCode { } // namespace rocketmq -#endif // __CLIENT_ERROR_CODE_H__ +#endif // ROCKETMQ_COMMON_CLIENTERRORCODE_H_ diff --git a/src/common/ClientRPCHook.cpp b/src/common/ClientRPCHook.cpp index 6c348526f..5fcb47b7f 100644 --- a/src/common/ClientRPCHook.cpp +++ b/src/common/ClientRPCHook.cpp @@ -16,20 +16,18 @@ */ #include "ClientRPCHook.h" -#include - #include "Logging.h" #include "RemotingCommand.h" #include "protocol/header/CommandHeader.h" #include "spas_client.h" -namespace rocketmq { +static const std::string ACCESS_KEY = "AccessKey"; +static const std::string SECRET_KEY = "SecretKey"; +static const std::string SIGNATURE_KEY = "Signature"; +static const std::string SIGNATURE_METHOD = "SignatureMethod"; +static const std::string ONS_CHANNEL_KEY = "OnsChannel"; -const std::string SessionCredentials::AccessKey = "AccessKey"; -const std::string SessionCredentials::SecretKey = "SecretKey"; -const std::string SessionCredentials::Signature = "Signature"; -const std::string SessionCredentials::SignatureMethod = "SignatureMethod"; -const std::string SessionCredentials::ONSChannelKey = "OnsChannel"; +namespace rocketmq { void ClientRPCHook::doBeforeRequest(const std::string& remoteAddr, RemotingCommand& request, bool toSent) { if (toSent) { @@ -50,8 +48,8 @@ void ClientRPCHook::doAfterResponse(const std::string& remoteAddr, void ClientRPCHook::signCommand(RemotingCommand& command) { std::map headerMap; - headerMap.insert(std::make_pair(SessionCredentials::AccessKey, session_credentials_.getAccessKey())); - headerMap.insert(std::make_pair(SessionCredentials::ONSChannelKey, session_credentials_.getAuthChannel())); + headerMap.insert(std::make_pair(ACCESS_KEY, session_credentials_.getAccessKey())); + headerMap.insert(std::make_pair(ONS_CHANNEL_KEY, session_credentials_.getAuthChannel())); LOG_DEBUG_NEW("before insert declared filed, MAP SIZE is:{}", headerMap.size()); auto* header = command.readCustomHeader(); @@ -75,9 +73,9 @@ void ClientRPCHook::signCommand(RemotingCommand& command) { rocketmqSignature::spas_sign(totalMsg.c_str(), totalMsg.size(), session_credentials_.getSecretKey().c_str()); if (sign != nullptr) { std::string signature(static_cast(sign)); - command.set_ext_field(SessionCredentials::Signature, signature); - command.set_ext_field(SessionCredentials::AccessKey, session_credentials_.getAccessKey()); - command.set_ext_field(SessionCredentials::ONSChannelKey, session_credentials_.getAuthChannel()); + command.set_ext_field(SIGNATURE_KEY, signature); + command.set_ext_field(ACCESS_KEY, session_credentials_.getAccessKey()); + command.set_ext_field(ONS_CHANNEL_KEY, session_credentials_.getAuthChannel()); rocketmqSignature::spas_mem_free(sign); } else { LOG_ERROR_NEW("signature for request failed"); diff --git a/src/common/FilterAPI.h b/src/common/FilterAPI.hpp similarity index 74% rename from src/common/FilterAPI.h rename to src/common/FilterAPI.hpp index 3ca8b31a4..aa40eb5bc 100644 --- a/src/common/FilterAPI.h +++ b/src/common/FilterAPI.hpp @@ -14,12 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __FILTER_API_H__ -#define __FILTER_API_H__ +#ifndef ROCKETMQ_COMMON_FILTERAPI_HPP_ +#define ROCKETMQ_COMMON_FILTERAPI_HPP_ -#include +#include // std::string -#include "MQClientException.h" +#include "MQException.h" #include "SubscriptionData.h" #include "UtilAll.h" @@ -27,12 +27,12 @@ namespace rocketmq { class FilterAPI { public: - static SubscriptionDataPtr buildSubscriptionData(const std::string& topic, const std::string& subString) { + static SubscriptionData* buildSubscriptionData(const std::string& topic, const std::string& subString) { // delete in Rebalance std::unique_ptr subscriptionData(new SubscriptionData(topic, subString)); - if (subString.empty() || !subString.compare(SUB_ALL)) { - subscriptionData->setSubString(SUB_ALL); + if (subString.empty() || SUB_ALL == subString) { + subscriptionData->set_sub_string(SUB_ALL); } else { std::vector tags; UtilAll::Split(tags, subString, "||"); @@ -42,8 +42,8 @@ class FilterAPI { if (!tag.empty()) { UtilAll::Trim(tag); if (!tag.empty()) { - subscriptionData->putTagsSet(tag); - subscriptionData->putCodeSet(UtilAll::hash_code(tag)); + subscriptionData->put_tag(tag); + subscriptionData->put_code(UtilAll::hash_code(tag)); } } } @@ -58,4 +58,4 @@ class FilterAPI { } // namespace rocketmq -#endif // __FILTER_API_H__ +#endif // ROCKETMQ_COMMON_FILTERAPI_HPP_ diff --git a/src/common/InvokeCallback.h b/src/common/InvokeCallback.h index 676222710..a89580f5e 100644 --- a/src/common/InvokeCallback.h +++ b/src/common/InvokeCallback.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __INVOKE_CALLBACK_H__ -#define __INVOKE_CALLBACK_H__ +#ifndef ROCKETMQ_COMMON_INVOKECALLBACK_H_ +#define ROCKETMQ_COMMON_INVOKECALLBACK_H_ namespace rocketmq { @@ -24,9 +24,10 @@ class ResponseFuture; class InvokeCallback { public: virtual ~InvokeCallback() = default; + virtual void operationComplete(ResponseFuture* responseFuture) noexcept = 0; }; } // namespace rocketmq -#endif // __INVOKE_CALLBACK_H__ +#endif // ROCKETMQ_COMMON_INVOKECALLBACK_H_ diff --git a/src/common/MQVersion.cpp b/src/common/MQVersion.cpp index 1d8e481c3..a5f027f9a 100644 --- a/src/common/MQVersion.cpp +++ b/src/common/MQVersion.cpp @@ -18,8 +18,8 @@ namespace rocketmq { -const int MQVersion::s_CurrentVersion = MQVersion::V4_6_0; -const std::string MQVersion::s_CurrentLanguage = "CPP"; +const int MQVersion::CURRENT_VERSION = MQVersion::V4_6_0; +const std::string MQVersion::CURRENT_LANGUAGE = "CPP"; const char* MQVersion::GetVersionDesc(int value) { int currentVersion = value; diff --git a/src/common/MQVersion.h b/src/common/MQVersion.h index 2760dad64..ec39c28c4 100644 --- a/src/common/MQVersion.h +++ b/src/common/MQVersion.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_VERSION_H__ -#define __MQ_VERSION_H__ +#ifndef ROCKETMQ_COMMON_MQVERSION_H_ +#define ROCKETMQ_COMMON_MQVERSION_H_ #include @@ -968,12 +968,12 @@ class MQVersion { HIGHER_VERSION }; - static const int s_CurrentVersion; - static const std::string s_CurrentLanguage; + static const int CURRENT_VERSION; + static const std::string CURRENT_LANGUAGE; static const char* GetVersionDesc(int value); }; } // namespace rocketmq -#endif // __MQ_VERSION_H__ +#endif // ROCKETMQ_COMMON_MQVERSION_H_ diff --git a/src/common/MessageSysFlag.h b/src/common/MessageSysFlag.h index 6948e3792..07d6d3762 100644 --- a/src/common/MessageSysFlag.h +++ b/src/common/MessageSysFlag.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MESSAGE_SYS_FLAG_H__ -#define __MESSAGE_SYS_FLAG_H__ +#ifndef ROCKETMQ_COMMON_MESSAGESYSFLAG_H_ +#define ROCKETMQ_COMMON_MESSAGESYSFLAG_H_ namespace rocketmq { @@ -41,4 +41,4 @@ class MessageSysFlag { } // namespace rocketmq -#endif // __MESSAGE_SYS_FLAG_H__ +#endif // ROCKETMQ_COMMON_MESSAGESYSFLAG_H_ diff --git a/src/common/NameSpaceUtil.h b/src/common/NameSpaceUtil.h index 29dfbb64d..2e19c0a07 100644 --- a/src/common/NameSpaceUtil.h +++ b/src/common/NameSpaceUtil.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __NAMESPACE_UTIL_H__ -#define __NAMESPACE_UTIL_H__ +#ifndef ROCKETMQ_COMMON_NAMESPACEUTIL_H_ +#define ROCKETMQ_COMMON_NAMESPACEUTIL_H_ #include @@ -33,4 +33,4 @@ class NameSpaceUtil { } // namespace rocketmq -#endif // __NAMESPACE_UTIL_H__ +#endif // ROCKETMQ_COMMON_NAMESPACEUTIL_H_ diff --git a/src/common/PermName.h b/src/common/PermName.h index e5ea3c6d2..9df10df2c 100644 --- a/src/common/PermName.h +++ b/src/common/PermName.h @@ -14,10 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __PERM_NAME_H__ -#define __PERM_NAME_H__ +#ifndef ROCKETMQ_COMMON_PERMNAME_H_ +#define ROCKETMQ_COMMON_PERMNAME_H_ -#include +#include // std::string namespace rocketmq { @@ -28,6 +28,7 @@ class PermName { static int PERM_WRITE; static int PERM_INHERIT; + public: static bool isReadable(int perm); static bool isWriteable(int perm); static bool isInherited(int perm); @@ -36,4 +37,4 @@ class PermName { } // namespace rocketmq -#endif // __PERM_NAME_H__ +#endif // ROCKETMQ_COMMON_PERMNAME_H_ diff --git a/src/common/PullCallbackWrap.cpp b/src/common/PullCallbackWrap.cpp index 32c2a5846..65cf63c79 100755 --- a/src/common/PullCallbackWrap.cpp +++ b/src/common/PullCallbackWrap.cpp @@ -19,27 +19,27 @@ namespace rocketmq { PullCallbackWrap::PullCallbackWrap(PullCallback* pullCallback, MQClientAPIImpl* pClientAPI) - : m_pullCallback(pullCallback), m_pClientAPI(pClientAPI) {} + : pull_callback_(pullCallback), client_api_impl_(pClientAPI) {} void PullCallbackWrap::operationComplete(ResponseFuture* responseFuture) noexcept { std::unique_ptr response(responseFuture->getResponseCommand()); // avoid RemotingCommand leak - if (m_pullCallback == nullptr) { + if (pull_callback_ == nullptr) { LOG_ERROR("m_pullCallback is NULL, AsyncPull could not continue"); return; } if (response != nullptr) { try { - std::unique_ptr pullResult(m_pClientAPI->processPullResponse(response.get())); + std::unique_ptr pullResult(client_api_impl_->processPullResponse(response.get())); assert(pullResult != nullptr); - m_pullCallback->onSuccess(*pullResult); + pull_callback_->onSuccess(*pullResult); } catch (MQException& e) { - m_pullCallback->onException(e); + pull_callback_->onException(e); } } else { std::string err; - if (!responseFuture->isSendRequestOK()) { + if (!responseFuture->send_request_ok()) { err = "send request failed"; } else if (responseFuture->isTimeout()) { err = "wait response timeout"; @@ -47,12 +47,12 @@ void PullCallbackWrap::operationComplete(ResponseFuture* responseFuture) noexcep err = "unknown reason"; } MQException exception(err, -1, __FILE__, __LINE__); - m_pullCallback->onException(exception); + pull_callback_->onException(exception); } // auto delete callback - if (m_pullCallback->getPullCallbackType() == PULL_CALLBACK_TYPE_AUTO_DELETE) { - deleteAndZero(m_pullCallback); + if (pull_callback_->getPullCallbackType() == PULL_CALLBACK_TYPE_AUTO_DELETE) { + deleteAndZero(pull_callback_); } } diff --git a/src/common/PullCallbackWrap.h b/src/common/PullCallbackWrap.h index b4343d570..f676fe2c6 100755 --- a/src/common/PullCallbackWrap.h +++ b/src/common/PullCallbackWrap.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __PULL_CALLBACK_WRAP_H__ -#define __PULL_CALLBACK_WRAP_H__ +#ifndef ROCKET_COMMON_PULLCALLBACKWRAP_H_ +#define ROCKET_COMMON_PULLCALLBACKWRAP_H_ #include "InvokeCallback.h" #include "MQClientAPIImpl.h" @@ -31,10 +31,10 @@ class PullCallbackWrap : public InvokeCallback { void operationComplete(ResponseFuture* responseFuture) noexcept override; private: - PullCallback* m_pullCallback; - MQClientAPIImpl* m_pClientAPI; + PullCallback* pull_callback_; + MQClientAPIImpl* client_api_impl_; }; } // namespace rocketmq -#endif // __PULL_CALLBACK_WRAP_H__ +#endif // ROCKET_COMMON_PULLCALLBACKWRAP_H_ diff --git a/src/common/PullSysFlag.cpp b/src/common/PullSysFlag.cpp index da6287fbc..dc8194fd8 100644 --- a/src/common/PullSysFlag.cpp +++ b/src/common/PullSysFlag.cpp @@ -16,12 +16,12 @@ */ #include "PullSysFlag.h" -namespace rocketmq { +static const int FLAG_COMMIT_OFFSET = 0x1 << 0; +static const int FLAG_SUSPEND = 0x1 << 1; +static const int FLAG_SUBSCRIPTION = 0x1 << 2; +static const int FLAG_CLASS_FILTER = 0x1 << 3; -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; +namespace rocketmq { int PullSysFlag::buildSysFlag(bool commitOffset, bool suspend, bool subscription, bool classFilter) { int flag = 0; diff --git a/src/common/PullSysFlag.h b/src/common/PullSysFlag.h index 3e2cac25f..51f2944b5 100644 --- a/src/common/PullSysFlag.h +++ b/src/common/PullSysFlag.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __PULL_SYS_FLAG_H__ -#define __PULL_SYS_FLAG_H__ +#ifndef ROCKETMQ_COMMON_PULLSYSFLAG_H_ +#define ROCKETMQ_COMMON_PULLSYSFLAG_H_ namespace rocketmq { @@ -28,14 +28,8 @@ class PullSysFlag { 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 // __PULL_SYS_FLAG_H__ +#endif // ROCKETMQ_COMMON_PULLSYSFLAG_H_ diff --git a/src/common/SendCallbackWrap.cpp b/src/common/SendCallbackWrap.cpp index e8951b354..d7514c08f 100755 --- a/src/common/SendCallbackWrap.cpp +++ b/src/common/SendCallbackWrap.cpp @@ -26,8 +26,8 @@ #include "MQMessageQueue.h" #include "MQProtos.h" #include "PullAPIWrapper.h" -#include "PullResultExt.h" -#include "TopicPublishInfo.h" +#include "PullResultExt.hpp" +#include "TopicPublishInfo.hpp" #include "protocol/header/CommandHeader.h" namespace rocketmq { @@ -42,32 +42,32 @@ SendCallbackWrap::SendCallbackWrap(const std::string& addr, int retryTimesWhenSendFailed, int times, DefaultMQProducerImplPtr producer) - : m_addr(addr), - m_brokerName(brokerName), - m_msg(msg), - m_request(std::forward(request)), - m_sendCallback(sendCallback), - m_topicPublishInfo(topicPublishInfo), - m_instance(instance), - m_timesTotal(retryTimesWhenSendFailed), - m_times(times), - m_producer(producer) {} + : addr_(addr), + broker_name_(brokerName), + msg_(msg), + request_(std::forward(request)), + send_callback_(sendCallback), + topic_publish_info_(topicPublishInfo), + instance_(instance), + times_total_(retryTimesWhenSendFailed), + times_(times), + producer_(producer) {} void SendCallbackWrap::operationComplete(ResponseFuture* responseFuture) noexcept { - auto producer = m_producer.lock(); + auto producer = producer_.lock(); if (nullptr == producer) { MQException exception("DefaultMQProducer is released.", -1, __FILE__, __LINE__); - m_sendCallback->onException(exception); + send_callback_->onException(exception); // auto delete callback - if (m_sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { - deleteAndZero(m_sendCallback); + if (send_callback_->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { + deleteAndZero(send_callback_); } return; } std::unique_ptr response(responseFuture->getResponseCommand()); // avoid RemotingCommand leak - if (nullptr == m_sendCallback && response != nullptr) { + if (nullptr == send_callback_ && response != nullptr) { // TODO: executeSendMessageHookAfter // try { // std::unique_ptr sendResult(m_pClientAPI->processSendResponse(m_brokerName, m_msg, response.get())); @@ -78,19 +78,19 @@ void SendCallbackWrap::operationComplete(ResponseFuture* responseFuture) noexcep // } catch (...) { // } - producer->updateFaultItem(m_brokerName, UtilAll::currentTimeMillis() - responseFuture->getBeginTimestamp(), false); + producer->updateFaultItem(broker_name_, UtilAll::currentTimeMillis() - responseFuture->begin_timestamp(), false); return; } if (response != nullptr) { - int opaque = responseFuture->getOpaque(); + int opaque = responseFuture->opaque(); try { std::unique_ptr sendResult( - m_instance->getMQClientAPIImpl()->processSendResponse(m_brokerName, m_msg, response.get())); + instance_->getMQClientAPIImpl()->processSendResponse(broker_name_, msg_, response.get())); assert(sendResult != nullptr); LOG_DEBUG("operationComplete: processSendResponse success, opaque:%d, maxRetryTime:%d, retrySendTimes:%d", opaque, - m_timesTotal, m_times); + times_total_, times_); // TODO: executeSendMessageHookAfter // if (context != null) { @@ -99,26 +99,25 @@ void SendCallbackWrap::operationComplete(ResponseFuture* responseFuture) noexcep // } try { - m_sendCallback->onSuccess(*sendResult); + send_callback_->onSuccess(*sendResult); } catch (...) { } - producer->updateFaultItem(m_brokerName, UtilAll::currentTimeMillis() - responseFuture->getBeginTimestamp(), - false); + producer->updateFaultItem(broker_name_, UtilAll::currentTimeMillis() - responseFuture->begin_timestamp(), false); // auto delete callback - if (m_sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { - deleteAndZero(m_sendCallback); + if (send_callback_->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { + deleteAndZero(send_callback_); } } catch (MQException& e) { - producer->updateFaultItem(m_brokerName, UtilAll::currentTimeMillis() - responseFuture->getBeginTimestamp(), true); + producer->updateFaultItem(broker_name_, UtilAll::currentTimeMillis() - responseFuture->begin_timestamp(), true); LOG_ERROR("operationComplete: processSendResponse exception: %s", e.what()); return onExceptionImpl(responseFuture, responseFuture->leftTime(), e, false); } } else { - producer->updateFaultItem(m_brokerName, UtilAll::currentTimeMillis() - responseFuture->getBeginTimestamp(), true); + producer->updateFaultItem(broker_name_, UtilAll::currentTimeMillis() - responseFuture->begin_timestamp(), true); std::string err; - if (!responseFuture->isSendRequestOK()) { + if (!responseFuture->send_request_ok()) { err = "send request failed"; } else if (responseFuture->isTimeout()) { err = "wait response timeout"; @@ -134,58 +133,58 @@ void SendCallbackWrap::onExceptionImpl(ResponseFuture* responseFuture, long timeoutMillis, MQException& e, bool needRetry) { - auto producer = m_producer.lock(); + auto producer = producer_.lock(); if (nullptr == producer) { MQException exception("DefaultMQProducer is released.", -1, __FILE__, __LINE__); - m_sendCallback->onException(exception); + send_callback_->onException(exception); // auto delete callback - if (m_sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { - deleteAndZero(m_sendCallback); + if (send_callback_->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { + deleteAndZero(send_callback_); } return; } - m_times++; - if (needRetry && m_times <= m_timesTotal) { - std::string retryBrokerName = m_brokerName; // by default, it will send to the same broker - if (m_topicPublishInfo != nullptr) { + times_++; + if (needRetry && times_ <= times_total_) { + std::string retryBrokerName = broker_name_; // by default, it will send to the same broker + if (topic_publish_info_ != nullptr) { // select one message queue accordingly, in order to determine which broker to send - const auto& mqChosen = producer->selectOneMessageQueue(m_topicPublishInfo.get(), m_brokerName); - retryBrokerName = mqChosen.getBrokerName(); + const auto& mqChosen = producer->selectOneMessageQueue(topic_publish_info_.get(), broker_name_); + retryBrokerName = mqChosen.broker_name(); // set queueId to requestHeader - auto* requestHeader = m_request.readCustomHeader(); + auto* requestHeader = request_.readCustomHeader(); if (std::type_index(typeid(*requestHeader)) == std::type_index(typeid(SendMessageRequestHeaderV2))) { - static_cast(requestHeader)->e = mqChosen.getQueueId(); + static_cast(requestHeader)->e = mqChosen.queue_id(); } else { - static_cast(requestHeader)->queueId = mqChosen.getQueueId(); + static_cast(requestHeader)->queueId = mqChosen.queue_id(); } } - std::string addr = m_instance->findBrokerAddressInPublish(retryBrokerName); - LOG_INFO_NEW("async send msg by retry {} times. topic={}, brokerAddr={}, brokerName={}", m_times, m_msg->getTopic(), + std::string addr = instance_->findBrokerAddressInPublish(retryBrokerName); + LOG_INFO_NEW("async send msg by retry {} times. topic={}, brokerAddr={}, brokerName={}", times_, msg_->getTopic(), addr, retryBrokerName); try { // new request - m_request.set_opaque(RemotingCommand::createNewRequestId()); + request_.set_opaque(RemotingCommand::createNewRequestId()); // resend - m_addr = std::move(addr); - m_brokerName = std::move(retryBrokerName); - m_instance->getMQClientAPIImpl()->sendMessageAsyncImpl(this, timeoutMillis); + addr_ = std::move(addr); + broker_name_ = std::move(retryBrokerName); + instance_->getMQClientAPIImpl()->sendMessageAsyncImpl(this, timeoutMillis); responseFuture->releaseInvokeCallback(); // for avoid delete this SendCallbackWrap return; } catch (MQException& e1) { - producer->updateFaultItem(m_brokerName, 3000, true); + producer->updateFaultItem(broker_name_, 3000, true); return onExceptionImpl(responseFuture, responseFuture->leftTime(), e1, true); } } else { - m_sendCallback->onException(e); + send_callback_->onException(e); // auto delete callback - if (m_sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { - deleteAndZero(m_sendCallback); + if (send_callback_->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { + deleteAndZero(send_callback_); } } } diff --git a/src/common/SendCallbackWrap.h b/src/common/SendCallbackWrap.h index 2ef8ffa34..5bf9f6f4f 100755 --- a/src/common/SendCallbackWrap.h +++ b/src/common/SendCallbackWrap.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __SEND_CALLBACK_WRAP_H__ -#define __SEND_CALLBACK_WRAP_H__ +#ifndef ROCKETMQ_COMMON_SENDCALLBACKWRAP_H_ +#define ROCKETMQ_COMMON_SENDCALLBACKWRAP_H_ #include @@ -26,7 +26,7 @@ #include "RemotingCommand.h" #include "ResponseFuture.h" #include "SendCallback.h" -#include "TopicPublishInfo.h" +#include "TopicPublishInfo.hpp" namespace rocketmq { @@ -46,27 +46,27 @@ class SendCallbackWrap : public InvokeCallback { void operationComplete(ResponseFuture* responseFuture) noexcept override; void onExceptionImpl(ResponseFuture* responseFuture, long timeoutMillis, MQException& e, bool needRetry); - const std::string& getAddr() { return m_addr; } - const MessagePtr getMessage() { return m_msg; } - RemotingCommand& getRemotingCommand() { return m_request; } + const std::string& getAddr() { return addr_; } + const MessagePtr getMessage() { return msg_; } + RemotingCommand& getRemotingCommand() { return request_; } - void setRetrySendTimes(int retrySendTimes) { m_times = retrySendTimes; } - int getRetrySendTimes() { return m_times; } - int getMaxRetrySendTimes() { return m_timesTotal; } + void setRetrySendTimes(int retrySendTimes) { times_ = retrySendTimes; } + int getRetrySendTimes() { return times_; } + int getMaxRetrySendTimes() { return times_total_; } private: - std::string m_addr; - std::string m_brokerName; - const MessagePtr m_msg; - RemotingCommand m_request; - SendCallback* m_sendCallback; - TopicPublishInfoPtr m_topicPublishInfo; - MQClientInstancePtr m_instance; - int m_timesTotal; - int m_times; - std::weak_ptr m_producer; + std::string addr_; + std::string broker_name_; + const MessagePtr msg_; + RemotingCommand request_; + SendCallback* send_callback_; + TopicPublishInfoPtr topic_publish_info_; + MQClientInstancePtr instance_; + int times_total_; + int times_; + std::weak_ptr producer_; }; } // namespace rocketmq -#endif // __SEND_CALLBACK_WRAP_H__ +#endif // ROCKETMQ_COMMON_SENDCALLBACKWRAP_H_ diff --git a/src/common/ServiceState.h b/src/common/ServiceState.h index 726c15090..d2fd31af0 100644 --- a/src/common/ServiceState.h +++ b/src/common/ServiceState.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __SERVICE_STATE_H__ -#define __SERVICE_STATE_H__ +#ifndef ROCKETMQ_COMMON_SERVICESTATE_H_ +#define ROCKETMQ_COMMON_SERVICESTATE_H_ namespace rocketmq { @@ -23,4 +23,4 @@ enum ServiceState { CREATE_JUST, RUNNING, SHUTDOWN_ALREADY, START_FAILED }; } // namespace rocketmq -#endif // __SERVICE_STATE_H__ +#endif // ROCKETMQ_COMMON_SERVICESTATE_H_ diff --git a/src/common/ServiceThread.cpp b/src/common/ServiceThread.cpp index e77830751..059a29056 100644 --- a/src/common/ServiceThread.cpp +++ b/src/common/ServiceThread.cpp @@ -22,65 +22,65 @@ namespace rocketmq { void ServiceThread::start() { - LOG_INFO_NEW("Try to start service thread:{} started:{} lastThread:{}", getServiceName(), m_started.load(), - (void*)m_thread.get()); + LOG_INFO_NEW("Try to start service thread:{} started:{} lastThread:{}", getServiceName(), started_.load(), + (void*)thread_.get()); bool expected = false; - if (!m_started.compare_exchange_strong(expected, true)) { + if (!started_.compare_exchange_strong(expected, true)) { return; } - m_stopped = false; - m_thread.reset(new thread(getServiceName(), &ServiceThread::run, this)); - m_thread->start(); + stopped_ = false; + thread_.reset(new thread(getServiceName(), &ServiceThread::run, this)); + thread_->start(); } void ServiceThread::shutdown() { - LOG_INFO_NEW("Try to shutdown service thread:{} started:{} lastThread:{}", getServiceName(), m_started.load(), - (void*)m_thread.get()); + LOG_INFO_NEW("Try to shutdown service thread:{} started:{} lastThread:{}", getServiceName(), started_.load(), + (void*)thread_.get()); bool expected = true; - if (!m_started.compare_exchange_strong(expected, false)) { + if (!started_.compare_exchange_strong(expected, false)) { return; } - m_stopped = true; + stopped_ = true; LOG_INFO_NEW("shutdown thread {}", getServiceName()); wakeup(); int64_t beginTime = UtilAll::currentTimeMillis(); - m_thread->join(); + thread_->join(); int64_t elapsedTime = UtilAll::currentTimeMillis() - beginTime; LOG_INFO_NEW("join thread {} elapsed time(ms) {}", getServiceName(), elapsedTime); } void ServiceThread::wakeup() { bool expected = false; - if (m_hasNotified.compare_exchange_strong(expected, true)) { - m_waitPoint.count_down(); // notify + if (has_notified_.compare_exchange_strong(expected, true)) { + wait_point_.count_down(); // notify } } void ServiceThread::waitForRunning(long interval) { bool expected = true; - if (m_hasNotified.compare_exchange_strong(expected, false)) { + if (has_notified_.compare_exchange_strong(expected, false)) { onWaitEnd(); return; } // entry to wait - m_waitPoint.reset(); + wait_point_.reset(); try { - m_waitPoint.wait(interval, time_unit::milliseconds); + wait_point_.wait(interval, time_unit::milliseconds); } catch (const std::exception& e) { LOG_WARN_NEW("encounter unexpected exception: {}", e.what()); } - m_hasNotified.store(false); + has_notified_.store(false); onWaitEnd(); } void ServiceThread::onWaitEnd() {} bool ServiceThread::isStopped() { - return m_stopped; + return stopped_; }; } // namespace rocketmq diff --git a/src/common/ServiceThread.h b/src/common/ServiceThread.h index ff6548951..70591aca4 100644 --- a/src/common/ServiceThread.h +++ b/src/common/ServiceThread.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __SERVICE_THREAD_H__ -#define __SERVICE_THREAD_H__ +#ifndef ROCKETMQ_COMMON_SERVICETHREAD_H_ +#define ROCKETMQ_COMMON_SERVICETHREAD_H_ #include #include @@ -28,12 +28,7 @@ namespace rocketmq { class ServiceThread { public: ServiceThread() - : m_waitPoint(1), - m_hasNotified(false), - m_stopped(false), - m_isDaemon(false), - m_thread(nullptr), - m_started(false) {} + : wait_point_(1), has_notified_(false), stopped_(false), is_daemon_(false), thread_(nullptr), started_(false) {} virtual ~ServiceThread() = default; virtual std::string getServiceName() = 0; @@ -51,16 +46,16 @@ class ServiceThread { virtual void onWaitEnd(); protected: - latch m_waitPoint; - std::atomic m_hasNotified; - volatile bool m_stopped; - bool m_isDaemon; + latch wait_point_; + std::atomic has_notified_; + volatile bool stopped_; + bool is_daemon_; private: - std::unique_ptr m_thread; - std::atomic m_started; + std::unique_ptr thread_; + std::atomic started_; }; } // namespace rocketmq -#endif // __PULL_MESSAGE_SERVICE_H__ +#endif // ROCKETMQ_COMMON_SERVICETHREAD_H_ diff --git a/src/common/SubscriptionData.h b/src/common/SubscriptionData.h index 9db58d905..277403c02 100644 --- a/src/common/SubscriptionData.h +++ b/src/common/SubscriptionData.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __SUBSCRIPTION_DATA_H__ -#define __SUBSCRIPTION_DATA_H__ +#ifndef ROCKETMQ_SUBSCRIPTIONDATA_H_ +#define ROCKETMQ_SUBSCRIPTIONDATA_H_ #include @@ -26,48 +26,47 @@ namespace rocketmq { -class SubscriptionData; -typedef SubscriptionData* SubscriptionDataPtr; - class ROCKETMQCLIENT_API SubscriptionData { public: SubscriptionData(); SubscriptionData(const std::string& topic, const std::string& subString); SubscriptionData(const SubscriptionData& other); - virtual ~SubscriptionData() { - m_tagSet.clear(); - m_codeSet.clear(); - } + virtual ~SubscriptionData() = default; + + bool operator==(const SubscriptionData& other) const; + bool operator!=(const SubscriptionData& other) const { return !operator==(other); } + + bool operator<(const SubscriptionData& other) const; - const std::string& getTopic() const; + Json::Value toJson() const; - const std::string& getSubString() const; - void setSubString(const std::string& sub); + public: + inline const std::string& topic() const { return topic_; } - int64_t getSubVersion() const; + inline const std::string& sub_string() const { return sub_string_; } + inline void set_sub_string(const std::string& sub) { sub_string_ = sub; } - void putTagsSet(const std::string& tag); - bool containTag(const std::string& tag); - std::vector& getTagsSet(); + inline int64_t sub_version() const { return sub_version_; } - void putCodeSet(int32_t code); + inline std::vector& tags_set() { return tag_set_; } - bool operator==(const SubscriptionData& other) const; - bool operator!=(const SubscriptionData& other) const { return !operator==(other); } + inline void put_tag(const std::string& tag) { tag_set_.push_back(tag); } - bool operator<(const SubscriptionData& other) const; + inline bool contain_tag(const std::string& tag) const { + return std::find(tag_set_.begin(), tag_set_.end(), tag) != tag_set_.end(); + } - Json::Value toJson() const; + inline void put_code(int32_t code) { code_set_.push_back(code); } private: - std::string m_topic; - std::string m_subString; - int64_t m_subVersion; - std::vector m_tagSet; - std::vector m_codeSet; + std::string topic_; + std::string sub_string_; + int64_t sub_version_; + std::vector tag_set_; + std::vector code_set_; }; } // namespace rocketmq -#endif // __SUBSCRIPTION_DATA_H__ +#endif // ROCKETMQ_SUBSCRIPTIONDATA_H_ diff --git a/src/common/SubscriptionGroupConfig.h b/src/common/SubscriptionGroupConfig.h index eec7ef2d5..2e390183b 100644 --- a/src/common/SubscriptionGroupConfig.h +++ b/src/common/SubscriptionGroupConfig.h @@ -14,10 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __SUBSCRIPTION_GROUP_CONFIG_H__ -#define __SUBSCRIPTION_GROUP_CONFIG_H__ +#ifndef ROCKETMQ_COMMON_SUBSCRIPTIONGROUPCONFIG_H_ +#define ROCKETMQ_COMMON_SUBSCRIPTIONGROUPCONFIG_H_ -#include +#include "UtilAll.h" namespace rocketmq { @@ -47,4 +47,4 @@ class SubscriptionGroupConfig { } // namespace rocketmq -#endif // __SUBSCRIPTION_GROUP_CONFIG_H__ +#endif // ROCKETMQ_COMMON_SUBSCRIPTIONGROUPCONFIG_H_ diff --git a/src/common/TopicConfig.cpp b/src/common/TopicConfig.cpp index 3a7a19655..a32edab1b 100644 --- a/src/common/TopicConfig.cpp +++ b/src/common/TopicConfig.cpp @@ -20,40 +20,41 @@ #include "PermName.h" +static const std::string SEPARATOR = " "; + namespace rocketmq { -int TopicConfig::DefaultReadQueueNums = 16; -int TopicConfig::DefaultWriteQueueNums = 16; -std::string TopicConfig::SEPARATOR = " "; +const int TopicConfig::DEFAULT_READ_QUEUE_NUMS = 16; +const int TopicConfig::DEFAULT_WRITE_QUEUE_NUMS = 16; TopicConfig::TopicConfig() - : m_topicName(""), - m_readQueueNums(DefaultReadQueueNums), - m_writeQueueNums(DefaultWriteQueueNums), - m_perm(PermName::PERM_READ | PermName::PERM_WRITE), - m_topicFilterType(SINGLE_TAG) {} + : topic_name_(null), + read_queue_nums_(DEFAULT_READ_QUEUE_NUMS), + write_queue_nums_(DEFAULT_WRITE_QUEUE_NUMS), + perm_(PermName::PERM_READ | PermName::PERM_WRITE), + topic_filter_type_(SINGLE_TAG) {} TopicConfig::TopicConfig(const std::string& topicName) - : m_topicName(topicName), - m_readQueueNums(DefaultReadQueueNums), - m_writeQueueNums(DefaultWriteQueueNums), - m_perm(PermName::PERM_READ | PermName::PERM_WRITE), - m_topicFilterType(SINGLE_TAG) {} + : topic_name_(topicName), + read_queue_nums_(DEFAULT_READ_QUEUE_NUMS), + write_queue_nums_(DEFAULT_WRITE_QUEUE_NUMS), + perm_(PermName::PERM_READ | PermName::PERM_WRITE), + topic_filter_type_(SINGLE_TAG) {} TopicConfig::TopicConfig(const std::string& topicName, int readQueueNums, int writeQueueNums, int perm) - : m_topicName(topicName), - m_readQueueNums(readQueueNums), - m_writeQueueNums(writeQueueNums), - m_perm(perm), - m_topicFilterType(SINGLE_TAG) {} + : topic_name_(topicName), + read_queue_nums_(readQueueNums), + write_queue_nums_(writeQueueNums), + perm_(perm), + topic_filter_type_(SINGLE_TAG) {} TopicConfig::~TopicConfig() {} -std::string TopicConfig::encode() { +std::string TopicConfig::encode() const { std::stringstream ss; - ss << m_topicName << SEPARATOR << m_readQueueNums << SEPARATOR << m_writeQueueNums << SEPARATOR << m_perm << SEPARATOR - << m_topicFilterType; + ss << topic_name_ << SEPARATOR << read_queue_nums_ << SEPARATOR << write_queue_nums_ << SEPARATOR << perm_ + << SEPARATOR << topic_filter_type_; return ss.str(); } @@ -61,56 +62,16 @@ std::string TopicConfig::encode() { bool TopicConfig::decode(const std::string& in) { std::stringstream ss(in); - ss >> m_topicName; - ss >> m_readQueueNums; - ss >> m_writeQueueNums; - ss >> m_perm; + ss >> topic_name_; + ss >> read_queue_nums_; + ss >> write_queue_nums_; + ss >> perm_; int type; ss >> type; - m_topicFilterType = (TopicFilterType)type; + topic_filter_type_ = (TopicFilterType)type; return true; } -const std::string& TopicConfig::getTopicName() { - return m_topicName; -} - -void TopicConfig::setTopicName(const std::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 diff --git a/src/common/TopicConfig.h b/src/common/TopicConfig.h index fa796efe5..9fba938a6 100644 --- a/src/common/TopicConfig.h +++ b/src/common/TopicConfig.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __TOPIC_CONFIG_H__ -#define __TOPIC_CONFIG_H__ +#ifndef ROCKETMQ_COMMON_TOPICCONFIG_H_ +#define ROCKETMQ_COMMON_TOPICCONFIG_H_ #include @@ -25,39 +25,43 @@ namespace rocketmq { class TopicConfig { + public: + static const int DEFAULT_READ_QUEUE_NUMS; + static const int DEFAULT_WRITE_QUEUE_NUMS; + public: TopicConfig(); TopicConfig(const std::string& topicName); TopicConfig(const std::string& topicName, int readQueueNums, int writeQueueNums, int perm); ~TopicConfig(); - std::string encode(); + std::string encode() const; bool decode(const std::string& in); - const std::string& getTopicName(); - void setTopicName(const std::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; + inline const std::string& topic_name() const { return topic_name_; } + inline void set_topic_name(const std::string& topicName) { topic_name_ = topicName; } - private: - static std::string SEPARATOR; + inline int read_queue_nums() const { return read_queue_nums_; } + inline void set_read_queue_nums(int readQueueNums) { read_queue_nums_ = readQueueNums; } + + inline int write_queue_nums() const { return write_queue_nums_; } + inline void set_write_queue_nums(int writeQueueNums) { write_queue_nums_ = writeQueueNums; } - std::string m_topicName; - int m_readQueueNums; - int m_writeQueueNums; - int m_perm; - TopicFilterType m_topicFilterType; + inline int perm() const { return perm_; } + inline void set_perm(int perm) { perm_ = perm; } + + inline TopicFilterType topic_filter_type() const { return topic_filter_type_; } + inline void set_topic_filter_type(TopicFilterType topicFilterType) { topic_filter_type_ = topicFilterType; } + + private: + std::string topic_name_; + int read_queue_nums_; + int write_queue_nums_; + int perm_; + TopicFilterType topic_filter_type_; }; } // namespace rocketmq -#endif // __TOPIC_CONFIG_H__ +#endif // ROCKETMQ_COMMON_TOPICCONFIG_H_ diff --git a/src/common/UtilAll.cpp b/src/common/UtilAll.cpp index 162a45e25..f326d959b 100644 --- a/src/common/UtilAll.cpp +++ b/src/common/UtilAll.cpp @@ -154,7 +154,7 @@ bool UtilAll::SplitURL(const std::string& serverURL, std::string& addr, short& n } addr = serverURL.substr(0, pos); - if (0 == addr.compare("localhost")) { + if ("localhost" == addr) { addr = "127.0.0.1"; } diff --git a/src/common/Validators.cpp b/src/common/Validators.cpp index 9525a4144..22084eecd 100644 --- a/src/common/Validators.cpp +++ b/src/common/Validators.cpp @@ -19,12 +19,11 @@ #include #include "MQProtos.h" -#include "UtilAll.h" -namespace rocketmq { +const std::string VALID_PATTERN_STR = "^[a-zA-Z0-9_-]+$"; +const int CHARACTER_MAX_LENGTH = 255; -const std::string Validators::validPatternStr = "^[a-zA-Z0-9_-]+$"; -const int Validators::CHARACTER_MAX_LENGTH = 255; +namespace rocketmq { bool Validators::regularExpressionMatcher(const std::string& origin, const std::string& patternStr) { if (UtilAll::isBlank(origin)) { @@ -75,8 +74,9 @@ void Validators::checkTopic(const std::string& topic) { THROW_MQEXCEPTION(MQClientException, "the topic[" + topic + "] is conflict with default topic.", -1); } - if (!regularExpressionMatcher(topic, validPatternStr)) { - std::string str = "the specified topic[" + topic + "] contains illegal characters, allowing only" + validPatternStr; + if (!regularExpressionMatcher(topic, VALID_PATTERN_STR)) { + std::string str = + "the specified topic[" + topic + "] contains illegal characters, allowing only" + VALID_PATTERN_STR; THROW_MQEXCEPTION(MQClientException, str, -1); } } @@ -86,8 +86,9 @@ void Validators::checkGroup(const std::string& group) { THROW_MQEXCEPTION(MQClientException, "the specified group is blank", -1); } - if (!regularExpressionMatcher(group, validPatternStr)) { - std::string str = "the specified group[" + group + "] contains illegal characters, allowing only" + validPatternStr; + if (!regularExpressionMatcher(group, VALID_PATTERN_STR)) { + std::string str = + "the specified group[" + group + "] contains illegal characters, allowing only" + VALID_PATTERN_STR; THROW_MQEXCEPTION(MQClientException, str, -1); } if ((int)group.length() > CHARACTER_MAX_LENGTH) { diff --git a/src/common/Validators.h b/src/common/Validators.h index 3ffe52773..f00df1d9b 100644 --- a/src/common/Validators.h +++ b/src/common/Validators.h @@ -14,13 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __VALIDATORST_H__ -#define __VALIDATORST_H__ +#ifndef ROCKETMQ_COMMON_VALIDATORST_H_ +#define ROCKETMQ_COMMON_VALIDATORST_H_ -#include - -#include "MQClientException.h" #include "Message.h" +#include "MQException.h" #include "UtilAll.h" namespace rocketmq { @@ -32,12 +30,8 @@ class Validators { static void checkTopic(const std::string& topic); static void checkGroup(const std::string& group); static void checkMessage(const Message& msg, int maxMessageSize); - - public: - static const std::string validPatternStr; - static const int CHARACTER_MAX_LENGTH; }; } // namespace rocketmq -#endif // __VALIDATORST_H__ +#endif // ROCKETMQ_COMMON_VALIDATORST_H_ diff --git a/src/common/VirtualEnvUtil.cpp b/src/common/VirtualEnvUtil.cpp index 8dab46ed6..14a0b5c7f 100644 --- a/src/common/VirtualEnvUtil.cpp +++ b/src/common/VirtualEnvUtil.cpp @@ -21,9 +21,9 @@ #include "UtilAll.h" -namespace rocketmq { +static const char* VIRTUAL_APPGROUP_PREFIX = "%%PROJECT_%s%%"; -const char* VirtualEnvUtil::VIRTUAL_APPGROUP_PREFIX = "%%PROJECT_%s%%"; +namespace rocketmq { std::string VirtualEnvUtil::buildWithProjectGroup(const std::string& origin, const std::string& projectGroup) { if (!UtilAll::isBlank(projectGroup)) { diff --git a/src/common/VirtualEnvUtil.h b/src/common/VirtualEnvUtil.h index 2c96f9d43..7dfafe684 100644 --- a/src/common/VirtualEnvUtil.h +++ b/src/common/VirtualEnvUtil.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __VIRTUAL_ENV_UTIL_H__ -#define __VIRTUAL_ENV_UTIL_H__ +#ifndef RROCKETMQ_COMMON_VIRTUALENVUTIL_H_ +#define RROCKETMQ_COMMON_VIRTUALENVUTIL_H_ #include @@ -25,11 +25,8 @@ 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 // __VIRTUAL_ENV_UTIL_H__ +#endif // RROCKETMQ_COMMON_VIRTUALENVUTIL_H_ diff --git a/src/common/noncopyable.h b/src/common/noncopyable.h index 50f1b5d57..792c7ac11 100644 --- a/src/common/noncopyable.h +++ b/src/common/noncopyable.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __NONCOPYABLE_H__ -#define __NONCOPYABLE_H__ +#ifndef ROCKETMQ_COMMON_NONCOPYABLE_H_ +#define ROCKETMQ_COMMON_NONCOPYABLE_H_ namespace rocketmq { @@ -30,4 +30,4 @@ class noncopyable { } // namespace rocketmq -#endif // __NONCOPYABLE_H__ +#endif // ROCKETMQ_COMMON_NONCOPYABLE_H_ diff --git a/src/concurrent/concurrent_queue.hpp b/src/concurrent/concurrent_queue.hpp index 20ae5f5d7..d826f3053 100644 --- a/src/concurrent/concurrent_queue.hpp +++ b/src/concurrent/concurrent_queue.hpp @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __CONCURRENT_QUEUE_HPP__ -#define __CONCURRENT_QUEUE_HPP__ +#ifndef ROCKETMQ_CONCURRENT_CONCURRENTQUEUE_HPP_ +#define ROCKETMQ_CONCURRENT_CONCURRENTQUEUE_HPP_ #include #include @@ -152,4 +152,4 @@ class concurrent_queue { } // namespace rocketmq -#endif // __CONCURRENT_QUEUE_HPP__ +#endif // ROCKETMQ_CONCURRENT_CONCURRENTQUEUE_HPP_ diff --git a/src/concurrent/executor.hpp b/src/concurrent/executor.hpp index 7f530d97b..84a7c4c35 100644 --- a/src/concurrent/executor.hpp +++ b/src/concurrent/executor.hpp @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __EXECUTOR_HPP__ -#define __EXECUTOR_HPP__ +#ifndef ROCKETMQ_CONCURRENT_EXECUTOR_HPP_ +#define ROCKETMQ_CONCURRENT_EXECUTOR_HPP_ #include #include @@ -83,4 +83,4 @@ class scheduled_executor_service : virtual public executor_service { #include "executor_impl.hpp" -#endif // __EXECUTOR_HPP__ +#endif // ROCKETMQ_CONCURRENT_EXECUTOR_HPP_ diff --git a/src/concurrent/executor_impl.hpp b/src/concurrent/executor_impl.hpp index 10acdd569..89b90dd7f 100644 --- a/src/concurrent/executor_impl.hpp +++ b/src/concurrent/executor_impl.hpp @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __EXECUTOR_IMPL_HPP__ -#define __EXECUTOR_IMPL_HPP__ +#ifndef ROCKETMQ_CONCURRENT_EXECUTORIMPL_HPP_ +#define ROCKETMQ_CONCURRENT_EXECUTORIMPL_HPP_ #include #include @@ -40,14 +40,14 @@ class abstract_executor_service : virtual public executor_service { class thread_pool_executor : public abstract_executor_service { public: - explicit thread_pool_executor(std::size_t num_threads, bool start_immediately = true) - : task_queue_(), state_(STOP), num_threads_(num_threads), free_threads_(0) { + explicit thread_pool_executor(std::size_t thread_nums, bool start_immediately = true) + : task_queue_(), state_(STOP), thread_nums_(thread_nums), free_threads_(0) { if (start_immediately) { startup(); } } - explicit thread_pool_executor(const std::string& name, std::size_t num_threads, bool start_immediately = true) - : task_queue_(), state_(STOP), num_threads_(num_threads), thread_group_(name), free_threads_(0) { + explicit thread_pool_executor(const std::string& name, std::size_t thread_nums, bool start_immediately = true) + : task_queue_(), state_(STOP), thread_nums_(thread_nums), thread_group_(name), free_threads_(0) { if (start_immediately) { startup(); } @@ -56,7 +56,7 @@ class thread_pool_executor : public abstract_executor_service { virtual void startup() { if (state_ == STOP) { state_ = RUNNING; - thread_group_.create_threads(std::bind(&thread_pool_executor::run, this), num_threads_); + thread_group_.create_threads(std::bind(&thread_pool_executor::run, this), thread_nums_); thread_group_.start(); } } @@ -72,7 +72,7 @@ class thread_pool_executor : public abstract_executor_service { bool is_shutdown() override { return state_ != RUNNING; } - std::size_t num_threads() { return num_threads_; } + std::size_t thread_nums() { return thread_nums_; } protected: static const unsigned int ACCEPT_NEW_TASKS = 1U << 0U; @@ -119,7 +119,7 @@ class thread_pool_executor : public abstract_executor_service { private: state state_; - std::size_t num_threads_; + std::size_t thread_nums_; thread_group thread_group_; std::mutex wakeup_mutex_; @@ -145,8 +145,8 @@ struct scheduled_executor_handler : public executor_handler { class scheduled_thread_pool_executor : public thread_pool_executor, virtual public scheduled_executor_service { public: - explicit scheduled_thread_pool_executor(std::size_t num_threads, bool start_immediately = true) - : thread_pool_executor(num_threads, false), + explicit scheduled_thread_pool_executor(std::size_t thread_nums, bool start_immediately = true) + : thread_pool_executor(thread_nums, false), time_queue_(&scheduled_executor_handler::less), stopped_(true), single_thread_(false), @@ -157,9 +157,9 @@ class scheduled_thread_pool_executor : public thread_pool_executor, virtual publ } } explicit scheduled_thread_pool_executor(const std::string& name, - std::size_t num_threads, + std::size_t thread_nums, bool start_immediately = true) - : thread_pool_executor(name, num_threads, false), + : thread_pool_executor(name, thread_nums, false), time_queue_(&scheduled_executor_handler::less), stopped_(true), single_thread_(false), @@ -305,4 +305,4 @@ class scheduled_thread_pool_executor : public thread_pool_executor, virtual publ } // namespace rocketmq -#endif // __EXECUTOR_IMPL_HPP__ +#endif // ROCKETMQ_CONCURRENT_EXECUTORIMPL_HPP_ diff --git a/src/concurrent/latch.hpp b/src/concurrent/latch.hpp index 088dc326a..b583f8ff1 100644 --- a/src/concurrent/latch.hpp +++ b/src/concurrent/latch.hpp @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __LATCH_HPP__ -#define __LATCH_HPP__ +#ifndef ROCKETMQ_CONCURRENT_LATCH_HPP_ +#define ROCKETMQ_CONCURRENT_LATCH_HPP_ #include #include @@ -143,4 +143,4 @@ class latch { } // namespace rocketmq -#endif // __LATCH_HPP__ +#endif // ROCKETMQ_CONCURRENT_LATCH_HPP_ diff --git a/src/concurrent/thread.hpp b/src/concurrent/thread.hpp index 67d3d8e0c..6a2048aab 100644 --- a/src/concurrent/thread.hpp +++ b/src/concurrent/thread.hpp @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __THREAD_HPP__ -#define __THREAD_HPP__ +#ifndef ROCKETMQ_CONCURRENT_THREAD_HPP_ +#define ROCKETMQ_CONCURRENT_THREAD_HPP_ #include #include @@ -165,4 +165,4 @@ class thread { } // namespace rocketmq -#endif // __THREAD_HPP__ +#endif // ROCKETMQ_CONCURRENT_THREAD_HPP_ diff --git a/src/concurrent/thread_group.hpp b/src/concurrent/thread_group.hpp index 59bcd9a3f..11548d629 100644 --- a/src/concurrent/thread_group.hpp +++ b/src/concurrent/thread_group.hpp @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __THREAD_GROUP_HPP__ -#define __THREAD_GROUP_HPP__ +#ifndef ROCKETMQ_CONCURRENT_THREADGROUP_HPP_ +#define ROCKETMQ_CONCURRENT_THREADGROUP_HPP_ #include "thread.hpp" @@ -28,8 +28,8 @@ class thread_group { thread_group(const std::string& name) : name_(name), first_(nullptr) {} template - thread_group(const std::string& name, Function f, std::size_t num_threads) : name_(name), first_(nullptr) { - create_threads(f, num_threads); + thread_group(const std::string& name, Function f, std::size_t thread_nums) : name_(name), first_(nullptr) { + create_threads(f, thread_nums); } // Destructor joins any remaining threads in the group. @@ -43,8 +43,8 @@ class thread_group { // Create new threads in the group. template - void create_threads(Function f, std::size_t num_threads) { - for (std::size_t i = 0; i < num_threads; ++i) { + void create_threads(Function f, std::size_t thread_nums) { + for (std::size_t i = 0; i < thread_nums; ++i) { create_thread(f); } } @@ -90,4 +90,4 @@ class thread_group { } // namespace rocketmq -#endif // __THREAD_GROUP_HPP__ +#endif // ROCKETMQ_CONCURRENT_THREADGROUP_HPP_ diff --git a/src/concurrent/time.hpp b/src/concurrent/time.hpp index ccb3c0abe..fef4f4ecc 100644 --- a/src/concurrent/time.hpp +++ b/src/concurrent/time.hpp @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __TIME_HPP__ -#define __TIME_HPP__ +#ifndef ROCKETMQ_CONCURRENT_TIME_HPP_ +#define ROCKETMQ_CONCURRENT_TIME_HPP_ #include #include @@ -48,4 +48,4 @@ inline std::chrono::steady_clock::time_point until_time_point(long delay, time_u } // namespace rocketmq -#endif // __TIME_HPP__ +#endif // ROCKETMQ_CONCURRENT_TIME_HPP_ diff --git a/src/consumer/AllocateMQAveragely.h b/src/consumer/AllocateMQAveragely.hpp similarity index 93% rename from src/consumer/AllocateMQAveragely.h rename to src/consumer/AllocateMQAveragely.hpp index d0acc2027..15a3d2cf1 100644 --- a/src/consumer/AllocateMQAveragely.h +++ b/src/consumer/AllocateMQAveragely.hpp @@ -14,14 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __ALLOCATE_MQ_AVERAGELY_H__ -#define __ALLOCATE_MQ_AVERAGELY_H__ +#ifndef ROCKETMQ_CONSUMER_ALLOCATEMQAVERAGELY_HPP_ +#define ROCKETMQ_CONSUMER_ALLOCATEMQAVERAGELY_HPP_ #include #include "AllocateMQStrategy.h" #include "Logging.h" -#include "MQClientException.h" +#include "MQException.h" namespace rocketmq { @@ -80,4 +80,4 @@ class AllocateMQAveragely : public AllocateMQStrategy { } // namespace rocketmq -#endif // __ALLOCATE_MQ_AVERAGELY_H__ +#endif // ROCKETMQ_CONSUMER_ALLOCATEMQAVERAGELY_HPP_ diff --git a/src/consumer/ConsumeMessageConcurrentlyService.cpp b/src/consumer/ConsumeMessageConcurrentlyService.cpp index 42cde1263..5c3c2f9d9 100755 --- a/src/consumer/ConsumeMessageConcurrentlyService.cpp +++ b/src/consumer/ConsumeMessageConcurrentlyService.cpp @@ -15,8 +15,9 @@ * limitations under the License. */ #include "ConsumeMsgService.h" + #include "Logging.h" -#include "MessageAccessor.h" +#include "MessageAccessor.hpp" #include "OffsetStore.h" #include "UtilAll.h" @@ -25,36 +26,36 @@ namespace rocketmq { ConsumeMessageConcurrentlyService::ConsumeMessageConcurrentlyService(DefaultMQPushConsumerImpl* consumer, int threadCount, MQMessageListener* msgListener) - : m_consumer(consumer), - m_messageListener(msgListener), - m_consumeExecutor("ConsumeMessageThread", threadCount, false), - m_scheduledExecutorService("ConsumeMessageScheduledThread", false) {} + : consumer_(consumer), + message_listener_(msgListener), + consume_executor_("ConsumeMessageThread", threadCount, false), + scheduled_executor_service_("ConsumeMessageScheduledThread", false) {} ConsumeMessageConcurrentlyService::~ConsumeMessageConcurrentlyService() = default; void ConsumeMessageConcurrentlyService::start() { // start callback threadpool - m_consumeExecutor.startup(); - m_scheduledExecutorService.startup(); + consume_executor_.startup(); + scheduled_executor_service_.startup(); } void ConsumeMessageConcurrentlyService::shutdown() { - m_scheduledExecutorService.shutdown(); - m_consumeExecutor.shutdown(); + scheduled_executor_service_.shutdown(); + consume_executor_.shutdown(); } void ConsumeMessageConcurrentlyService::submitConsumeRequest(std::vector& msgs, ProcessQueuePtr processQueue, const MQMessageQueue& messageQueue, const bool dispathToConsume) { - m_consumeExecutor.submit( + consume_executor_.submit( std::bind(&ConsumeMessageConcurrentlyService::ConsumeRequest, this, msgs, processQueue, messageQueue)); } void ConsumeMessageConcurrentlyService::submitConsumeRequestLater(std::vector& msgs, ProcessQueuePtr processQueue, const MQMessageQueue& messageQueue) { - m_scheduledExecutorService.schedule( + scheduled_executor_service_.schedule( std::bind(&ConsumeMessageConcurrentlyService::submitConsumeRequest, this, msgs, processQueue, messageQueue, true), 5000L, time_unit::milliseconds); } @@ -62,9 +63,9 @@ void ConsumeMessageConcurrentlyService::submitConsumeRequestLater(std::vector& msgs, ProcessQueuePtr processQueue, const MQMessageQueue& messageQueue) { - if (processQueue->isDropped()) { + if (processQueue->dropped()) { LOG_WARN_NEW("the message queue not be able to consume, because it's dropped. group={} {}", - m_consumer->getDefaultMQPushConsumerConfig()->getGroupName(), messageQueue.toString()); + consumer_->getDefaultMQPushConsumerConfig()->getGroupName(), messageQueue.toString()); return; } @@ -74,13 +75,13 @@ void ConsumeMessageConcurrentlyService::ConsumeRequest(std::vectorresetRetryTopic( - msgs, m_consumer->getDefaultMQPushConsumerConfig()->getGroupName()); // set where to sendMessageBack + consumer_->resetRetryTopic( + msgs, consumer_->getDefaultMQPushConsumerConfig()->getGroupName()); // set where to sendMessageBack ConsumeStatus status = RECONSUME_LATER; try { auto consumeTimestamp = UtilAll::currentTimeMillis(); - processQueue->setLastConsumeTimestamp(consumeTimestamp); + processQueue->set_last_consume_timestamp(consumeTimestamp); if (!msgs.empty()) { auto timestamp = UtilAll::to_string(consumeTimestamp); for (const auto& msg : msgs) { @@ -92,12 +93,12 @@ void ConsumeMessageConcurrentlyService::ConsumeRequest(std::vectorconsumeMessage(message_list); + status = message_listener_->consumeMessage(message_list); } catch (const std::exception& e) { LOG_WARN_NEW("encounter unexpected exception when consume messages.\n{}", e.what()); } - if (processQueue->isDropped()) { + if (processQueue->dropped()) { LOG_WARN_NEW("processQueue is dropped without process consume result. messageQueue={}", messageQueue.toString()); return; } @@ -117,7 +118,7 @@ void ConsumeMessageConcurrentlyService::ConsumeRequest(std::vectormessageModel()) { + switch (consumer_->messageModel()) { case BROADCASTING: // Note: broadcasting reconsume should do by application, as it has big affect to broker cluster for (size_t i = ackIndex + 1; i < msgs.size(); i++) { @@ -133,7 +134,7 @@ void ConsumeMessageConcurrentlyService::ConsumeRequest(std::vectorgetMsgId(), idx, (*iter)->getReconsumeTimes()); auto& msg = (*iter); - bool result = m_consumer->sendMessageBack(msg, 0, messageQueue.getBrokerName()); + bool result = consumer_->sendMessageBack(msg, 0, messageQueue.broker_name()); if (!result) { msg->setReconsumeTimes(msg->getReconsumeTimes() + 1); msgBackFailed.push_back(msg); @@ -154,8 +155,8 @@ void ConsumeMessageConcurrentlyService::ConsumeRequest(std::vectorremoveMessage(msgs); - if (offset >= 0 && !processQueue->isDropped()) { - m_consumer->getOffsetStore()->updateOffset(messageQueue, offset, true); + if (offset >= 0 && !processQueue->dropped()) { + consumer_->getOffsetStore()->updateOffset(messageQueue, offset, true); } } diff --git a/src/consumer/ConsumeMessageOrderlyService.cpp b/src/consumer/ConsumeMessageOrderlyService.cpp index 4404edcb8..1a3698cd7 100755 --- a/src/consumer/ConsumeMessageOrderlyService.cpp +++ b/src/consumer/ConsumeMessageOrderlyService.cpp @@ -15,6 +15,7 @@ * limitations under the License. */ #include "ConsumeMsgService.h" + #include "Logging.h" #include "OffsetStore.h" #include "RebalanceImpl.h" @@ -22,24 +23,24 @@ namespace rocketmq { -const uint64_t ConsumeMessageOrderlyService::MaxTimeConsumeContinuously = 60000; +const uint64_t MAX_TIME_CONSUME_CONTINUOUSLY = 60000; ConsumeMessageOrderlyService::ConsumeMessageOrderlyService(DefaultMQPushConsumerImpl* consumer, int threadCount, MQMessageListener* msgListener) - : m_consumer(consumer), - m_messageListener(msgListener), - m_consumeExecutor("OderlyConsumeService", threadCount, false), - m_scheduledExecutorService(false) {} + : consumer_(consumer), + message_listener_(msgListener), + consume_executor_("OderlyConsumeService", threadCount, false), + scheduled_executor_service_(false) {} ConsumeMessageOrderlyService::~ConsumeMessageOrderlyService() = default; void ConsumeMessageOrderlyService::start() { - m_consumeExecutor.startup(); + consume_executor_.startup(); - m_scheduledExecutorService.startup(); - m_scheduledExecutorService.schedule(std::bind(&ConsumeMessageOrderlyService::lockMQPeriodically, this), - ProcessQueue::RebalanceLockInterval, time_unit::milliseconds); + scheduled_executor_service_.startup(); + scheduled_executor_service_.schedule(std::bind(&ConsumeMessageOrderlyService::lockMQPeriodically, this), + ProcessQueue::REBALANCE_LOCK_INTERVAL, time_unit::milliseconds); } void ConsumeMessageOrderlyService::shutdown() { @@ -48,23 +49,23 @@ void ConsumeMessageOrderlyService::shutdown() { } void ConsumeMessageOrderlyService::stopThreadPool() { - m_consumeExecutor.shutdown(); - m_scheduledExecutorService.shutdown(); + consume_executor_.shutdown(); + scheduled_executor_service_.shutdown(); } void ConsumeMessageOrderlyService::lockMQPeriodically() { - m_consumer->getRebalanceImpl()->lockAll(); + consumer_->getRebalanceImpl()->lockAll(); - m_scheduledExecutorService.schedule(std::bind(&ConsumeMessageOrderlyService::lockMQPeriodically, this), - ProcessQueue::RebalanceLockInterval, time_unit::milliseconds); + scheduled_executor_service_.schedule(std::bind(&ConsumeMessageOrderlyService::lockMQPeriodically, this), + ProcessQueue::REBALANCE_LOCK_INTERVAL, time_unit::milliseconds); } void ConsumeMessageOrderlyService::unlockAllMQ() { - m_consumer->getRebalanceImpl()->unlockAll(false); + consumer_->getRebalanceImpl()->unlockAll(false); } bool ConsumeMessageOrderlyService::lockOneMQ(const MQMessageQueue& mq) { - return m_consumer->getRebalanceImpl()->lock(mq); + return consumer_->getRebalanceImpl()->lock(mq); } void ConsumeMessageOrderlyService::submitConsumeRequest(std::vector& msgs, @@ -72,7 +73,7 @@ void ConsumeMessageOrderlyService::submitConsumeRequest(std::vector dummy; - m_scheduledExecutorService.schedule(std::bind(&ConsumeMessageOrderlyService::submitConsumeRequest, this, - std::ref(dummy), processQueue, messageQueue, true), - timeMillis, time_unit::milliseconds); + scheduled_executor_service_.schedule(std::bind(&ConsumeMessageOrderlyService::submitConsumeRequest, this, + std::ref(dummy), processQueue, messageQueue, true), + timeMillis, time_unit::milliseconds); } void ConsumeMessageOrderlyService::tryLockLaterAndReconsume(const MQMessageQueue& mq, ProcessQueuePtr processQueue, const long delayMills) { - m_scheduledExecutorService.schedule( + scheduled_executor_service_.schedule( [this, mq, processQueue]() { bool lockOK = lockOneMQ(mq); if (lockOK) { @@ -109,50 +110,50 @@ void ConsumeMessageOrderlyService::tryLockLaterAndReconsume(const MQMessageQueue } void ConsumeMessageOrderlyService::ConsumeRequest(ProcessQueuePtr processQueue, const MQMessageQueue& messageQueue) { - if (processQueue->isDropped()) { + if (processQueue->dropped()) { LOG_WARN_NEW("run, the message queue not be able to consume, because it's dropped. {}", messageQueue.toString()); return; } - auto objLock = m_messageQueueLock.fetchLockObject(messageQueue); + auto objLock = message_queue_lock_.fetchLockObject(messageQueue); std::lock_guard lock(*objLock); - if (BROADCASTING == m_consumer->messageModel() || (processQueue->isLocked() && !processQueue->isLockExpired())) { + if (BROADCASTING == consumer_->messageModel() || (processQueue->locked() && !processQueue->isLockExpired())) { auto beginTime = UtilAll::currentTimeMillis(); for (bool continueConsume = true; continueConsume;) { - if (processQueue->isDropped()) { + if (processQueue->dropped()) { LOG_WARN_NEW("the message queue not be able to consume, because it's dropped. {}", messageQueue.toString()); break; } - if (CLUSTERING == m_consumer->messageModel() && !processQueue->isLocked()) { + if (CLUSTERING == consumer_->messageModel() && !processQueue->locked()) { LOG_WARN_NEW("the message queue not locked, so consume later, {}", messageQueue.toString()); tryLockLaterAndReconsume(messageQueue, processQueue, 10); break; } - if (CLUSTERING == m_consumer->messageModel() && processQueue->isLockExpired()) { + if (CLUSTERING == consumer_->messageModel() && processQueue->isLockExpired()) { LOG_WARN_NEW("the message queue lock expired, so consume later, {}", messageQueue.toString()); tryLockLaterAndReconsume(messageQueue, processQueue, 10); break; } auto interval = UtilAll::currentTimeMillis() - beginTime; - if (interval > MaxTimeConsumeContinuously) { + if (interval > MAX_TIME_CONSUME_CONTINUOUSLY) { submitConsumeRequestLater(processQueue, messageQueue, 10); break; } - const int consumeBatchSize = m_consumer->getDefaultMQPushConsumerConfig()->getConsumeMessageBatchMaxSize(); + const int consumeBatchSize = consumer_->getDefaultMQPushConsumerConfig()->getConsumeMessageBatchMaxSize(); std::vector msgs; processQueue->takeMessages(msgs, consumeBatchSize); - m_consumer->resetRetryTopic(msgs, m_consumer->getDefaultMQPushConsumerConfig()->getGroupName()); + consumer_->resetRetryTopic(msgs, consumer_->getDefaultMQPushConsumerConfig()->getGroupName()); if (!msgs.empty()) { ConsumeStatus status = RECONSUME_LATER; try { - std::lock_guard lock(processQueue->getLockConsume()); - if (processQueue->isDropped()) { + std::lock_guard lock(processQueue->lock_consume()); + if (processQueue->dropped()) { LOG_WARN_NEW("consumeMessage, the message queue not be able to consume, because it's dropped. {}", messageQueue.toString()); break; @@ -162,7 +163,7 @@ void ConsumeMessageOrderlyService::ConsumeRequest(ProcessQueuePtr processQueue, for (const auto& msg : msgs) { message_list.emplace_back(msg); } - status = m_messageListener->consumeMessage(message_list); + status = message_listener_->consumeMessage(message_list); } catch (const std::exception& e) { LOG_WARN_NEW("encounter unexpected exception when consume messages.\n{}", e.what()); } @@ -182,15 +183,15 @@ void ConsumeMessageOrderlyService::ConsumeRequest(ProcessQueuePtr processQueue, break; } - if (commitOffset >= 0 && !processQueue->isDropped()) { - m_consumer->getOffsetStore()->updateOffset(messageQueue, commitOffset, false); + if (commitOffset >= 0 && !processQueue->dropped()) { + consumer_->getOffsetStore()->updateOffset(messageQueue, commitOffset, false); } } else { continueConsume = false; } } } else { - if (processQueue->isDropped()) { + if (processQueue->dropped()) { LOG_WARN_NEW("the message queue not be able to consume, because it's dropped. {}", messageQueue.toString()); return; } diff --git a/src/consumer/ConsumeMsgService.h b/src/consumer/ConsumeMsgService.h index b8e1d8aea..6f5780903 100755 --- a/src/consumer/ConsumeMsgService.h +++ b/src/consumer/ConsumeMsgService.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __CONSUME_MESSAGE_SERVICE_H__ -#define __CONSUME_MESSAGE_SERVICE_H__ +#ifndef ROCKETMQ_CONSUMER_CONSUMEMSGSERVICE_H_ +#define ROCKETMQ_CONSUMER_CONSUMEMSGSERVICE_H_ #include "DefaultMQPushConsumerImpl.h" #include "Logging.h" @@ -62,11 +62,11 @@ class ConsumeMessageConcurrentlyService : public ConsumeMsgService { const MQMessageQueue& messageQueue); private: - DefaultMQPushConsumerImpl* m_consumer; - MQMessageListener* m_messageListener; + DefaultMQPushConsumerImpl* consumer_; + MQMessageListener* message_listener_; - thread_pool_executor m_consumeExecutor; - scheduled_thread_pool_executor m_scheduledExecutorService; + thread_pool_executor consume_executor_; + scheduled_thread_pool_executor scheduled_executor_service_; }; class ConsumeMessageOrderlyService : public ConsumeMsgService { @@ -94,17 +94,14 @@ class ConsumeMessageOrderlyService : public ConsumeMsgService { bool lockOneMQ(const MQMessageQueue& mq); private: - static const uint64_t MaxTimeConsumeContinuously; + DefaultMQPushConsumerImpl* consumer_; + MQMessageListener* message_listener_; - private: - DefaultMQPushConsumerImpl* m_consumer; - MQMessageListener* m_messageListener; - - MessageQueueLock m_messageQueueLock; - thread_pool_executor m_consumeExecutor; - scheduled_thread_pool_executor m_scheduledExecutorService; + MessageQueueLock message_queue_lock_; + thread_pool_executor consume_executor_; + scheduled_thread_pool_executor scheduled_executor_service_; }; } // namespace rocketmq -#endif // __CONSUME_MESSAGE_SERVICE_H__ +#endif // ROCKETMQ_CONSUMER_CONSUMEMSGSERVICE_H_ diff --git a/src/consumer/DefaultMQPullConsumerImpl.cpp b/src/consumer/DefaultMQPullConsumerImpl.cpp index e72defd01..78845cf51 100644 --- a/src/consumer/DefaultMQPullConsumerImpl.cpp +++ b/src/consumer/DefaultMQPullConsumerImpl.cpp @@ -276,7 +276,7 @@ // } // void DefaultMQPullConsumer::subscriptionAutomatically(const std::string& topic) { -// SubscriptionDataPtr pSdata = m_rebalanceImpl->getSubscriptionData(topic); +// SubscriptionData* pSdata = m_rebalanceImpl->getSubscriptionData(topic); // if (pSdata == nullptr) { // std::unique_ptr subscriptionData(FilterAPI::buildSubscriptionData(topic, SUB_ALL)); // m_rebalanceImpl->setSubscriptionData(topic, subscriptionData.release()); diff --git a/src/consumer/DefaultMQPushConsumer.cpp b/src/consumer/DefaultMQPushConsumer.cpp index d72994883..f5a80d9cf 100644 --- a/src/consumer/DefaultMQPushConsumer.cpp +++ b/src/consumer/DefaultMQPushConsumer.cpp @@ -16,7 +16,7 @@ */ #include "DefaultMQPushConsumer.h" -#include "DefaultMQPushConsumerConfigImpl.h" +#include "DefaultMQPushConsumerConfigImpl.hpp" #include "DefaultMQPushConsumerImpl.h" #include "UtilAll.h" @@ -35,7 +35,8 @@ DefaultMQPushConsumer::DefaultMQPushConsumer(const std::string& groupname, RPCHo setGroupName(groupname); } - push_consumer_impl_ = DefaultMQPushConsumerImpl::create(getRealConfig(), rpcHook); + // create DefaultMQPushConsumerImpl + push_consumer_impl_ = DefaultMQPushConsumerImpl::create(real_config(), rpcHook); } DefaultMQPushConsumer::~DefaultMQPushConsumer() = default; @@ -89,7 +90,7 @@ void DefaultMQPushConsumer::resume() { } void DefaultMQPushConsumer::setRPCHook(RPCHookPtr rpcHook) { - std::dynamic_pointer_cast(push_consumer_impl_)->setRPCHook(rpcHook); + dynamic_cast(push_consumer_impl_.get())->setRPCHook(rpcHook); } } // namespace rocketmq diff --git a/src/consumer/DefaultMQPushConsumerConfigImpl.cpp b/src/consumer/DefaultMQPushConsumerConfigImpl.cpp deleted file mode 100644 index 560a6be02..000000000 --- a/src/consumer/DefaultMQPushConsumerConfigImpl.cpp +++ /dev/null @@ -1,125 +0,0 @@ - -/* - * 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 "DefaultMQPushConsumerConfigImpl.h" - -#include -#include - -#include "AllocateMQAveragely.h" - -namespace rocketmq { - -DefaultMQPushConsumerConfigImpl::DefaultMQPushConsumerConfigImpl() - : m_messageModel(CLUSTERING), - m_consumeFromWhere(CONSUME_FROM_LAST_OFFSET), - m_consumeTimestamp("0"), - m_consumeThreadNum(std::min(8, (int)std::thread::hardware_concurrency())), - m_consumeMessageBatchMaxSize(1), - m_maxMsgCacheSize(1000), - m_asyncPullTimeout(30 * 1000), - m_maxReconsumeTimes(-1), - m_pullTimeDelayMillsWhenException(3000), - m_allocateMQStrategy(new AllocateMQAveragely()) {} - -MessageModel DefaultMQPushConsumerConfigImpl::getMessageModel() const { - return m_messageModel; -} - -void DefaultMQPushConsumerConfigImpl::setMessageModel(MessageModel messageModel) { - m_messageModel = messageModel; -} - -ConsumeFromWhere DefaultMQPushConsumerConfigImpl::getConsumeFromWhere() const { - return m_consumeFromWhere; -} - -void DefaultMQPushConsumerConfigImpl::setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) { - m_consumeFromWhere = consumeFromWhere; -} - -std::string DefaultMQPushConsumerConfigImpl::getConsumeTimestamp() { - return m_consumeTimestamp; -} - -void DefaultMQPushConsumerConfigImpl::setConsumeTimestamp(std::string consumeTimestamp) { - m_consumeTimestamp = consumeTimestamp; -} - -int DefaultMQPushConsumerConfigImpl::getConsumeThreadNum() const { - return m_consumeThreadNum; -} - -void DefaultMQPushConsumerConfigImpl::setConsumeThreadNum(int threadNum) { - if (threadNum > 0) { - m_consumeThreadNum = threadNum; - } -} - -int DefaultMQPushConsumerConfigImpl::getConsumeMessageBatchMaxSize() const { - return m_consumeMessageBatchMaxSize; -} - -void DefaultMQPushConsumerConfigImpl::setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) { - if (consumeMessageBatchMaxSize >= 1) { - m_consumeMessageBatchMaxSize = consumeMessageBatchMaxSize; - } -} - -int DefaultMQPushConsumerConfigImpl::getMaxCacheMsgSizePerQueue() const { - return m_maxMsgCacheSize; -} - -void DefaultMQPushConsumerConfigImpl::setMaxCacheMsgSizePerQueue(int maxCacheSize) { - if (maxCacheSize > 0 && maxCacheSize < 65535) { - m_maxMsgCacheSize = maxCacheSize; - } -} - -int DefaultMQPushConsumerConfigImpl::getAsyncPullTimeout() const { - return m_asyncPullTimeout; -} - -void DefaultMQPushConsumerConfigImpl::setAsyncPullTimeout(int asyncPullTimeout) { - m_asyncPullTimeout = asyncPullTimeout; -} - -int DefaultMQPushConsumerConfigImpl::getMaxReconsumeTimes() const { - return m_maxReconsumeTimes; -} - -void DefaultMQPushConsumerConfigImpl::setMaxReconsumeTimes(int maxReconsumeTimes) { - m_maxReconsumeTimes = maxReconsumeTimes; -} - -long DefaultMQPushConsumerConfigImpl::getPullTimeDelayMillsWhenException() const { - return m_pullTimeDelayMillsWhenException; -} - -void DefaultMQPushConsumerConfigImpl::setPullTimeDelayMillsWhenException(long pullTimeDelayMillsWhenException) { - m_pullTimeDelayMillsWhenException = pullTimeDelayMillsWhenException; -} - -AllocateMQStrategy* DefaultMQPushConsumerConfigImpl::getAllocateMQStrategy() const { - return m_allocateMQStrategy.get(); -} - -void DefaultMQPushConsumerConfigImpl::setAllocateMQStrategy(AllocateMQStrategy* strategy) { - m_allocateMQStrategy.reset(strategy); -} - -} // namespace rocketmq diff --git a/src/consumer/DefaultMQPushConsumerConfigImpl.h b/src/consumer/DefaultMQPushConsumerConfigImpl.h deleted file mode 100644 index 1ca601328..000000000 --- a/src/consumer/DefaultMQPushConsumerConfigImpl.h +++ /dev/null @@ -1,81 +0,0 @@ - -/* - * 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 __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_IMPL_H__ -#define __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_IMPL_H__ - -#include "DefaultMQPushConsumerConfig.h" -#include "MQClientConfigImpl.h" - -namespace rocketmq { - -class DefaultMQPushConsumerConfigImpl : virtual public DefaultMQPushConsumerConfig, public MQClientConfigImpl { - public: - DefaultMQPushConsumerConfigImpl(); - virtual ~DefaultMQPushConsumerConfigImpl() = default; - - MessageModel getMessageModel() const override; - void setMessageModel(MessageModel messageModel) override; - - ConsumeFromWhere getConsumeFromWhere() const override; - void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) override; - - std::string getConsumeTimestamp() override; - void setConsumeTimestamp(std::string consumeTimestamp) override; - - int getConsumeThreadNum() const override; - void setConsumeThreadNum(int threadNum) override; - - int getConsumeMessageBatchMaxSize() const override; - void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) override; - - int getMaxCacheMsgSizePerQueue() const override; - void setMaxCacheMsgSizePerQueue(int maxCacheSize) override; - - int getAsyncPullTimeout() const override; - void setAsyncPullTimeout(int asyncPullTimeout) override; - - int getMaxReconsumeTimes() const override; - void setMaxReconsumeTimes(int maxReconsumeTimes) override; - - long getPullTimeDelayMillsWhenException() const override; - void setPullTimeDelayMillsWhenException(long pullTimeDelayMillsWhenException) override; - - AllocateMQStrategy* getAllocateMQStrategy() const override; - void setAllocateMQStrategy(AllocateMQStrategy* strategy) override; - - protected: - MessageModel m_messageModel; - - ConsumeFromWhere m_consumeFromWhere; - std::string m_consumeTimestamp; - - int m_consumeThreadNum; - int m_consumeMessageBatchMaxSize; - int m_maxMsgCacheSize; - - int m_asyncPullTimeout; // 30s - int m_maxReconsumeTimes; - - long m_pullTimeDelayMillsWhenException; // 3000 - - std::unique_ptr m_allocateMQStrategy; -}; - -} // namespace rocketmq - -#endif // __DEFAULT_MQ_PUSH_CONSUMER_CONFIG_IMPL_H__ \ No newline at end of file diff --git a/src/consumer/DefaultMQPushConsumerConfigImpl.hpp b/src/consumer/DefaultMQPushConsumerConfigImpl.hpp new file mode 100644 index 000000000..1b1f1eb07 --- /dev/null +++ b/src/consumer/DefaultMQPushConsumerConfigImpl.hpp @@ -0,0 +1,112 @@ + +/* + * 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_CONSUMER_DEFAULTMQPUSHCONSUMERCONFIGIMPL_HPP_ +#define ROCKETMQ_CONSUMER_DEFAULTMQPUSHCONSUMERCONFIGIMPL_HPP_ + +#include // std::min +#include // std::thread::hardware_concurrency + +#include "AllocateMQAveragely.hpp" +#include "DefaultMQPushConsumerConfig.h" +#include "MQClientConfigImpl.hpp" + +namespace rocketmq { + +/** + * DefaultMQPushConsumerConfigImpl - implement for DefaultMQPushConsumerConfig + */ +class DefaultMQPushConsumerConfigImpl : virtual public DefaultMQPushConsumerConfig, public MQClientConfigImpl { + public: + DefaultMQPushConsumerConfigImpl() + : message_model_(MessageModel::CLUSTERING), + consume_from_where_(ConsumeFromWhere::CONSUME_FROM_LAST_OFFSET), + consume_timestamp_("0"), + consume_thread_num_(std::min(8, (int)std::thread::hardware_concurrency())), + consume_message_batch_max_size_(1), + max_msg_cache_size_(1000), + async_pull_timeout_(30 * 1000), + max_reconsume_times_(-1), + pull_time_delay_mills_when_exception_(3000), + allocate_mq_strategy_(new AllocateMQAveragely()) {} + virtual ~DefaultMQPushConsumerConfigImpl() = default; + + MessageModel getMessageModel() const override { return message_model_; } + void setMessageModel(MessageModel messageModel) override { message_model_ = messageModel; } + + ConsumeFromWhere getConsumeFromWhere() const override { return consume_from_where_; } + void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) override { consume_from_where_ = consumeFromWhere; } + + const std::string& getConsumeTimestamp() const override { return consume_timestamp_; } + void setConsumeTimestamp(const std::string& consumeTimestamp) override { consume_timestamp_ = consumeTimestamp; } + + int getConsumeThreadNum() const override { return consume_thread_num_; } + void setConsumeThreadNum(int threadNum) override { + if (threadNum > 0) { + consume_thread_num_ = threadNum; + } + } + + int getConsumeMessageBatchMaxSize() const override { return consume_message_batch_max_size_; } + void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) override { + if (consumeMessageBatchMaxSize >= 1) { + consume_message_batch_max_size_ = consumeMessageBatchMaxSize; + } + } + + int getMaxCacheMsgSizePerQueue() const override { return max_msg_cache_size_; } + void setMaxCacheMsgSizePerQueue(int maxCacheSize) override { + if (maxCacheSize > 0 && maxCacheSize < 65535) { + max_msg_cache_size_ = maxCacheSize; + } + } + + int getAsyncPullTimeout() const override { return async_pull_timeout_; } + void setAsyncPullTimeout(int asyncPullTimeout) override { async_pull_timeout_ = asyncPullTimeout; } + + int getMaxReconsumeTimes() const override { return max_reconsume_times_; } + void setMaxReconsumeTimes(int maxReconsumeTimes) override { max_reconsume_times_ = maxReconsumeTimes; } + + long getPullTimeDelayMillsWhenException() const override { return pull_time_delay_mills_when_exception_; } + void setPullTimeDelayMillsWhenException(long pullTimeDelayMillsWhenException) override { + pull_time_delay_mills_when_exception_ = pullTimeDelayMillsWhenException; + } + + AllocateMQStrategy* getAllocateMQStrategy() const override { return allocate_mq_strategy_.get(); } + void setAllocateMQStrategy(AllocateMQStrategy* strategy) override { allocate_mq_strategy_.reset(strategy); } + + protected: + MessageModel message_model_; + + ConsumeFromWhere consume_from_where_; + std::string consume_timestamp_; + + int consume_thread_num_; + int consume_message_batch_max_size_; + int max_msg_cache_size_; + + int async_pull_timeout_; // 30s + int max_reconsume_times_; + + long pull_time_delay_mills_when_exception_; // 3000 + + std::unique_ptr allocate_mq_strategy_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_CONSUMER_DEFAULTMQPUSHCONSUMERCONFIGIMPL_HPP_ \ No newline at end of file diff --git a/src/consumer/DefaultMQPushConsumerImpl.cpp b/src/consumer/DefaultMQPushConsumerImpl.cpp index 6e83861f4..71097b2e1 100644 --- a/src/consumer/DefaultMQPushConsumerImpl.cpp +++ b/src/consumer/DefaultMQPushConsumerImpl.cpp @@ -23,18 +23,19 @@ #include "CommunicationMode.h" #include "ConsumeMsgService.h" #include "ConsumerRunningInfo.h" -#include "FilterAPI.h" +#include "FilterAPI.hpp" #include "Logging.h" #include "MQAdminImpl.h" #include "MQClientAPIImpl.h" #include "MQClientInstance.h" #include "MQClientManager.h" #include "MQProtos.h" -#include "OffsetStore.h" +#include "LocalFileOffsetStore.h" #include "PullAPIWrapper.h" #include "PullMessageService.hpp" #include "PullSysFlag.h" #include "RebalancePushImpl.h" +#include "RemoteBrokerOffsetStore.h" #include "SocketUtil.h" #include "UtilAll.h" #include "Validators.h" @@ -45,40 +46,36 @@ class AsyncPullCallback : public AutoDeletePullCallback { public: AsyncPullCallback(DefaultMQPushConsumerImplPtr pushConsumer, PullRequestPtr request, - SubscriptionDataPtr subscriptionData) - : m_defaultMQPushConsumer(pushConsumer), m_pullRequest(request), m_subscriptionData(subscriptionData) {} + SubscriptionData* subscriptionData) + : default_mq_push_consumer_(pushConsumer), pull_request_(request), subscription_data_(subscriptionData) {} - ~AsyncPullCallback() override { - m_defaultMQPushConsumer.reset(); - m_pullRequest.reset(); - m_subscriptionData = nullptr; - } + ~AsyncPullCallback() = default; void onSuccess(PullResult& pullResult) override { - auto defaultMQPushConsumer = m_defaultMQPushConsumer.lock(); + auto defaultMQPushConsumer = default_mq_push_consumer_.lock(); if (nullptr == defaultMQPushConsumer) { LOG_WARN_NEW("AsyncPullCallback::onSuccess: DefaultMQPushConsumerImpl is released."); return; } - PullResult result = defaultMQPushConsumer->getPullAPIWrapper()->processPullResult(m_pullRequest->getMessageQueue(), - pullResult, m_subscriptionData); + PullResult result = defaultMQPushConsumer->getPullAPIWrapper()->processPullResult(pull_request_->message_queue(), + pullResult, subscription_data_); switch (result.pull_status()) { case FOUND: { - int64_t prevRequestOffset = m_pullRequest->getNextOffset(); - m_pullRequest->setNextOffset(result.next_begin_offset()); + int64_t prevRequestOffset = pull_request_->next_offset(); + pull_request_->set_next_offset(result.next_begin_offset()); int64_t firstMsgOffset = (std::numeric_limits::max)(); if (result.msg_found_list().empty()) { - defaultMQPushConsumer->executePullRequestImmediately(m_pullRequest); + defaultMQPushConsumer->executePullRequestImmediately(pull_request_); } else { firstMsgOffset = result.msg_found_list()[0]->getQueueOffset(); - m_pullRequest->getProcessQueue()->putMessage(result.msg_found_list()); + pull_request_->process_queue()->putMessage(result.msg_found_list()); defaultMQPushConsumer->getConsumerMsgService()->submitConsumeRequest( - result.msg_found_list(), m_pullRequest->getProcessQueue(), m_pullRequest->getMessageQueue(), true); + result.msg_found_list(), pull_request_->process_queue(), pull_request_->message_queue(), true); - defaultMQPushConsumer->executePullRequestImmediately(m_pullRequest); + defaultMQPushConsumer->executePullRequestImmediately(pull_request_); } if (result.next_begin_offset() < prevRequestOffset || firstMsgOffset < prevRequestOffset) { @@ -90,32 +87,32 @@ class AsyncPullCallback : public AutoDeletePullCallback { } break; case NO_NEW_MSG: case NO_MATCHED_MSG: - m_pullRequest->setNextOffset(result.next_begin_offset()); - defaultMQPushConsumer->correctTagsOffset(m_pullRequest); - defaultMQPushConsumer->executePullRequestImmediately(m_pullRequest); + pull_request_->set_next_offset(result.next_begin_offset()); + defaultMQPushConsumer->correctTagsOffset(pull_request_); + defaultMQPushConsumer->executePullRequestImmediately(pull_request_); break; case NO_LATEST_MSG: - m_pullRequest->setNextOffset(result.next_begin_offset()); - defaultMQPushConsumer->correctTagsOffset(m_pullRequest); + pull_request_->set_next_offset(result.next_begin_offset()); + defaultMQPushConsumer->correctTagsOffset(pull_request_); defaultMQPushConsumer->executePullRequestLater( - m_pullRequest, + pull_request_, defaultMQPushConsumer->getDefaultMQPushConsumerConfig()->getPullTimeDelayMillsWhenException()); break; case OFFSET_ILLEGAL: { - LOG_WARN_NEW("the pull request offset illegal, {} {}", m_pullRequest->toString(), result.toString()); + LOG_WARN_NEW("the pull request offset illegal, {} {}", pull_request_->toString(), result.toString()); - m_pullRequest->setNextOffset(result.next_begin_offset()); - m_pullRequest->getProcessQueue()->setDropped(true); + pull_request_->set_next_offset(result.next_begin_offset()); + pull_request_->process_queue()->set_dropped(true); // update and persist offset, then removeProcessQueue - auto pullRequest = m_pullRequest; + auto pullRequest = pull_request_; defaultMQPushConsumer->executeTaskLater( [defaultMQPushConsumer, pullRequest]() { try { - defaultMQPushConsumer->getOffsetStore()->updateOffset(pullRequest->getMessageQueue(), - pullRequest->getNextOffset(), false); - defaultMQPushConsumer->getOffsetStore()->persist(pullRequest->getMessageQueue()); - defaultMQPushConsumer->getRebalanceImpl()->removeProcessQueue(pullRequest->getMessageQueue()); + defaultMQPushConsumer->getOffsetStore()->updateOffset(pullRequest->message_queue(), + pullRequest->next_offset(), false); + defaultMQPushConsumer->getOffsetStore()->persist(pullRequest->message_queue()); + defaultMQPushConsumer->getRebalanceImpl()->removeProcessQueue(pullRequest->message_queue()); LOG_WARN_NEW("fix the pull request offset, {}", pullRequest->toString()); } catch (std::exception& e) { @@ -130,25 +127,25 @@ class AsyncPullCallback : public AutoDeletePullCallback { } void onException(MQException& e) noexcept override { - auto defaultMQPushConsumer = m_defaultMQPushConsumer.lock(); + auto defaultMQPushConsumer = default_mq_push_consumer_.lock(); if (nullptr == defaultMQPushConsumer) { LOG_WARN_NEW("AsyncPullCallback::onException: DefaultMQPushConsumerImpl is released."); return; } - if (!UtilAll::isRetryTopic(m_pullRequest->getMessageQueue().getTopic())) { + if (!UtilAll::isRetryTopic(pull_request_->message_queue().topic())) { LOG_WARN_NEW("execute the pull request exception: {}", e.what()); } // TODO defaultMQPushConsumer->executePullRequestLater( - m_pullRequest, defaultMQPushConsumer->getDefaultMQPushConsumerConfig()->getPullTimeDelayMillsWhenException()); + pull_request_, defaultMQPushConsumer->getDefaultMQPushConsumerConfig()->getPullTimeDelayMillsWhenException()); } private: - std::weak_ptr m_defaultMQPushConsumer; - PullRequestPtr m_pullRequest; - SubscriptionDataPtr m_subscriptionData; + std::weak_ptr default_mq_push_consumer_; + PullRequestPtr pull_request_; + SubscriptionData* subscription_data_; }; DefaultMQPushConsumerImpl::DefaultMQPushConsumerImpl(DefaultMQPushConsumerConfigPtr config) @@ -156,75 +153,17 @@ DefaultMQPushConsumerImpl::DefaultMQPushConsumerImpl(DefaultMQPushConsumerConfig DefaultMQPushConsumerImpl::DefaultMQPushConsumerImpl(DefaultMQPushConsumerConfigPtr config, RPCHookPtr rpcHook) : MQClientImpl(config, rpcHook), - m_pushConsumerConfig(config), - m_startTime(UtilAll::currentTimeMillis()), - m_pause(false), - m_consumeOrderly(false), - m_rebalanceImpl(new RebalancePushImpl(this)), - m_pullAPIWrapper(nullptr), - m_offsetStore(nullptr), - m_consumeService(nullptr), - m_messageListener(nullptr) {} + start_time_(UtilAll::currentTimeMillis()), + pause_(false), + consume_orderly_(false), + rebalance_impl_(new RebalancePushImpl(this)), + pull_api_wrapper_(nullptr), + offset_store_(nullptr), + consume_service_(nullptr), + message_listener_(nullptr) {} DefaultMQPushConsumerImpl::~DefaultMQPushConsumerImpl() = default; -int DefaultMQPushConsumerImpl::getMaxReconsumeTimes() { - // default reconsume times: 16 - if (m_pushConsumerConfig->getMaxReconsumeTimes() == -1) { - return 16; - } else { - return m_pushConsumerConfig->getMaxReconsumeTimes(); - } -} - -bool DefaultMQPushConsumerImpl::sendMessageBack(MessageExtPtr msg, int delayLevel) { - return sendMessageBack(msg, delayLevel, null); -} - -bool DefaultMQPushConsumerImpl::sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) { - try { - std::string brokerAddr = brokerName.empty() ? socketAddress2String(msg->getStoreHost()) - : m_clientInstance->findBrokerAddressInPublish(brokerName); - - m_clientInstance->getMQClientAPIImpl()->consumerSendMessageBack( - brokerAddr, msg, m_pushConsumerConfig->getGroupName(), delayLevel, 5000, getMaxReconsumeTimes()); - return true; - } catch (const std::exception& e) { - LOG_ERROR_NEW("sendMessageBack exception, group: {}, msg: {}. {}", m_pushConsumerConfig->getGroupName(), - msg->toString(), e.what()); - } - return false; -} - -void DefaultMQPushConsumerImpl::fetchSubscribeMessageQueues(const std::string& topic, - std::vector& mqs) { - mqs.clear(); - try { - m_clientInstance->getMQAdminImpl()->fetchSubscribeMessageQueues(topic, mqs); - } catch (MQException& e) { - LOG_ERROR_NEW("{}", e.what()); - } -} - -void DefaultMQPushConsumerImpl::doRebalance() { - if (!m_pause) { - m_rebalanceImpl->doRebalance(isConsumeOrderly()); - } -} - -void DefaultMQPushConsumerImpl::persistConsumerOffset() { - if (isServiceStateOk()) { - std::vector mqs = m_rebalanceImpl->getAllocatedMQ(); - if (m_pushConsumerConfig->getMessageModel() == BROADCASTING) { - m_offsetStore->persistAll(mqs); - } else { - for (const auto& mq : mqs) { - m_offsetStore->persist(mq); - } - } - } -} - void DefaultMQPushConsumerImpl::start() { #ifndef WIN32 /* Ignore the SIGPIPE */ @@ -235,165 +174,142 @@ void DefaultMQPushConsumerImpl::start() { ::sigaction(SIGPIPE, &sa, 0); #endif - switch (m_serviceState) { + switch (service_state_) { case CREATE_JUST: { - LOG_INFO_NEW("the consumer [{}] start beginning.", m_pushConsumerConfig->getGroupName()); + LOG_INFO_NEW("the consumer [{}] start beginning.", client_config_->getGroupName()); - m_serviceState = START_FAILED; + service_state_ = START_FAILED; - // data checkConfig(); copySubscription(); - if (messageModel() == CLUSTERING) { - m_pushConsumerConfig->changeInstanceNameToPID(); + if (messageModel() == MessageModel::CLUSTERING) { + client_config_->changeInstanceNameToPID(); } - // ensure m_clientInstance + // init client_instance_ MQClientImpl::start(); - // reset rebalance - m_rebalanceImpl->setConsumerGroup(m_pushConsumerConfig->getGroupName()); - m_rebalanceImpl->setMessageModel(m_pushConsumerConfig->getMessageModel()); - m_rebalanceImpl->setAllocateMQStrategy(m_pushConsumerConfig->getAllocateMQStrategy()); - m_rebalanceImpl->setClientInstance(m_clientInstance.get()); - - m_pullAPIWrapper.reset(new PullAPIWrapper(m_clientInstance.get(), m_pushConsumerConfig->getGroupName())); - - switch (m_pushConsumerConfig->getMessageModel()) { - case BROADCASTING: - m_offsetStore.reset(new LocalFileOffsetStore(m_clientInstance.get(), m_pushConsumerConfig->getGroupName())); + // init rebalance_impl_ + rebalance_impl_->set_consumer_group(client_config_->getGroupName()); + rebalance_impl_->set_message_model( + dynamic_cast(client_config_.get())->getMessageModel()); + rebalance_impl_->set_allocate_mq_strategy( + dynamic_cast(client_config_.get())->getAllocateMQStrategy()); + rebalance_impl_->set_client_instance(client_instance_.get()); + + // init pull_api_wrapper_ + pull_api_wrapper_.reset(new PullAPIWrapper(client_instance_.get(), client_config_->getGroupName())); + // TODO: registerFilterMessageHook + + // init offset_store_ + switch (dynamic_cast(client_config_.get())->getMessageModel()) { + case MessageModel::BROADCASTING: + offset_store_.reset(new LocalFileOffsetStore(client_instance_.get(), client_config_->getGroupName())); break; - case CLUSTERING: - m_offsetStore.reset( - new RemoteBrokerOffsetStore(m_clientInstance.get(), m_pushConsumerConfig->getGroupName())); + case MessageModel::CLUSTERING: + offset_store_.reset(new RemoteBrokerOffsetStore(client_instance_.get(), client_config_->getGroupName())); break; } - m_offsetStore->load(); - - // checkConfig() guarantee m_pMessageListener is not nullptr - if (m_messageListener->getMessageListenerType() == messageListenerOrderly) { - LOG_INFO_NEW("start orderly consume service: {}", m_pushConsumerConfig->getGroupName()); - m_consumeOrderly = true; - m_consumeService.reset( - new ConsumeMessageOrderlyService(this, m_pushConsumerConfig->getConsumeThreadNum(), m_messageListener)); + offset_store_->load(); + + // checkConfig() guarantee message_listener_ is not nullptr + if (message_listener_->getMessageListenerType() == messageListenerOrderly) { + LOG_INFO_NEW("start orderly consume service: {}", client_config_->getGroupName()); + consume_orderly_ = true; + consume_service_.reset(new ConsumeMessageOrderlyService( + this, dynamic_cast(client_config_.get())->getConsumeThreadNum(), + message_listener_)); } else { // for backward compatible, defaultly and concurrently listeners are allocating // ConsumeMessageConcurrentlyService - LOG_INFO_NEW("start concurrently consume service: {}", m_pushConsumerConfig->getGroupName()); - m_consumeOrderly = false; - m_consumeService.reset(new ConsumeMessageConcurrentlyService(this, m_pushConsumerConfig->getConsumeThreadNum(), - m_messageListener)); + LOG_INFO_NEW("start concurrently consume service: {}", client_config_->getGroupName()); + consume_orderly_ = false; + consume_service_.reset(new ConsumeMessageConcurrentlyService( + this, dynamic_cast(client_config_.get())->getConsumeThreadNum(), + message_listener_)); } - m_consumeService->start(); + consume_service_->start(); // register consumer - bool registerOK = m_clientInstance->registerConsumer(m_pushConsumerConfig->getGroupName(), this); + bool registerOK = client_instance_->registerConsumer(client_config_->getGroupName(), this); if (!registerOK) { - m_serviceState = CREATE_JUST; - m_consumeService->shutdown(); - THROW_MQEXCEPTION(MQClientException, "The cousumer group[" + m_pushConsumerConfig->getGroupName() + + service_state_ = CREATE_JUST; + consume_service_->shutdown(); + THROW_MQEXCEPTION(MQClientException, "The cousumer group[" + client_config_->getGroupName() + "] has been created before, specify another name please.", -1); } - m_clientInstance->start(); - LOG_INFO_NEW("the consumer [{}] start OK", m_pushConsumerConfig->getGroupName()); - m_serviceState = RUNNING; + client_instance_->start(); + + LOG_INFO_NEW("the consumer [{}] start OK", client_config_->getGroupName()); + service_state_ = RUNNING; break; } case RUNNING: case START_FAILED: case SHUTDOWN_ALREADY: + THROW_MQEXCEPTION(MQClientException, "The PushConsumer service state not OK, maybe started once", -1); break; default: break; } updateTopicSubscribeInfoWhenSubscriptionChanged(); - m_clientInstance->sendHeartbeatToAllBrokerWithLock(); - m_clientInstance->rebalanceImmediately(); -} - -void DefaultMQPushConsumerImpl::shutdown() { - switch (m_serviceState) { - case RUNNING: { - m_consumeService->shutdown(); - persistConsumerOffset(); - m_clientInstance->unregisterConsumer(m_pushConsumerConfig->getGroupName()); - m_clientInstance->shutdown(); - LOG_INFO_NEW("the consumer [{}] shutdown OK", m_pushConsumerConfig->getGroupName()); - m_rebalanceImpl->destroy(); - m_serviceState = SHUTDOWN_ALREADY; - break; - } - case CREATE_JUST: - case SHUTDOWN_ALREADY: - break; - default: - break; - } -} - -void DefaultMQPushConsumerImpl::registerMessageListener(MQMessageListener* messageListener) { - if (nullptr != messageListener) { - m_messageListener = messageListener; - } -} - -void DefaultMQPushConsumerImpl::registerMessageListener(MessageListenerConcurrently* messageListener) { - registerMessageListener(static_cast(messageListener)); -} - -void DefaultMQPushConsumerImpl::registerMessageListener(MessageListenerOrderly* messageListener) { - registerMessageListener(static_cast(messageListener)); -} - -MQMessageListener* DefaultMQPushConsumerImpl::getMessageListener() const { - return m_messageListener; -} - -void DefaultMQPushConsumerImpl::subscribe(const std::string& topic, const std::string& subExpression) { - m_subTopics[topic] = subExpression; + client_instance_->sendHeartbeatToAllBrokerWithLock(); + client_instance_->rebalanceImmediately(); } void DefaultMQPushConsumerImpl::checkConfig() { - std::string groupname = m_pushConsumerConfig->getGroupName(); + std::string groupname = client_config_->getGroupName(); // check consumerGroup Validators::checkGroup(groupname); // consumerGroup - if (!groupname.compare(DEFAULT_CONSUMER_GROUP)) { - THROW_MQEXCEPTION(MQClientException, "consumerGroup can not equal DEFAULT_CONSUMER", -1); + if (DEFAULT_CONSUMER_GROUP == groupname) { + THROW_MQEXCEPTION(MQClientException, + "consumerGroup can not equal " + DEFAULT_CONSUMER_GROUP + ", please specify another one.", -1); + } + + if (dynamic_cast(client_config_.get())->getMessageModel() != BROADCASTING && + dynamic_cast(client_config_.get())->getMessageModel() != CLUSTERING) { + THROW_MQEXCEPTION(MQClientException, "messageModel is valid", -1); } - if (m_pushConsumerConfig->getMessageModel() != BROADCASTING && - m_pushConsumerConfig->getMessageModel() != CLUSTERING) { - THROW_MQEXCEPTION(MQClientException, "messageModel is valid ", -1); + // allocateMessageQueueStrategy + if (nullptr == dynamic_cast(client_config_.get())->getAllocateMQStrategy()) { + THROW_MQEXCEPTION(MQClientException, "allocateMessageQueueStrategy is null", -1); } - if (m_messageListener == nullptr) { - THROW_MQEXCEPTION(MQClientException, "messageListener is null ", -1); + // subscription + if (subscription_.empty()) { + THROW_MQEXCEPTION(MQClientException, "subscription is empty", -1); + } + + // messageListener + if (message_listener_ == nullptr) { + THROW_MQEXCEPTION(MQClientException, "messageListener is null", -1); } } void DefaultMQPushConsumerImpl::copySubscription() { - for (const auto& it : m_subTopics) { + for (const auto& it : subscription_) { LOG_INFO_NEW("buildSubscriptionData: {}, {}", it.first, it.second); - SubscriptionDataPtr subscriptionData = FilterAPI::buildSubscriptionData(it.first, it.second); - m_rebalanceImpl->setSubscriptionData(it.first, subscriptionData); + SubscriptionData* subscriptionData = FilterAPI::buildSubscriptionData(it.first, it.second); + rebalance_impl_->setSubscriptionData(it.first, subscriptionData); } - switch (m_pushConsumerConfig->getMessageModel()) { + switch (dynamic_cast(client_config_.get())->getMessageModel()) { case BROADCASTING: break; case CLUSTERING: { // auto subscript retry topic - std::string retryTopic = UtilAll::getRetryTopic(m_pushConsumerConfig->getGroupName()); - SubscriptionDataPtr subscriptionData = FilterAPI::buildSubscriptionData(retryTopic, SUB_ALL); - m_rebalanceImpl->setSubscriptionData(retryTopic, subscriptionData); + std::string retryTopic = UtilAll::getRetryTopic(client_config_->getGroupName()); + SubscriptionData* subscriptionData = FilterAPI::buildSubscriptionData(retryTopic, SUB_ALL); + rebalance_impl_->setSubscriptionData(retryTopic, subscriptionData); break; } default: @@ -401,88 +317,149 @@ void DefaultMQPushConsumerImpl::copySubscription() { } } -void DefaultMQPushConsumerImpl::updateTopicSubscribeInfo(const std::string& topic, std::vector& info) { - m_rebalanceImpl->setTopicSubscribeInfo(topic, info); -} - void DefaultMQPushConsumerImpl::updateTopicSubscribeInfoWhenSubscriptionChanged() { - auto& subTable = m_rebalanceImpl->getSubscriptionInner(); - for (const auto& sub : subTable) { - bool ret = m_clientInstance->updateTopicRouteInfoFromNameServer(sub.first); + auto& subTable = rebalance_impl_->getSubscriptionInner(); + for (const auto& it : subTable) { + const auto& topic = it.first; + bool ret = client_instance_->updateTopicRouteInfoFromNameServer(topic); if (!ret) { - LOG_WARN_NEW("The topic:[{}] not exist", sub.first); + LOG_WARN_NEW("The topic:[{}] not exist", topic); } } } -std::string DefaultMQPushConsumerImpl::groupName() const { - return m_pushConsumerConfig->getGroupName(); +void DefaultMQPushConsumerImpl::shutdown() { + switch (service_state_) { + case RUNNING: { + consume_service_->shutdown(); + persistConsumerOffset(); + client_instance_->unregisterConsumer(client_config_->getGroupName()); + client_instance_->shutdown(); + LOG_INFO_NEW("the consumer [{}] shutdown OK", client_config_->getGroupName()); + rebalance_impl_->destroy(); + service_state_ = SHUTDOWN_ALREADY; + break; + } + case CREATE_JUST: + case SHUTDOWN_ALREADY: + break; + default: + break; + } } -MessageModel DefaultMQPushConsumerImpl::messageModel() const { - return m_pushConsumerConfig->getMessageModel(); -}; +bool DefaultMQPushConsumerImpl::sendMessageBack(MessageExtPtr msg, int delayLevel) { + return sendMessageBack(msg, delayLevel, null); +} -ConsumeType DefaultMQPushConsumerImpl::consumeType() const { - return CONSUME_PASSIVELY; +bool DefaultMQPushConsumerImpl::sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) { + try { + std::string brokerAddr = brokerName.empty() ? socketAddress2String(msg->getStoreHost()) + : client_instance_->findBrokerAddressInPublish(brokerName); + + client_instance_->getMQClientAPIImpl()->consumerSendMessageBack( + brokerAddr, msg, dynamic_cast(client_config_.get())->getGroupName(), delayLevel, + 5000, getMaxReconsumeTimes()); + return true; + } catch (const std::exception& e) { + LOG_ERROR_NEW("sendMessageBack exception, group: {}, msg: {}. {}", + dynamic_cast(client_config_.get())->getGroupName(), msg->toString(), + e.what()); + } + return false; } -ConsumeFromWhere DefaultMQPushConsumerImpl::consumeFromWhere() const { - return m_pushConsumerConfig->getConsumeFromWhere(); +void DefaultMQPushConsumerImpl::fetchSubscribeMessageQueues(const std::string& topic, + std::vector& mqs) { + mqs.clear(); + try { + client_instance_->getMQAdminImpl()->fetchSubscribeMessageQueues(topic, mqs); + } catch (MQException& e) { + LOG_ERROR_NEW("{}", e.what()); + } } -std::vector DefaultMQPushConsumerImpl::subscriptions() const { - std::vector result; - auto& subTable = m_rebalanceImpl->getSubscriptionInner(); - for (const auto& it : subTable) { - result.push_back(*(it.second)); +void DefaultMQPushConsumerImpl::registerMessageListener(MQMessageListener* messageListener) { + if (nullptr != messageListener) { + message_listener_ = messageListener; } - return result; +} + +void DefaultMQPushConsumerImpl::registerMessageListener(MessageListenerConcurrently* messageListener) { + registerMessageListener(static_cast(messageListener)); +} + +void DefaultMQPushConsumerImpl::registerMessageListener(MessageListenerOrderly* messageListener) { + registerMessageListener(static_cast(messageListener)); +} + +MQMessageListener* DefaultMQPushConsumerImpl::getMessageListener() const { + return message_listener_; +} + +void DefaultMQPushConsumerImpl::subscribe(const std::string& topic, const std::string& subExpression) { + // TODO: change substation after start + subscription_[topic] = subExpression; } void DefaultMQPushConsumerImpl::suspend() { - m_pause = true; - LOG_INFO_NEW("suspend this consumer, {}", m_pushConsumerConfig->getGroupName()); + pause_ = true; + LOG_INFO_NEW("suspend this consumer, {}", client_config_->getGroupName()); } void DefaultMQPushConsumerImpl::resume() { - m_pause = false; + pause_ = false; doRebalance(); - LOG_INFO_NEW("resume this consumer, {}", m_pushConsumerConfig->getGroupName()); + LOG_INFO_NEW("resume this consumer, {}", client_config_->getGroupName()); } -bool DefaultMQPushConsumerImpl::isPause() { - return m_pause; +void DefaultMQPushConsumerImpl::doRebalance() { + if (!pause_) { + rebalance_impl_->doRebalance(isConsumeOrderly()); + } } -void DefaultMQPushConsumerImpl::setPause(bool pause) { - m_pause = pause; +void DefaultMQPushConsumerImpl::persistConsumerOffset() { + if (isServiceStateOk()) { + std::vector mqs = rebalance_impl_->getAllocatedMQ(); + if (dynamic_cast(client_config_.get())->getMessageModel() == BROADCASTING) { + offset_store_->persistAll(mqs); + } else { + for (const auto& mq : mqs) { + offset_store_->persist(mq); + } + } + } +} + +void DefaultMQPushConsumerImpl::updateTopicSubscribeInfo(const std::string& topic, std::vector& info) { + rebalance_impl_->setTopicSubscribeInfo(topic, info); } void DefaultMQPushConsumerImpl::updateConsumeOffset(const MQMessageQueue& mq, int64_t offset) { if (offset >= 0) { - m_offsetStore->updateOffset(mq, offset, false); + offset_store_->updateOffset(mq, offset, false); } else { LOG_ERROR_NEW("updateConsumeOffset of mq:{} error", mq.toString()); } } void DefaultMQPushConsumerImpl::correctTagsOffset(PullRequestPtr pullRequest) { - if (0L == pullRequest->getProcessQueue()->getCacheMsgCount()) { - m_offsetStore->updateOffset(pullRequest->getMessageQueue(), pullRequest->getNextOffset(), true); + if (0L == pullRequest->process_queue()->getCacheMsgCount()) { + offset_store_->updateOffset(pullRequest->message_queue(), pullRequest->next_offset(), true); } } void DefaultMQPushConsumerImpl::executePullRequestLater(PullRequestPtr pullRequest, long timeDelay) { - m_clientInstance->getPullMessageService()->executePullRequestLater(pullRequest, timeDelay); + client_instance_->getPullMessageService()->executePullRequestLater(pullRequest, timeDelay); } void DefaultMQPushConsumerImpl::executePullRequestImmediately(PullRequestPtr pullRequest) { - m_clientInstance->getPullMessageService()->executePullRequestImmediately(pullRequest); + client_instance_->getPullMessageService()->executePullRequestImmediately(pullRequest); } void DefaultMQPushConsumerImpl::executeTaskLater(const handler_type& task, long timeDelay) { - m_clientInstance->getPullMessageService()->executeTaskLater(task, timeDelay); + client_instance_->getPullMessageService()->executeTaskLater(task, timeDelay); } void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pullRequest) { @@ -491,26 +468,27 @@ void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pullRequest) { return; } - auto processQueue = pullRequest->getProcessQueue(); - if (processQueue->isDropped()) { + auto processQueue = pullRequest->process_queue(); + if (processQueue->dropped()) { LOG_WARN_NEW("the pull request[{}] is dropped.", pullRequest->toString()); return; } - processQueue->setLastPullTimestamp(UtilAll::currentTimeMillis()); + processQueue->set_last_pull_timestamp(UtilAll::currentTimeMillis()); int cachedMessageCount = processQueue->getCacheMsgCount(); - if (cachedMessageCount > m_pushConsumerConfig->getMaxCacheMsgSizePerQueue()) { + if (cachedMessageCount > + dynamic_cast(client_config_.get())->getMaxCacheMsgSizePerQueue()) { // too many message in cache, wait to process executePullRequestLater(pullRequest, 1000); return; } if (isConsumeOrderly()) { - if (processQueue->isLocked()) { - if (!pullRequest->isLockedFirst()) { - const auto offset = m_rebalanceImpl->computePullFromWhere(pullRequest->getMessageQueue()); - bool brokerBusy = offset < pullRequest->getNextOffset(); + if (processQueue->locked()) { + if (!pullRequest->locked_first()) { + const auto offset = rebalance_impl_->computePullFromWhere(pullRequest->message_queue()); + bool brokerBusy = offset < pullRequest->next_offset(); LOG_INFO_NEW( "the first time to pull message, so fix offset from broker. pullRequest: {} NewOffset: {} brokerBusy: {}", pullRequest->toString(), offset, UtilAll::to_string(brokerBusy)); @@ -521,34 +499,38 @@ void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pullRequest) { pullRequest->toString(), offset); } - pullRequest->setLockedFirst(true); - pullRequest->setNextOffset(offset); + pullRequest->set_locked_first(true); + pullRequest->set_next_offset(offset); } } else { - executePullRequestLater(pullRequest, m_pushConsumerConfig->getPullTimeDelayMillsWhenException()); + executePullRequestLater( + pullRequest, + dynamic_cast(client_config_.get())->getPullTimeDelayMillsWhenException()); LOG_INFO_NEW("pull message later because not locked in broker, {}", pullRequest->toString()); return; } } - const auto& messageQueue = pullRequest->getMessageQueue(); - SubscriptionDataPtr subscriptionData = m_rebalanceImpl->getSubscriptionData(messageQueue.getTopic()); + const auto& messageQueue = pullRequest->message_queue(); + SubscriptionData* subscriptionData = rebalance_impl_->getSubscriptionData(messageQueue.topic()); if (nullptr == subscriptionData) { - executePullRequestLater(pullRequest, m_pushConsumerConfig->getPullTimeDelayMillsWhenException()); + executePullRequestLater( + pullRequest, + dynamic_cast(client_config_.get())->getPullTimeDelayMillsWhenException()); LOG_WARN_NEW("find the consumer's subscription failed, {}", pullRequest->toString()); return; } bool commitOffsetEnable = false; int64_t commitOffsetValue = 0; - if (CLUSTERING == m_pushConsumerConfig->getMessageModel()) { - commitOffsetValue = m_offsetStore->readOffset(messageQueue, READ_FROM_MEMORY); + if (CLUSTERING == dynamic_cast(client_config_.get())->getMessageModel()) { + commitOffsetValue = offset_store_->readOffset(messageQueue, READ_FROM_MEMORY); if (commitOffsetValue > 0) { commitOffsetEnable = true; } } - const auto& subExpression = subscriptionData->getSubString(); + const auto& subExpression = subscriptionData->sub_string(); int sysFlag = PullSysFlag::buildSysFlag(commitOffsetEnable, // commitOffset true, // suspend @@ -557,20 +539,23 @@ void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pullRequest) { try { auto* callback = new AsyncPullCallback(shared_from_this(), pullRequest, subscriptionData); - m_pullAPIWrapper->pullKernelImpl(messageQueue, // 1 - subExpression, // 2 - subscriptionData->getSubVersion(), // 3 - pullRequest->getNextOffset(), // 4 - 32, // 5 - sysFlag, // 6 - commitOffsetValue, // 7 - 1000 * 15, // 8 - m_pushConsumerConfig->getAsyncPullTimeout(), // 9 - CommunicationMode::ASYNC, // 10 - callback); // 11 + pull_api_wrapper_->pullKernelImpl( + messageQueue, // 1 + subExpression, // 2 + subscriptionData->sub_version(), // 3 + pullRequest->next_offset(), // 4 + 32, // 5 + sysFlag, // 6 + commitOffsetValue, // 7 + 1000 * 15, // 8 + dynamic_cast(client_config_.get())->getAsyncPullTimeout(), // 9 + CommunicationMode::ASYNC, // 10 + callback); // 11 } catch (MQException& e) { LOG_ERROR_NEW("pullKernelImpl exception: {}", e.what()); - executePullRequestLater(pullRequest, m_pushConsumerConfig->getPullTimeDelayMillsWhenException()); + executePullRequestLater( + pullRequest, + dynamic_cast(client_config_.get())->getPullTimeDelayMillsWhenException()); } } @@ -585,25 +570,60 @@ void DefaultMQPushConsumerImpl::resetRetryTopic(const std::vector } } +int DefaultMQPushConsumerImpl::getMaxReconsumeTimes() { + // default reconsume times: 16 + if (dynamic_cast(client_config_.get())->getMaxReconsumeTimes() == -1) { + return 16; + } else { + return dynamic_cast(client_config_.get())->getMaxReconsumeTimes(); + } +} + +std::string DefaultMQPushConsumerImpl::groupName() const { + return client_config_->getGroupName(); +} + +MessageModel DefaultMQPushConsumerImpl::messageModel() const { + return dynamic_cast(client_config_.get())->getMessageModel(); +}; + +ConsumeType DefaultMQPushConsumerImpl::consumeType() const { + return CONSUME_PASSIVELY; +} + +ConsumeFromWhere DefaultMQPushConsumerImpl::consumeFromWhere() const { + return dynamic_cast(client_config_.get())->getConsumeFromWhere(); +} + +std::vector DefaultMQPushConsumerImpl::subscriptions() const { + std::vector result; + auto& subTable = rebalance_impl_->getSubscriptionInner(); + for (const auto& it : subTable) { + result.push_back(*(it.second)); + } + return result; +} + ConsumerRunningInfo* DefaultMQPushConsumerImpl::consumerRunningInfo() { auto* info = new ConsumerRunningInfo(); - info->setProperty(ConsumerRunningInfo::PROP_CONSUME_ORDERLY, UtilAll::to_string(m_consumeOrderly)); - info->setProperty(ConsumerRunningInfo::PROP_THREADPOOL_CORE_SIZE, - UtilAll::to_string(m_pushConsumerConfig->getConsumeThreadNum())); - info->setProperty(ConsumerRunningInfo::PROP_CONSUMER_START_TIMESTAMP, UtilAll::to_string(m_startTime)); + info->setProperty(ConsumerRunningInfo::PROP_CONSUME_ORDERLY, UtilAll::to_string(consume_orderly_)); + info->setProperty( + ConsumerRunningInfo::PROP_THREADPOOL_CORE_SIZE, + UtilAll::to_string(dynamic_cast(client_config_.get())->getConsumeThreadNum())); + info->setProperty(ConsumerRunningInfo::PROP_CONSUMER_START_TIMESTAMP, UtilAll::to_string(start_time_)); auto subSet = subscriptions(); info->setSubscriptionSet(subSet); - auto processQueueTable = m_rebalanceImpl->getProcessQueueTable(); + auto processQueueTable = rebalance_impl_->getProcessQueueTable(); for (const auto& it : processQueueTable) { const auto& mq = it.first; const auto& pq = it.second; ProcessQueueInfo pqinfo; - pqinfo.setCommitOffset(m_offsetStore->readOffset(mq, MEMORY_FIRST_THEN_STORE)); + pqinfo.setCommitOffset(offset_store_->readOffset(mq, MEMORY_FIRST_THEN_STORE)); pq->fillProcessQueueInfo(pqinfo); info->setMqTable(mq, pqinfo); } diff --git a/src/consumer/DefaultMQPushConsumerImpl.h b/src/consumer/DefaultMQPushConsumerImpl.h index 95563a251..e6bee6947 100755 --- a/src/consumer/DefaultMQPushConsumerImpl.h +++ b/src/consumer/DefaultMQPushConsumerImpl.h @@ -14,27 +14,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __DEFAULT_MQ_PUSH_CONSUMER_IMPL_H__ -#define __DEFAULT_MQ_PUSH_CONSUMER_IMPL_H__ +#ifndef ROCKETMQ_CONXUMER_DEFAULTMQPUSHCONSUMERIMPL_H_ +#define ROCKETMQ_CONXUMER_DEFAULTMQPUSHCONSUMERIMPL_H_ #include #include #include +#include "concurrent/executor.hpp" #include "DefaultMQPushConsumer.h" #include "MQClientImpl.h" #include "MQConsumerInner.h" #include "PullRequest.h" -#include "concurrent/executor.hpp" namespace rocketmq { -class RebalanceImpl; -class SubscriptionData; +class AsyncPullCallback; +class ConsumeMsgService; class OffsetStore; class PullAPIWrapper; -class ConsumeMsgService; -class AsyncPullCallback; +class RebalanceImpl; +class SubscriptionData; class DefaultMQPushConsumerImpl; typedef std::shared_ptr DefaultMQPushConsumerImplPtr; @@ -44,6 +44,10 @@ class DefaultMQPushConsumerImpl : public std::enable_shared_from_this& info) override; + ConsumerRunningInfo* consumerRunningInfo() override; public: - bool isPause(); - void setPause(bool pause); - void updateConsumeOffset(const MQMessageQueue& mq, int64_t offset); void correctTagsOffset(PullRequestPtr pullRequest); @@ -107,49 +109,52 @@ class DefaultMQPushConsumerImpl : public std::enable_shared_from_this& msgs, const std::string& consumerGroup); + private: + void checkConfig(); + void copySubscription(); + void updateTopicSubscribeInfoWhenSubscriptionChanged(); + public: - bool isConsumeOrderly() { return m_consumeOrderly; } + int getMaxReconsumeTimes(); + + inline bool isPause() const { return pause_; }; + inline void setPause(bool pause) { pause_ = pause; } - RebalanceImpl* getRebalanceImpl() const { return m_rebalanceImpl.get(); } + inline bool isConsumeOrderly() { return consume_orderly_; } - PullAPIWrapper* getPullAPIWrapper() const { return m_pullAPIWrapper.get(); } + inline RebalanceImpl* getRebalanceImpl() const { return rebalance_impl_.get(); } - OffsetStore* getOffsetStore() const { return m_offsetStore.get(); } + inline PullAPIWrapper* getPullAPIWrapper() const { return pull_api_wrapper_.get(); } - ConsumeMsgService* getConsumerMsgService() const { return m_consumeService.get(); } + inline OffsetStore* getOffsetStore() const { return offset_store_.get(); } - MessageListenerType getMessageListenerType() const { - if (nullptr != m_messageListener) { - return m_messageListener->getMessageListenerType(); + inline ConsumeMsgService* getConsumerMsgService() const { return consume_service_.get(); } + + inline MessageListenerType getMessageListenerType() const { + if (nullptr != message_listener_) { + return message_listener_->getMessageListenerType(); } return messageListenerDefaultly; } - DefaultMQPushConsumerConfig* getDefaultMQPushConsumerConfig() { return m_pushConsumerConfig.get(); } - - private: - void checkConfig(); - void copySubscription(); - void updateTopicSubscribeInfoWhenSubscriptionChanged(); - - int getMaxReconsumeTimes(); + inline DefaultMQPushConsumerConfig* getDefaultMQPushConsumerConfig() { + return dynamic_cast(client_config_.get()); + } private: - DefaultMQPushConsumerConfigPtr m_pushConsumerConfig; - - uint64_t m_startTime; + uint64_t start_time_; - volatile bool m_pause; - bool m_consumeOrderly; + volatile bool pause_; + bool consume_orderly_; - std::map m_subTopics; - std::unique_ptr m_rebalanceImpl; - std::unique_ptr m_pullAPIWrapper; - std::unique_ptr m_offsetStore; - std::unique_ptr m_consumeService; - MQMessageListener* m_messageListener; + std::map subscription_; + std::unique_ptr rebalance_impl_; + std::unique_ptr pull_api_wrapper_; + std::unique_ptr offset_store_; + std::unique_ptr consume_service_; + MQMessageListener* message_listener_; }; } // namespace rocketmq -#endif // __DEFAULT_MQ_PUSH_CONSUMER_IMPL_H__ +#endif // ROCKETMQ_CONXUMER_DEFAULTMQPUSHCONSUMERIMPL_H_ diff --git a/src/extern/MQClientErrorContainer.h b/src/consumer/FindBrokerResult.hpp similarity index 58% rename from src/extern/MQClientErrorContainer.h rename to src/consumer/FindBrokerResult.hpp index 1b3ff6ce4..0683e485c 100644 --- a/src/extern/MQClientErrorContainer.h +++ b/src/consumer/FindBrokerResult.hpp @@ -14,22 +14,28 @@ * 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__ +#ifndef ROCKETMQ_CONSUMER_FINDBROKERRESULT_HPP_ +#define ROCKETMQ_CONSUMER_FINDBROKERRESULT_HPP_ -#include +#include // std::string namespace rocketmq { -class MQClientErrorContainer { +class FindBrokerResult { public: - static void setErr(const std::string& str); - static const std::string& getErr(); + FindBrokerResult(const std::string& sbrokerAddr, bool bslave) : broker_addr_(sbrokerAddr), slave_(bslave) {} + + inline const std::string& broker_addr() const { return broker_addr_; } + inline void set_borker_addr(const std::string& broker_addr) { broker_addr_ = broker_addr; } + + inline bool slave() const { return slave_; } + inline void set_slave(bool slave) { slave_ = slave; } private: - static thread_local std::string t_err; + std::string broker_addr_; + bool slave_; }; } // namespace rocketmq -#endif // __MQ_CLIENT_ERROR_CONTAINER_H__ +#endif // ROCKETMQ_CONSUMER_FINDBROKERRESULT_HPP_ diff --git a/src/consumer/LocalFileOffsetStore.cpp b/src/consumer/LocalFileOffsetStore.cpp new file mode 100644 index 000000000..b2da58813 --- /dev/null +++ b/src/consumer/LocalFileOffsetStore.cpp @@ -0,0 +1,193 @@ +/* + * 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 "LocalFileOffsetStore.h" + +#include + +#include "Logging.h" +#include "MQClientInstance.h" +#include "MessageQueue.h" +#include "UtilAll.h" + +namespace rocketmq { + +LocalFileOffsetStore::LocalFileOffsetStore(MQClientInstance* instance, const std::string& groupName) + : client_instance_(instance), group_name_(groupName) { + LOG_INFO("new LocalFileOffsetStore"); + + std::string clientId = instance->getClientId(); + std::string homeDir(UtilAll::getHomeDirectory()); + std::string storeDir = + homeDir + FILE_SEPARATOR + ".rocketmq_offsets" + FILE_SEPARATOR + clientId + FILE_SEPARATOR + groupName; + store_path_ = storeDir + FILE_SEPARATOR + "offsets.json"; + + if (!UtilAll::existDirectory(storeDir)) { + UtilAll::createDirectory(storeDir); + if (!UtilAll::existDirectory(storeDir)) { + LOG_ERROR("create offset store dir:%s error", storeDir.c_str()); + std::string errorMsg("create offset store dir failed: "); + errorMsg.append(storeDir); + THROW_MQEXCEPTION(MQClientException, errorMsg, -1); + } + } +} + +LocalFileOffsetStore::~LocalFileOffsetStore() { + client_instance_ = nullptr; + offset_table_.clear(); +} + +void LocalFileOffsetStore::load() { + auto offsetTable = readLocalOffset(); + if (!offsetTable.empty()) { + // update offsetTable + { + std::lock_guard lock(lock_); + offset_table_ = offsetTable; + } + + for (const auto& it : offsetTable) { + const auto& mq = it.first; + const auto offset = it.second; + LOG_INFO_NEW("load consumer's offset, {} {} {}", group_name_, mq.toString(), offset); + } + } +} + +void LocalFileOffsetStore::updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) { + std::lock_guard lock(lock_); + offset_table_[mq] = offset; +} + +int64_t LocalFileOffsetStore::readOffset(const MQMessageQueue& mq, ReadOffsetType type) { + switch (type) { + case MEMORY_FIRST_THEN_STORE: + case READ_FROM_MEMORY: { + std::lock_guard lock(lock_); + const auto& it = offset_table_.find(mq); + if (it != offset_table_.end()) { + return it->second; + } else if (READ_FROM_MEMORY == type) { + return -1; + } + } break; + case READ_FROM_STORE: { + auto offsetTable = readLocalOffset(); + if (!offsetTable.empty()) { + const auto& it = offsetTable.find(mq); + if (it != offsetTable.end()) { + auto offset = it->second; + updateOffset(mq, offset, false); + return offset; + } + } + } break; + default: + break; + } + LOG_ERROR("can not readOffset from offsetStore.json, maybe first time consumation"); + return -1; +} + +void LocalFileOffsetStore::persist(const MQMessageQueue& mq) {} + +void LocalFileOffsetStore::persistAll(const std::vector& mqs) { + if (mqs.empty()) { + return; + } + + std::map offsetTable; + { + std::lock_guard lock(lock_); + offsetTable = offset_table_; + } + + Json::Value root(Json::objectValue); + Json::Value jOffsetTable(Json::objectValue); + for (const auto& mq : mqs) { + const auto& it = offsetTable.find(mq); + if (it != offsetTable.end()) { + std::string strMQ = RemotingSerializable::toJson(toJson(mq)); + jOffsetTable[strMQ] = Json::Value((Json::Int64)it->second); + } + } + root["offsetTable"] = jOffsetTable; + + std::lock_guard lock2(file_mutex_); + std::string storePathTmp = store_path_ + ".tmp"; + std::ofstream ofstrm(storePathTmp, std::ios::binary | std::ios::out); + if (ofstrm.is_open()) { + try { + RemotingSerializable::toJson(root, ofstrm, true); + } catch (std::exception& e) { + THROW_MQEXCEPTION(MQClientException, "persistAll failed", -1); + } + + if (!UtilAll::ReplaceFile(store_path_, store_path_ + ".bak") || !UtilAll::ReplaceFile(storePathTmp, store_path_)) { + LOG_ERROR("could not rename file: %s", strerror(errno)); + } + } +} + +void LocalFileOffsetStore::removeOffset(const MQMessageQueue& mq) {} + +std::map LocalFileOffsetStore::readLocalOffset() { + std::lock_guard lock(file_mutex_); + std::ifstream ifstrm(store_path_, std::ios::binary | std::ios::in); + if (ifstrm.is_open() && !ifstrm.eof()) { + try { + Json::Value root = RemotingSerializable::fromJson(ifstrm); + std::map offsetTable; + auto& jOffsetTable = root["offsetTable"]; + for (auto& strMQ : jOffsetTable.getMemberNames()) { + auto& offset = jOffsetTable[strMQ]; + Json::Value jMQ = RemotingSerializable::fromJson(strMQ); + MQMessageQueue mq(jMQ["topic"].asString(), jMQ["brokerName"].asString(), jMQ["queueId"].asInt()); + offsetTable.emplace(std::move(mq), offset.asInt64()); + } + return offsetTable; + } catch (std::exception& e) { + // ... + } + } + return readLocalOffsetBak(); +} + +std::map LocalFileOffsetStore::readLocalOffsetBak() { + std::map offsetTable; + std::ifstream ifstrm(store_path_ + ".bak", std::ios::binary | std::ios::in); + if (ifstrm.is_open()) { + if (!ifstrm.eof()) { + try { + Json::Value root = RemotingSerializable::fromJson(ifstrm); + auto& jOffsetTable = root["offsetTable"]; + for (auto& strMQ : jOffsetTable.getMemberNames()) { + auto& offset = jOffsetTable[strMQ]; + Json::Value jMQ = RemotingSerializable::fromJson(strMQ); + MQMessageQueue mq(jMQ["topic"].asString(), jMQ["brokerName"].asString(), jMQ["queueId"].asInt()); + offsetTable.emplace(std::move(mq), offset.asInt64()); + } + } catch (const std::exception& e) { + LOG_WARN_NEW("readLocalOffset Exception {}", e.what()); + THROW_MQEXCEPTION(MQClientException, "readLocalOffset Exception", -1); + } + } + } + return offsetTable; +} + +} // namespace rocketmq diff --git a/src/consumer/LocalFileOffsetStore.h b/src/consumer/LocalFileOffsetStore.h new file mode 100644 index 000000000..c517fb4ca --- /dev/null +++ b/src/consumer/LocalFileOffsetStore.h @@ -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. + */ +#ifndef ROCKETMQ_CONSUMER_LOCALFILEOFFSETSTORE_H_ +#define ROCKETMQ_CONSUMER_LOCALFILEOFFSETSTORE_H_ + +#include // std::map +#include // std::mutex + +#include "MQClientInstance.h" +#include "OffsetStore.h" + +namespace rocketmq { + +class LocalFileOffsetStore : public OffsetStore { + public: + LocalFileOffsetStore(MQClientInstance* instance, const std::string& groupName); + virtual ~LocalFileOffsetStore(); + + void load() override; + void updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) override; + int64_t readOffset(const MQMessageQueue& mq, ReadOffsetType type) override; + void persist(const MQMessageQueue& mq) override; + void persistAll(const std::vector& mq) override; + void removeOffset(const MQMessageQueue& mq) override; + + private: + std::map readLocalOffset(); + std::map readLocalOffsetBak(); + + private: + MQClientInstance* client_instance_; + std::string group_name_; + + std::map offset_table_; + std::mutex lock_; + + std::string store_path_; + std::mutex file_mutex_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_CONSUMER_LOCALFILEOFFSETSTORE_H_ diff --git a/src/consumer/MQConsumerInner.h b/src/consumer/MQConsumerInner.h index 2daf98ef9..31a126b85 100644 --- a/src/consumer/MQConsumerInner.h +++ b/src/consumer/MQConsumerInner.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_CONSUMER_INNER_H__ -#define __MQ_CONSUMER_INNER_H__ +#ifndef ROCKETMQ_CONSUMER_MQCONSUMERINNER_H_ +#define ROCKETMQ_CONSUMER_MQCONSUMERINNER_H_ #include #include @@ -41,9 +41,10 @@ class MQConsumerInner { virtual void doRebalance() = 0; virtual void persistConsumerOffset() = 0; virtual void updateTopicSubscribeInfo(const std::string& topic, std::vector& info) = 0; + virtual ConsumerRunningInfo* consumerRunningInfo() = 0; }; } // namespace rocketmq -#endif // __MQ_CONSUMER_INNER_H__ +#endif // ROCKETMQ_CONSUMER_MQCONSUMERINNER_H_ diff --git a/src/consumer/MessageQueueLock.hpp b/src/consumer/MessageQueueLock.hpp index e43fab720..acdcd9d74 100644 --- a/src/consumer/MessageQueueLock.hpp +++ b/src/consumer/MessageQueueLock.hpp @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MESSAGE_QUEUE_LOCK__ -#define __MESSAGE_QUEUE_LOCK__ +#ifndef ROCKETMQ_CONSUMER_MESSAGEQUEUELOCK_HPP_ +#define ROCKETMQ_CONSUMER_MESSAGEQUEUELOCK_HPP_ #include #include @@ -31,20 +31,20 @@ namespace rocketmq { class MessageQueueLock { public: std::shared_ptr fetchLockObject(const MQMessageQueue& mq) { - std::lock_guard lock(m_mqLockTableMutex); - const auto& it = m_mqLockTable.find(mq); - if (it != m_mqLockTable.end()) { + std::lock_guard lock(mq_lock_table_mutex_); + const auto& it = mq_lock_table_.find(mq); + if (it != mq_lock_table_.end()) { return it->second; } else { - return m_mqLockTable[mq] = std::make_shared(); + return mq_lock_table_[mq] = std::make_shared(); } } private: - std::map> m_mqLockTable; - std::mutex m_mqLockTableMutex; + std::map> mq_lock_table_; + std::mutex mq_lock_table_mutex_; }; } // namespace rocketmq -#endif // __MESSAGE_QUEUE_LOCK__ +#endif // ROCKETMQ_CONSUMER_MESSAGEQUEUELOCK_HPP_ diff --git a/src/consumer/OffsetStore.cpp b/src/consumer/OffsetStore.cpp deleted file mode 100644 index 55305cf84..000000000 --- a/src/consumer/OffsetStore.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/* - * 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 - -#include "Logging.h" -#include "MQClientAPIImpl.h" -#include "MQClientInstance.h" -#include "MessageQueue.h" -#include "UtilAll.h" - -namespace rocketmq { - -//###################################### -// LocalFileOffsetStore -//###################################### - -LocalFileOffsetStore::LocalFileOffsetStore(MQClientInstance* instance, const std::string& groupName) - : m_clientInstance(instance), m_groupName(groupName) { - LOG_INFO("new LocalFileOffsetStore"); - - std::string clientId = instance->getClientId(); - std::string homeDir(UtilAll::getHomeDirectory()); - std::string storeDir = - homeDir + FILE_SEPARATOR + ".rocketmq_offsets" + FILE_SEPARATOR + clientId + FILE_SEPARATOR + groupName; - m_storePath = storeDir + FILE_SEPARATOR + "offsets.json"; - - if (!UtilAll::existDirectory(storeDir)) { - UtilAll::createDirectory(storeDir); - if (!UtilAll::existDirectory(storeDir)) { - LOG_ERROR("create offset store dir:%s error", storeDir.c_str()); - std::string errorMsg("create offset store dir failed: "); - errorMsg.append(storeDir); - THROW_MQEXCEPTION(MQClientException, errorMsg, -1); - } - } -} - -LocalFileOffsetStore::~LocalFileOffsetStore() { - m_clientInstance = nullptr; - m_offsetTable.clear(); -} - -void LocalFileOffsetStore::load() { - auto offsetTable = readLocalOffset(); - if (!offsetTable.empty()) { - // update offsetTable - { - std::lock_guard lock(m_lock); - m_offsetTable = offsetTable; - } - - for (const auto& it : offsetTable) { - const auto& mq = it.first; - const auto offset = it.second; - LOG_INFO_NEW("load consumer's offset, {} {} {}", m_groupName, mq.toString(), offset); - } - } -} - -void LocalFileOffsetStore::updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) { - std::lock_guard lock(m_lock); - m_offsetTable[mq] = offset; -} - -int64_t LocalFileOffsetStore::readOffset(const MQMessageQueue& mq, ReadOffsetType type) { - switch (type) { - case MEMORY_FIRST_THEN_STORE: - case READ_FROM_MEMORY: { - std::lock_guard lock(m_lock); - const auto& it = m_offsetTable.find(mq); - if (it != m_offsetTable.end()) { - return it->second; - } else if (READ_FROM_MEMORY == type) { - return -1; - } - } break; - case READ_FROM_STORE: { - auto offsetTable = readLocalOffset(); - if (!offsetTable.empty()) { - const auto& it = offsetTable.find(mq); - if (it != offsetTable.end()) { - auto offset = it->second; - updateOffset(mq, offset, false); - return offset; - } - } - } break; - default: - break; - } - LOG_ERROR("can not readOffset from offsetStore.json, maybe first time consumation"); - return -1; -} - -void LocalFileOffsetStore::persist(const MQMessageQueue& mq) {} - -void LocalFileOffsetStore::persistAll(const std::vector& mqs) { - if (mqs.empty()) { - return; - } - - std::map offsetTable; - { - std::lock_guard lock(m_lock); - offsetTable = m_offsetTable; - } - - Json::Value root(Json::objectValue); - Json::Value jOffsetTable(Json::objectValue); - for (const auto& mq : mqs) { - const auto& it = offsetTable.find(mq); - if (it != offsetTable.end()) { - std::string strMQ = RemotingSerializable::toJson(toJson(mq)); - jOffsetTable[strMQ] = Json::Value((Json::Int64)it->second); - } - } - root["offsetTable"] = jOffsetTable; - - std::lock_guard lock2(m_fileMutex); - std::string storePathTmp = m_storePath + ".tmp"; - std::ofstream ofstrm(storePathTmp, std::ios::binary | std::ios::out); - if (ofstrm.is_open()) { - try { - RemotingSerializable::toJson(root, ofstrm, true); - } catch (std::exception& e) { - THROW_MQEXCEPTION(MQClientException, "persistAll failed", -1); - } - - if (!UtilAll::ReplaceFile(m_storePath, m_storePath + ".bak") || !UtilAll::ReplaceFile(storePathTmp, m_storePath)) { - LOG_ERROR("could not rename file: %s", strerror(errno)); - } - } -} - -void LocalFileOffsetStore::removeOffset(const MQMessageQueue& mq) {} - -std::map LocalFileOffsetStore::readLocalOffset() { - std::lock_guard lock(m_fileMutex); - std::ifstream ifstrm(m_storePath, std::ios::binary | std::ios::in); - if (ifstrm.is_open() && !ifstrm.eof()) { - try { - Json::Value root = RemotingSerializable::fromJson(ifstrm); - std::map offsetTable; - auto& jOffsetTable = root["offsetTable"]; - for (auto& strMQ : jOffsetTable.getMemberNames()) { - auto& offset = jOffsetTable[strMQ]; - Json::Value jMQ = RemotingSerializable::fromJson(strMQ); - MQMessageQueue mq(jMQ["topic"].asString(), jMQ["brokerName"].asString(), jMQ["queueId"].asInt()); - offsetTable.emplace(std::move(mq), offset.asInt64()); - } - return offsetTable; - } catch (std::exception& e) { - // ... - } - } - return readLocalOffsetBak(); -} - -std::map LocalFileOffsetStore::readLocalOffsetBak() { - std::map offsetTable; - std::ifstream ifstrm(m_storePath + ".bak", std::ios::binary | std::ios::in); - if (ifstrm.is_open()) { - if (!ifstrm.eof()) { - try { - Json::Value root = RemotingSerializable::fromJson(ifstrm); - auto& jOffsetTable = root["offsetTable"]; - for (auto& strMQ : jOffsetTable.getMemberNames()) { - auto& offset = jOffsetTable[strMQ]; - Json::Value jMQ = RemotingSerializable::fromJson(strMQ); - MQMessageQueue mq(jMQ["topic"].asString(), jMQ["brokerName"].asString(), jMQ["queueId"].asInt()); - offsetTable.emplace(std::move(mq), offset.asInt64()); - } - } catch (const std::exception& e) { - LOG_WARN_NEW("readLocalOffset Exception {}", e.what()); - THROW_MQEXCEPTION(MQClientException, "readLocalOffset Exception", -1); - } - } - } - return offsetTable; -} - -//###################################### -// RemoteBrokerOffsetStore -//###################################### - -RemoteBrokerOffsetStore::RemoteBrokerOffsetStore(MQClientInstance* instance, const std::string& groupName) - : m_clientInstance(instance), m_groupName(groupName) {} - -RemoteBrokerOffsetStore::~RemoteBrokerOffsetStore() { - m_clientInstance = nullptr; - m_offsetTable.clear(); -} - -void RemoteBrokerOffsetStore::load() {} - -void RemoteBrokerOffsetStore::updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) { - std::lock_guard lock(m_lock); - const auto& it = m_offsetTable.find(mq); - if (it == m_offsetTable.end() || !increaseOnly || offset > it->second) { - m_offsetTable[mq] = offset; - } -} - -int64_t RemoteBrokerOffsetStore::readOffset(const MQMessageQueue& mq, ReadOffsetType type) { - switch (type) { - case MEMORY_FIRST_THEN_STORE: - case READ_FROM_MEMORY: { - std::lock_guard lock(m_lock); - - const auto& 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_t brokerOffset = fetchConsumeOffsetFromBroker(mq); - // update - updateOffset(mq, brokerOffset, false); - return brokerOffset; - } catch (MQBrokerException& e) { - LOG_ERROR(e.what()); - return -1; - } catch (MQException& e) { - LOG_ERROR(e.what()); - return -2; - } - } - default: - break; - } - return -1; -} - -void RemoteBrokerOffsetStore::persist(const MQMessageQueue& mq) { - std::map offsetTable; - { - std::lock_guard lock(m_lock); - offsetTable = m_offsetTable; - } - - const auto& it = offsetTable.find(mq); - if (it != offsetTable.end()) { - try { - updateConsumeOffsetToBroker(mq, it->second); - } catch (MQException& e) { - LOG_ERROR("updateConsumeOffsetToBroker error"); - } - } -} - -void RemoteBrokerOffsetStore::persistAll(const std::vector& mq) {} - -void RemoteBrokerOffsetStore::removeOffset(const MQMessageQueue& mq) { - std::lock_guard lock(m_lock); - const auto& it = m_offsetTable.find(mq); - if (it != m_offsetTable.end()) { - m_offsetTable.erase(it); - } -} - -void RemoteBrokerOffsetStore::updateConsumeOffsetToBroker(const MQMessageQueue& mq, int64_t offset) { - std::unique_ptr findBrokerResult(m_clientInstance->findBrokerAddressInAdmin(mq.getBrokerName())); - - if (findBrokerResult == nullptr) { - m_clientInstance->updateTopicRouteInfoFromNameServer(mq.getTopic()); - findBrokerResult.reset(m_clientInstance->findBrokerAddressInAdmin(mq.getBrokerName())); - } - - if (findBrokerResult != nullptr) { - UpdateConsumerOffsetRequestHeader* requestHeader = new UpdateConsumerOffsetRequestHeader(); - requestHeader->topic = mq.getTopic(); - requestHeader->consumerGroup = m_groupName; - requestHeader->queueId = mq.getQueueId(); - requestHeader->commitOffset = offset; - - try { - LOG_INFO("oneway updateConsumeOffsetToBroker of mq:%s, its offset is:%lld", mq.toString().c_str(), offset); - return m_clientInstance->getMQClientAPIImpl()->updateConsumerOffsetOneway(findBrokerResult->brokerAddr, - requestHeader, 1000 * 5); - } catch (MQException& e) { - LOG_ERROR(e.what()); - } - } - LOG_WARN("The broker not exist"); -} - -int64_t RemoteBrokerOffsetStore::fetchConsumeOffsetFromBroker(const MQMessageQueue& mq) { - std::unique_ptr findBrokerResult(m_clientInstance->findBrokerAddressInAdmin(mq.getBrokerName())); - - if (findBrokerResult == nullptr) { - m_clientInstance->updateTopicRouteInfoFromNameServer(mq.getTopic()); - findBrokerResult.reset(m_clientInstance->findBrokerAddressInAdmin(mq.getBrokerName())); - } - - if (findBrokerResult != nullptr) { - QueryConsumerOffsetRequestHeader* requestHeader = new QueryConsumerOffsetRequestHeader(); - requestHeader->topic = mq.getTopic(); - requestHeader->consumerGroup = m_groupName; - requestHeader->queueId = mq.getQueueId(); - - return m_clientInstance->getMQClientAPIImpl()->queryConsumerOffset(findBrokerResult->brokerAddr, requestHeader, - 1000 * 5); - } else { - LOG_ERROR("The broker not exist when fetchConsumeOffsetFromBroker"); - THROW_MQEXCEPTION(MQClientException, "The broker not exist", -1); - } -} - -} // namespace rocketmq diff --git a/src/consumer/OffsetStore.h b/src/consumer/OffsetStore.h deleted file mode 100644 index bbabfff7a..000000000 --- a/src/consumer/OffsetStore.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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 __OFFSET_STORE_H__ -#define __OFFSET_STORE_H__ - -#include -#include -#include - -#include "MQClientInstance.h" -#include "MQMessageQueue.h" - -namespace rocketmq { - -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: - virtual ~OffsetStore() = default; - - virtual void load() = 0; - virtual void updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) = 0; - virtual int64_t readOffset(const MQMessageQueue& mq, ReadOffsetType type) = 0; - virtual void persist(const MQMessageQueue& mq) = 0; - virtual void persistAll(const std::vector& mq) = 0; - virtual void removeOffset(const MQMessageQueue& mq) = 0; -}; - -class LocalFileOffsetStore : public OffsetStore { - public: - LocalFileOffsetStore(MQClientInstance* instance, const std::string& groupName); - virtual ~LocalFileOffsetStore(); - - void load() override; - void updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) override; - int64_t readOffset(const MQMessageQueue& mq, ReadOffsetType type) override; - void persist(const MQMessageQueue& mq) override; - void persistAll(const std::vector& mq) override; - void removeOffset(const MQMessageQueue& mq) override; - - private: - std::map readLocalOffset(); - std::map readLocalOffsetBak(); - - private: - MQClientInstance* m_clientInstance; - std::string m_groupName; - - std::map m_offsetTable; - std::mutex m_lock; - - std::string m_storePath; - std::mutex m_fileMutex; -}; - -class RemoteBrokerOffsetStore : public OffsetStore { - public: - RemoteBrokerOffsetStore(MQClientInstance* instance, const std::string& groupName); - virtual ~RemoteBrokerOffsetStore(); - - void load() override; - void updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) override; - int64_t readOffset(const MQMessageQueue& mq, ReadOffsetType type) override; - void persist(const MQMessageQueue& mq) override; - void persistAll(const std::vector& mq) override; - void removeOffset(const MQMessageQueue& mq) override; - - private: - void updateConsumeOffsetToBroker(const MQMessageQueue& mq, int64_t offset); - int64_t fetchConsumeOffsetFromBroker(const MQMessageQueue& mq); - - private: - MQClientInstance* m_clientInstance; - std::string m_groupName; - - std::map m_offsetTable; - std::mutex m_lock; -}; - -} // namespace rocketmq - -#endif // __OFFSET_STORE_H__ diff --git a/src/consumer/ProcessQueue.cpp b/src/consumer/ProcessQueue.cpp index 285caed4d..dee12f325 100644 --- a/src/consumer/ProcessQueue.cpp +++ b/src/consumer/ProcessQueue.cpp @@ -20,65 +20,66 @@ #include "ProcessQueueInfo.h" #include "UtilAll.h" +static const uint64_t PULL_MAX_IDLE_TIME = 120000; // ms + namespace rocketmq { -const uint64_t ProcessQueue::RebalanceLockMaxLiveTime = 30000; -const uint64_t ProcessQueue::RebalanceLockInterval = 20000; -const uint64_t ProcessQueue::PullMaxIdleTime = 120000; +const uint64_t ProcessQueue::REBALANCE_LOCK_MAX_LIVE_TIME = 30000; +const uint64_t ProcessQueue::REBALANCE_LOCK_INTERVAL = 20000; ProcessQueue::ProcessQueue() - : m_queueOffsetMax(0), - m_dropped(false), - m_lastPullTimestamp(UtilAll::currentTimeMillis()), - m_lastConsumeTimestamp(UtilAll::currentTimeMillis()), - m_locked(false), - m_lastLockTimestamp(UtilAll::currentTimeMillis()) {} + : queue_offset_max_(0), + dropped_(false), + last_pull_timestamp_(UtilAll::currentTimeMillis()), + last_consume_timestamp_(UtilAll::currentTimeMillis()), + locked_(false), + last_lock_timestamp_(UtilAll::currentTimeMillis()) {} ProcessQueue::~ProcessQueue() { - m_msgTreeMap.clear(); - m_consumingMsgOrderlyTreeMap.clear(); + msg_tree_map_.clear(); + consuming_msg_orderly_tree_map_.clear(); } bool ProcessQueue::isLockExpired() const { - return (UtilAll::currentTimeMillis() - m_lastLockTimestamp) > RebalanceLockMaxLiveTime; + return (UtilAll::currentTimeMillis() - last_lock_timestamp_) > REBALANCE_LOCK_MAX_LIVE_TIME; } bool ProcessQueue::isPullExpired() const { - return (UtilAll::currentTimeMillis() - m_lastPullTimestamp) > PullMaxIdleTime; + return (UtilAll::currentTimeMillis() - last_pull_timestamp_) > PULL_MAX_IDLE_TIME; } void ProcessQueue::putMessage(const std::vector& msgs) { - std::lock_guard lock(m_lockTreeMap); + std::lock_guard lock(lock_tree_map_); for (const auto& msg : msgs) { int64_t offset = msg->getQueueOffset(); - m_msgTreeMap[offset] = msg; - if (offset > m_queueOffsetMax) { - m_queueOffsetMax = offset; + msg_tree_map_[offset] = msg; + if (offset > queue_offset_max_) { + queue_offset_max_ = offset; } } - LOG_DEBUG_NEW("ProcessQueue: putMessage m_queueOffsetMax:{}", m_queueOffsetMax); + LOG_DEBUG_NEW("ProcessQueue: putMessage queue_offset_max:{}", queue_offset_max_); } int64_t ProcessQueue::removeMessage(const std::vector& msgs) { int64_t result = -1; const auto now = UtilAll::currentTimeMillis(); - std::lock_guard lock(m_lockTreeMap); - m_lastConsumeTimestamp = now; + std::lock_guard lock(lock_tree_map_); + last_consume_timestamp_ = now; - if (!m_msgTreeMap.empty()) { - result = m_queueOffsetMax + 1; - LOG_DEBUG_NEW("offset result is:{}, m_queueOffsetMax is:{}, msgs size:{}", result, m_queueOffsetMax, msgs.size()); + if (!msg_tree_map_.empty()) { + result = queue_offset_max_ + 1; + LOG_DEBUG_NEW("offset result is:{}, queue_offset_max is:{}, msgs size:{}", result, queue_offset_max_, msgs.size()); for (auto& msg : msgs) { - LOG_DEBUG_NEW("remove these msg from m_msgTreeMap, its offset:{}", msg->getQueueOffset()); - m_msgTreeMap.erase(msg->getQueueOffset()); + LOG_DEBUG_NEW("remove these msg from msg_tree_map, its offset:{}", msg->getQueueOffset()); + msg_tree_map_.erase(msg->getQueueOffset()); } - if (!m_msgTreeMap.empty()) { - auto it = m_msgTreeMap.begin(); + if (!msg_tree_map_.empty()) { + auto it = msg_tree_map_.begin(); result = it->first; } } @@ -87,44 +88,30 @@ int64_t ProcessQueue::removeMessage(const std::vector& msgs) { } int ProcessQueue::getCacheMsgCount() { - std::lock_guard lock(m_lockTreeMap); - return static_cast(m_msgTreeMap.size()); + std::lock_guard lock(lock_tree_map_); + return static_cast(msg_tree_map_.size() + consuming_msg_orderly_tree_map_.size()); } int64_t ProcessQueue::getCacheMinOffset() { - std::lock_guard lock(m_lockTreeMap); - if (m_msgTreeMap.empty()) { + std::lock_guard lock(lock_tree_map_); + if (msg_tree_map_.empty() && consuming_msg_orderly_tree_map_.empty()) { return 0; + } else if (!consuming_msg_orderly_tree_map_.empty()) { + return consuming_msg_orderly_tree_map_.begin()->first; } else { - return m_msgTreeMap.begin()->first; + return msg_tree_map_.begin()->first; } } int64_t ProcessQueue::getCacheMaxOffset() { - return m_queueOffsetMax; -} - -bool ProcessQueue::isDropped() const { - return m_dropped.load(); -} - -void ProcessQueue::setDropped(bool dropped) { - m_dropped.store(dropped); -} - -bool ProcessQueue::isLocked() const { - return m_locked.load(); -} - -void ProcessQueue::setLocked(bool locked) { - m_locked.store(locked); + return queue_offset_max_; } int64_t ProcessQueue::commit() { - std::lock_guard lock(m_lockTreeMap); - if (!m_consumingMsgOrderlyTreeMap.empty()) { - int64_t offset = (--m_consumingMsgOrderlyTreeMap.end())->first; - m_consumingMsgOrderlyTreeMap.clear(); + std::lock_guard lock(lock_tree_map_); + if (!consuming_msg_orderly_tree_map_.empty()) { + int64_t offset = (--consuming_msg_orderly_tree_map_.end())->first; + consuming_msg_orderly_tree_map_.clear(); return offset + 1; } else { return -1; @@ -132,94 +119,55 @@ int64_t ProcessQueue::commit() { } void ProcessQueue::makeMessageToCosumeAgain(std::vector& msgs) { - std::lock_guard lock(m_lockTreeMap); + std::lock_guard lock(lock_tree_map_); for (const auto& msg : msgs) { - m_msgTreeMap[msg->getQueueOffset()] = msg; - m_consumingMsgOrderlyTreeMap.erase(msg->getQueueOffset()); + msg_tree_map_[msg->getQueueOffset()] = msg; + consuming_msg_orderly_tree_map_.erase(msg->getQueueOffset()); } } void ProcessQueue::takeMessages(std::vector& out_msgs, int batchSize) { - std::lock_guard lock(m_lockTreeMap); - for (int i = 0; i != batchSize; i++) { - const auto& it = m_msgTreeMap.begin(); - if (it != m_msgTreeMap.end()) { - out_msgs.push_back(it->second); - m_consumingMsgOrderlyTreeMap[it->first] = it->second; - m_msgTreeMap.erase(it); - } + std::lock_guard lock(lock_tree_map_); + for (auto it = msg_tree_map_.begin(); it != msg_tree_map_.end() && batchSize--;) { + out_msgs.push_back(it->second); + consuming_msg_orderly_tree_map_[it->first] = it->second; + it = msg_tree_map_.erase(it); } } void ProcessQueue::clearAllMsgs() { - std::lock_guard lock(m_lockTreeMap); + std::lock_guard lock(lock_tree_map_); - if (isDropped()) { - LOG_DEBUG_NEW("clear m_msgTreeMap as PullRequest had been dropped."); - m_msgTreeMap.clear(); - m_consumingMsgOrderlyTreeMap.clear(); - m_queueOffsetMax = 0; + if (dropped()) { + LOG_DEBUG_NEW("clear msg_tree_map as PullRequest had been dropped."); + msg_tree_map_.clear(); + consuming_msg_orderly_tree_map_.clear(); + queue_offset_max_ = 0; } } -uint64_t ProcessQueue::getLastLockTimestamp() const { - return m_lastLockTimestamp; -} - -void ProcessQueue::setLastLockTimestamp(int64_t lastLockTimestamp) { - m_lastLockTimestamp = lastLockTimestamp; -} - -std::timed_mutex& ProcessQueue::getLockConsume() { - return m_lockConsume; -} - -uint64_t ProcessQueue::getLastPullTimestamp() const { - return m_lastPullTimestamp; -} - -void ProcessQueue::setLastPullTimestamp(uint64_t lastPullTimestamp) { - m_lastPullTimestamp = lastPullTimestamp; -} - -long ProcessQueue::getTryUnlockTimes() { - return m_tryUnlockTimes.load(); -} - -void ProcessQueue::incTryUnlockTimes() { - m_tryUnlockTimes.fetch_add(1); -} - -uint64_t ProcessQueue::getLastConsumeTimestamp() { - return m_lastConsumeTimestamp; -} - -void ProcessQueue::setLastConsumeTimestamp(uint64_t lastConsumeTimestamp) { - m_lastConsumeTimestamp = lastConsumeTimestamp; -} - void ProcessQueue::fillProcessQueueInfo(ProcessQueueInfo& info) { - std::lock_guard lock(m_lockTreeMap); + std::lock_guard lock(lock_tree_map_); - if (!m_msgTreeMap.empty()) { - info.cachedMsgMinOffset = m_msgTreeMap.begin()->first; - info.cachedMsgMaxOffset = m_queueOffsetMax; - info.cachedMsgCount = m_msgTreeMap.size(); + if (!msg_tree_map_.empty()) { + info.cachedMsgMinOffset = msg_tree_map_.begin()->first; + info.cachedMsgMaxOffset = queue_offset_max_; + info.cachedMsgCount = msg_tree_map_.size(); } - if (!m_consumingMsgOrderlyTreeMap.empty()) { - info.transactionMsgMinOffset = m_consumingMsgOrderlyTreeMap.begin()->first; - info.transactionMsgMaxOffset = (--m_consumingMsgOrderlyTreeMap.end())->first; - info.transactionMsgCount = m_consumingMsgOrderlyTreeMap.size(); + if (!consuming_msg_orderly_tree_map_.empty()) { + info.transactionMsgMinOffset = consuming_msg_orderly_tree_map_.begin()->first; + info.transactionMsgMaxOffset = (--consuming_msg_orderly_tree_map_.end())->first; + info.transactionMsgCount = consuming_msg_orderly_tree_map_.size(); } - info.setLocked(m_locked); - info.tryUnlockTimes = m_tryUnlockTimes.load(); - info.lastLockTimestamp = m_lastLockTimestamp; + info.setLocked(locked_); + info.tryUnlockTimes = try_unlock_times_.load(); + info.lastLockTimestamp = last_lock_timestamp_; - info.setDroped(m_dropped); - info.lastPullTimestamp = m_lastPullTimestamp; - info.lastConsumeTimestamp = m_lastConsumeTimestamp; + info.setDroped(dropped_); + info.lastPullTimestamp = last_pull_timestamp_; + info.lastConsumeTimestamp = last_consume_timestamp_; } } // namespace rocketmq diff --git a/src/consumer/ProcessQueue.h b/src/consumer/ProcessQueue.h index e2780ed8c..37ce7ed50 100644 --- a/src/consumer/ProcessQueue.h +++ b/src/consumer/ProcessQueue.h @@ -14,14 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __PROCESS_QUEUE_H__ -#define __PROCESS_QUEUE_H__ +#ifndef ROCKETMQ_CONSUMER_PROCESSQUEUE_H_ +#define ROCKETMQ_CONSUMER_PROCESSQUEUE_H_ -#include -#include -#include -#include -#include +#include // std::atomic +#include // std::map +#include // std::shared_ptr +#include // std::mutex +#include // std::vector #include "MessageExt.h" @@ -34,8 +34,8 @@ typedef std::shared_ptr ProcessQueuePtr; class ROCKETMQCLIENT_API ProcessQueue { public: - static const uint64_t RebalanceLockMaxLiveTime; // ms - static const uint64_t RebalanceLockInterval; // ms + static const uint64_t REBALANCE_LOCK_MAX_LIVE_TIME; // ms + static const uint64_t REBALANCE_LOCK_INTERVAL; // ms public: ProcessQueue(); @@ -51,51 +51,51 @@ class ROCKETMQCLIENT_API ProcessQueue { int64_t getCacheMinOffset(); int64_t getCacheMaxOffset(); - bool isDropped() const; - void setDropped(bool dropped); - - bool isLocked() const; - void setLocked(bool locked); - int64_t commit(); void makeMessageToCosumeAgain(std::vector& msgs); void takeMessages(std::vector& out_msgs, int batchSize); void clearAllMsgs(); - uint64_t getLastLockTimestamp() const; - void setLastLockTimestamp(int64_t lastLockTimestamp); + void fillProcessQueueInfo(ProcessQueueInfo& info); - std::timed_mutex& getLockConsume(); + public: + inline std::timed_mutex& lock_consume() { return lock_consume_; } - uint64_t getLastPullTimestamp() const; - void setLastPullTimestamp(uint64_t lastPullTimestamp); + inline long try_unlock_times() const { return try_unlock_times_.load(); } + inline void inc_try_unlock_times() { try_unlock_times_.fetch_add(1); } - long getTryUnlockTimes(); - void incTryUnlockTimes(); + inline bool dropped() const { return dropped_.load(); } + inline void set_dropped(bool dropped) { dropped_.store(dropped); } - uint64_t getLastConsumeTimestamp(); - void setLastConsumeTimestamp(uint64_t lastConsumeTimestamp); + inline uint64_t last_pull_timestamp() const { return last_pull_timestamp_; } + inline void set_last_pull_timestamp(uint64_t lastPullTimestamp) { last_pull_timestamp_ = lastPullTimestamp; } - void fillProcessQueueInfo(ProcessQueueInfo& info); + inline uint64_t last_consume_timestamp() const { return last_consume_timestamp_; } + inline void set_last_consume_timestamp(uint64_t lastConsumeTimestamp) { + last_consume_timestamp_ = lastConsumeTimestamp; + } - private: - static const uint64_t PullMaxIdleTime; + inline bool locked() const { return locked_.load(); } + inline void set_locked(bool locked) { locked_.store(locked); } + + inline uint64_t last_lock_timestamp() const { return last_lock_timestamp_; } + inline void set_last_lock_timestamp(int64_t lastLockTimestamp) { last_lock_timestamp_ = lastLockTimestamp; } private: - std::mutex m_lockTreeMap; - std::map m_msgTreeMap; - std::timed_mutex m_lockConsume; - std::map m_consumingMsgOrderlyTreeMap; - std::atomic m_tryUnlockTimes; - volatile int64_t m_queueOffsetMax; - std::atomic m_dropped; - volatile uint64_t m_lastPullTimestamp; - volatile uint64_t m_lastConsumeTimestamp; - std::atomic m_locked; - volatile uint64_t m_lastLockTimestamp; // ms + std::mutex lock_tree_map_; + std::map msg_tree_map_; + std::timed_mutex lock_consume_; + std::map consuming_msg_orderly_tree_map_; + std::atomic try_unlock_times_; + volatile int64_t queue_offset_max_; + std::atomic dropped_; + volatile uint64_t last_pull_timestamp_; + volatile uint64_t last_consume_timestamp_; + std::atomic locked_; + volatile uint64_t last_lock_timestamp_; // ms }; } // namespace rocketmq -#endif // __PROCESS_QUEUE_H__ +#endif // ROCKETMQ_CONSUMER_PROCESSQUEUE_H_ diff --git a/src/consumer/PullAPIWrapper.cpp b/src/consumer/PullAPIWrapper.cpp index 221f2856b..96a9a8fb8 100644 --- a/src/consumer/PullAPIWrapper.cpp +++ b/src/consumer/PullAPIWrapper.cpp @@ -20,31 +20,31 @@ #include "MQClientAPIImpl.h" #include "MQClientInstance.h" #include "MessageDecoder.h" -#include "MessageAccessor.h" -#include "PullResultExt.h" +#include "MessageAccessor.hpp" +#include "PullResultExt.hpp" #include "PullSysFlag.h" namespace rocketmq { PullAPIWrapper::PullAPIWrapper(MQClientInstance* instance, const std::string& consumerGroup) { - m_clientInstance = instance; - m_consumerGroup = consumerGroup; + client_instance_ = instance; + consumer_group_ = consumerGroup; } PullAPIWrapper::~PullAPIWrapper() { - m_clientInstance = nullptr; - m_pullFromWhichNodeTable.clear(); + client_instance_ = nullptr; + pull_from_which_node_table_.clear(); } void PullAPIWrapper::updatePullFromWhichNode(const MQMessageQueue& mq, int brokerId) { - std::lock_guard lock(m_lock); - m_pullFromWhichNodeTable[mq] = brokerId; + std::lock_guard lock(lock_); + pull_from_which_node_table_[mq] = brokerId; } int PullAPIWrapper::recalculatePullFromWhichNode(const MQMessageQueue& mq) { - std::lock_guard lock(m_lock); - const auto& it = m_pullFromWhichNodeTable.find(mq); - if (it != m_pullFromWhichNodeTable.end()) { + std::lock_guard lock(lock_); + const auto& it = pull_from_which_node_table_.find(mq); + if (it != pull_from_which_node_table_.end()) { return it->second; } return MASTER_ID; @@ -52,7 +52,7 @@ int PullAPIWrapper::recalculatePullFromWhichNode(const MQMessageQueue& mq) { PullResult PullAPIWrapper::processPullResult(const MQMessageQueue& mq, PullResult& pullResult, - SubscriptionDataPtr subscriptionData) { + SubscriptionData* subscriptionData) { assert(std::type_index(typeid(pullResult)) == std::type_index(typeid(PullResultExt))); auto& pullResultExt = dynamic_cast(pullResult); @@ -66,11 +66,11 @@ PullResult PullAPIWrapper::processPullResult(const MQMessageQueue& mq, auto msgList = MessageDecoder::decodes(*byteBuffer); // filter msg list again - if (subscriptionData != nullptr && !subscriptionData->getTagsSet().empty()) { + if (subscriptionData != nullptr && !subscriptionData->tags_set().empty()) { msgListFilterAgain.reserve(msgList.size()); for (const auto& msg : msgList) { const auto& msgTag = msg->getTags(); - if (subscriptionData->containTag(msgTag)) { + if (subscriptionData->contain_tag(msgTag)) { msgListFilterAgain.push_back(msg); } } @@ -106,24 +106,24 @@ PullResult* PullAPIWrapper::pullKernelImpl(const MQMessageQueue& mq, CommunicationMode communicationMode, // 10 PullCallback* pullCallback) { std::unique_ptr findBrokerResult( - m_clientInstance->findBrokerAddressInSubscribe(mq.getBrokerName(), recalculatePullFromWhichNode(mq), false)); + client_instance_->findBrokerAddressInSubscribe(mq.broker_name(), recalculatePullFromWhichNode(mq), false)); if (findBrokerResult == nullptr) { - m_clientInstance->updateTopicRouteInfoFromNameServer(mq.getTopic()); + client_instance_->updateTopicRouteInfoFromNameServer(mq.topic()); findBrokerResult.reset( - m_clientInstance->findBrokerAddressInSubscribe(mq.getBrokerName(), recalculatePullFromWhichNode(mq), false)); + client_instance_->findBrokerAddressInSubscribe(mq.broker_name(), recalculatePullFromWhichNode(mq), false)); } if (findBrokerResult != nullptr) { int sysFlagInner = sysFlag; - if (findBrokerResult->slave) { + if (findBrokerResult->slave()) { sysFlagInner = PullSysFlag::clearCommitOffsetFlag(sysFlagInner); } PullMessageRequestHeader* pRequestHeader = new PullMessageRequestHeader(); - pRequestHeader->consumerGroup = m_consumerGroup; - pRequestHeader->topic = mq.getTopic(); - pRequestHeader->queueId = mq.getQueueId(); + pRequestHeader->consumerGroup = consumer_group_; + pRequestHeader->topic = mq.topic(); + pRequestHeader->queueId = mq.queue_id(); pRequestHeader->queueOffset = offset; pRequestHeader->maxMsgNums = maxNums; pRequestHeader->sysFlag = sysFlagInner; @@ -132,11 +132,11 @@ PullResult* PullAPIWrapper::pullKernelImpl(const MQMessageQueue& mq, pRequestHeader->subscription = subExpression; pRequestHeader->subVersion = subVersion; - return m_clientInstance->getMQClientAPIImpl()->pullMessage(findBrokerResult->brokerAddr, pRequestHeader, + return client_instance_->getMQClientAPIImpl()->pullMessage(findBrokerResult->broker_addr(), pRequestHeader, timeoutMillis, communicationMode, pullCallback); } - THROW_MQEXCEPTION(MQClientException, "The broker [" + mq.getBrokerName() + "] not exist", -1); + THROW_MQEXCEPTION(MQClientException, "The broker [" + mq.broker_name() + "] not exist", -1); } } // namespace rocketmq diff --git a/src/consumer/PullAPIWrapper.h b/src/consumer/PullAPIWrapper.h index ce8f5c0a9..02055d02c 100644 --- a/src/consumer/PullAPIWrapper.h +++ b/src/consumer/PullAPIWrapper.h @@ -14,10 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __PULL_API_WRAPPER_H__ -#define __PULL_API_WRAPPER_H__ +#ifndef ROCKETMQ_CONSUMER_PULLAPIWRAPPER_H_ +#define ROCKETMQ_CONSUMER_PULLAPIWRAPPER_H_ -#include +#include // std::mutex #include "CommunicationMode.h" #include "MQClientInstance.h" @@ -32,7 +32,7 @@ class PullAPIWrapper { PullAPIWrapper(MQClientInstance* instance, const std::string& consumerGroup); ~PullAPIWrapper(); - PullResult processPullResult(const MQMessageQueue& mq, PullResult& pullResult, SubscriptionDataPtr subscriptionData); + PullResult processPullResult(const MQMessageQueue& mq, PullResult& pullResult, SubscriptionData* subscriptionData); PullResult* pullKernelImpl(const MQMessageQueue& mq, // 1 const std::string& subExpression, // 2 @@ -52,12 +52,12 @@ class PullAPIWrapper { int recalculatePullFromWhichNode(const MQMessageQueue& mq); private: - MQClientInstance* m_clientInstance; - std::string m_consumerGroup; - std::mutex m_lock; - std::map m_pullFromWhichNodeTable; + MQClientInstance* client_instance_; + std::string consumer_group_; + std::mutex lock_; + std::map pull_from_which_node_table_; }; } // namespace rocketmq -#endif // __PULL_API_WRAPPER_H__ +#endif // ROCKETMQ_CONSUMER_PULLAPIWRAPPER_H_ diff --git a/src/consumer/PullMessageService.hpp b/src/consumer/PullMessageService.hpp index 8f6a6d5e9..7b22e8b87 100644 --- a/src/consumer/PullMessageService.hpp +++ b/src/consumer/PullMessageService.hpp @@ -14,29 +14,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __PULL_MESSAGE_SERVICE_HPP__ -#define __PULL_MESSAGE_SERVICE_HPP__ +#ifndef ROCKETMQ_CONSUMER_PULLMESSAGESERVICE_HPP_ +#define ROCKETMQ_CONSUMER_PULLMESSAGESERVICE_HPP_ +#include "concurrent/executor.hpp" #include "DefaultMQPushConsumerImpl.h" #include "Logging.h" #include "MQClientInstance.h" #include "PullRequest.h" -#include "concurrent/executor.hpp" namespace rocketmq { class PullMessageService { public: PullMessageService(MQClientInstance* instance) - : m_clientInstance(instance), m_scheduledExecutorService(getServiceName(), 1, false) {} + : client_instance_(instance), scheduled_executor_service_(getServiceName(), 1, false) {} - void start() { m_scheduledExecutorService.startup(); } + void start() { scheduled_executor_service_.startup(); } - void shutdown() { m_scheduledExecutorService.shutdown(); } + void shutdown() { scheduled_executor_service_.shutdown(); } void executePullRequestLater(PullRequestPtr pullRequest, long timeDelay) { - if (m_clientInstance->isRunning()) { - m_scheduledExecutorService.schedule( + if (client_instance_->isRunning()) { + scheduled_executor_service_.schedule( std::bind(&PullMessageService::executePullRequestImmediately, this, pullRequest), timeDelay, time_unit::milliseconds); } else { @@ -45,18 +45,18 @@ class PullMessageService { } void executePullRequestImmediately(PullRequestPtr pullRequest) { - m_scheduledExecutorService.submit(std::bind(&PullMessageService::pullMessage, this, pullRequest)); + scheduled_executor_service_.submit(std::bind(&PullMessageService::pullMessage, this, pullRequest)); } void executeTaskLater(const handler_type& task, long timeDelay) { - m_scheduledExecutorService.schedule(task, timeDelay, time_unit::milliseconds); + scheduled_executor_service_.schedule(task, timeDelay, time_unit::milliseconds); } std::string getServiceName() { return "PullMessageService"; } private: void pullMessage(PullRequestPtr pullRequest) { - MQConsumerInner* consumer = m_clientInstance->selectConsumer(pullRequest->getConsumerGroup()); + MQConsumerInner* consumer = client_instance_->selectConsumer(pullRequest->consumer_group()); if (consumer != nullptr && std::type_index(typeid(*consumer)) == std::type_index(typeid(DefaultMQPushConsumerImpl))) { auto* impl = static_cast(consumer); @@ -67,10 +67,10 @@ class PullMessageService { } private: - MQClientInstance* m_clientInstance; - scheduled_thread_pool_executor m_scheduledExecutorService; + MQClientInstance* client_instance_; + scheduled_thread_pool_executor scheduled_executor_service_; }; } // namespace rocketmq -#endif // __PULL_MESSAGE_SERVICE_HPP__ +#endif // ROCKETMQ_CONSUMER_PULLMESSAGESERVICE_HPP_ diff --git a/src/consumer/PullRequest.cpp b/src/consumer/PullRequest.cpp index 2ff69d04f..e764195ce 100644 --- a/src/consumer/PullRequest.cpp +++ b/src/consumer/PullRequest.cpp @@ -16,60 +16,12 @@ */ #include "PullRequest.h" -#include // std::stringstream - -#include "Logging.h" - namespace rocketmq { -PullRequest::PullRequest() : m_nextOffset(0), m_lockedFirst(false) {} - -PullRequest::~PullRequest() {} - -bool PullRequest::isLockedFirst() const { - return m_lockedFirst; -} - -void PullRequest::setLockedFirst(bool lockedFirst) { - m_lockedFirst = lockedFirst; -} - -const std::string& PullRequest::getConsumerGroup() const { - return m_consumerGroup; -} - -void PullRequest::setConsumerGroup(const std::string& consumerGroup) { - m_consumerGroup = consumerGroup; -} - -const MQMessageQueue& PullRequest::getMessageQueue() { - return m_messageQueue; -} - -void PullRequest::setMessageQueue(const MQMessageQueue& messageQueue) { - m_messageQueue = messageQueue; -} - -int64_t PullRequest::getNextOffset() { - return m_nextOffset; -} - -void PullRequest::setNextOffset(int64_t nextOffset) { - m_nextOffset = nextOffset; -} - -ProcessQueuePtr PullRequest::getProcessQueue() { - return m_processQueue; -} - -void PullRequest::setProcessQueue(ProcessQueuePtr processQueue) { - m_processQueue = processQueue; -} - std::string PullRequest::toString() const { std::stringstream ss; - ss << "PullRequest [consumerGroup=" << m_consumerGroup << ", messageQueue=" << m_messageQueue.toString() - << ", nextOffset=" << m_nextOffset << "]"; + ss << "PullRequest [consumerGroup=" << consumer_group_ << ", messageQueue=" << message_queue_.toString() + << ", nextOffset=" << next_offset_ << "]"; return ss.str(); } diff --git a/src/consumer/PullRequest.h b/src/consumer/PullRequest.h index e86c07dbb..f9a09758f 100644 --- a/src/consumer/PullRequest.h +++ b/src/consumer/PullRequest.h @@ -14,12 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __PULL_REQUEST_H__ -#define __PULL_REQUEST_H__ +#ifndef ROCKETMQ_CONSUMER_PULLREQUEST_H_ +#define ROCKETMQ_CONSUMER_PULLREQUEST_H_ -#include -#include -#include +#include // std::stringstream #include "MQMessageQueue.h" #include "ProcessQueue.h" @@ -31,34 +29,34 @@ typedef std::shared_ptr PullRequestPtr; class ROCKETMQCLIENT_API PullRequest { public: - PullRequest(); - virtual ~PullRequest(); + PullRequest() : next_offset_(0), locked_first_(false) {} + virtual ~PullRequest() = default; - bool isLockedFirst() const; - void setLockedFirst(bool lockedFirst); + inline bool locked_first() const { return locked_first_; } + inline void set_locked_first(bool lockedFirst) { locked_first_ = lockedFirst; } - const std::string& getConsumerGroup() const; - void setConsumerGroup(const std::string& consumerGroup); + inline const std::string& consumer_group() const { return consumer_group_; } + inline void set_consumer_group(const std::string& consumerGroup) { consumer_group_ = consumerGroup; } - const MQMessageQueue& getMessageQueue(); - void setMessageQueue(const MQMessageQueue& messageQueue); + inline const MQMessageQueue& message_queue() { return message_queue_; } + inline void set_message_queue(const MQMessageQueue& messageQueue) { message_queue_ = messageQueue; } - int64_t getNextOffset(); - void setNextOffset(int64_t nextOffset); + inline int64_t next_offset() { return next_offset_; } + inline void set_next_offset(int64_t nextOffset) { next_offset_ = nextOffset; } - ProcessQueuePtr getProcessQueue(); - void setProcessQueue(ProcessQueuePtr processQueue); + inline ProcessQueuePtr process_queue() { return process_queue_; } + inline void set_process_queue(ProcessQueuePtr processQueue) { process_queue_ = processQueue; } std::string toString() const; private: - std::string m_consumerGroup; - MQMessageQueue m_messageQueue; - ProcessQueuePtr m_processQueue; - int64_t m_nextOffset; - bool m_lockedFirst; + std::string consumer_group_; + MQMessageQueue message_queue_; + ProcessQueuePtr process_queue_; + int64_t next_offset_; + bool locked_first_; }; } // namespace rocketmq -#endif // __PULL_REQUEST_H__ +#endif // ROCKETMQ_CONSUMER_PULLREQUEST_H_ diff --git a/src/consumer/PullResult.cpp b/src/consumer/PullResult.cpp index 133f2fe1d..672f2b35a 100644 --- a/src/consumer/PullResult.cpp +++ b/src/consumer/PullResult.cpp @@ -21,13 +21,13 @@ #include "UtilAll.h" -namespace rocketmq { - static const char* kPullStatusStrings[] = {"FOUND", "NO_NEW_MSG", "NO_MATCHED_MSG", "NO_LATEST_MSG" "OFFSET_ILLEGAL", "BROKER_TIMEOUT"}; +namespace rocketmq { + PullResult::PullResult() : pull_status_(NO_MATCHED_MSG), next_begin_offset_(0), min_offset_(0), max_offset_(0) {} PullResult::PullResult(PullStatus status) diff --git a/src/consumer/PullResultExt.h b/src/consumer/PullResultExt.hpp similarity index 93% rename from src/consumer/PullResultExt.h rename to src/consumer/PullResultExt.hpp index 4bbdc1d68..b8840f5e2 100644 --- a/src/consumer/PullResultExt.h +++ b/src/consumer/PullResultExt.hpp @@ -14,9 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "PullResult.h" +#ifndef ROCKETMQ_CONSUMER_PULLRESULTEXT_HPP_ +#define ROCKETMQ_CONSUMER_PULLRESULTEXT_HPP_ #include "ByteArray.h" +#include "PullResult.h" namespace rocketmq { @@ -54,3 +56,5 @@ class PullResultExt : public PullResult { }; } // namespace rocketmq + +#endif // ROCKETMQ_CONSUMER_PULLRESULTEXT_HPP_ diff --git a/src/consumer/RebalanceImpl.cpp b/src/consumer/RebalanceImpl.cpp index fb24e978d..9459d5e2d 100644 --- a/src/consumer/RebalanceImpl.cpp +++ b/src/consumer/RebalanceImpl.cpp @@ -26,33 +26,33 @@ RebalanceImpl::RebalanceImpl(const std::string& consumerGroup, MessageModel messageModel, AllocateMQStrategy* allocateMqStrategy, MQClientInstance* instance) - : m_consumerGroup(consumerGroup), - m_messageModel(messageModel), - m_allocateMQStrategy(allocateMqStrategy), - m_clientInstance(instance) {} + : consumer_group_(consumerGroup), + message_model_(messageModel), + allocate_mq_strategy_(allocateMqStrategy), + client_instance_(instance) {} RebalanceImpl::~RebalanceImpl() { - for (auto& it : m_subscriptionInner) { + for (auto& it : subscription_inner_) { deleteAndZero(it.second); } } void RebalanceImpl::unlock(MQMessageQueue mq, const bool oneway) { std::unique_ptr findBrokerResult( - m_clientInstance->findBrokerAddressInSubscribe(mq.getBrokerName(), MASTER_ID, true)); + client_instance_->findBrokerAddressInSubscribe(mq.broker_name(), MASTER_ID, true)); if (findBrokerResult) { std::unique_ptr unlockBatchRequest(new UnlockBatchRequestBody()); - unlockBatchRequest->setConsumerGroup(m_consumerGroup); - unlockBatchRequest->setClientId(m_clientInstance->getClientId()); + unlockBatchRequest->setConsumerGroup(consumer_group_); + unlockBatchRequest->setClientId(client_instance_->getClientId()); unlockBatchRequest->getMqSet().push_back(mq); try { - m_clientInstance->getMQClientAPIImpl()->unlockBatchMQ(findBrokerResult->brokerAddr, unlockBatchRequest.get(), + client_instance_->getMQClientAPIImpl()->unlockBatchMQ(findBrokerResult->broker_addr(), unlockBatchRequest.get(), 1000); ProcessQueuePtr processQueue = getProcessQueue(mq); if (processQueue) { - processQueue->setLocked(false); + processQueue->set_locked(false); LOG_INFO("the message queue unlock OK, mq:%s", mq.toString().c_str()); } else { LOG_ERROR("the message queue unlock Failed, mq:%s", mq.toString().c_str()); @@ -61,7 +61,7 @@ void RebalanceImpl::unlock(MQMessageQueue mq, const bool oneway) { LOG_ERROR("unlockBatchMQ exception, mq:%s", mq.toString().c_str()); } } else { - LOG_WARN("unlock findBrokerAddressInSubscribe ret null for broker:%s", mq.getBrokerName().data()); + LOG_WARN("unlock findBrokerAddressInSubscribe ret null for broker:%s", mq.broker_name().data()); } } @@ -78,20 +78,20 @@ void RebalanceImpl::unlockAll(const bool oneway) { } std::unique_ptr findBrokerResult( - m_clientInstance->findBrokerAddressInSubscribe(brokerName, MASTER_ID, true)); + client_instance_->findBrokerAddressInSubscribe(brokerName, MASTER_ID, true)); if (findBrokerResult) { std::unique_ptr unlockBatchRequest(new UnlockBatchRequestBody()); - unlockBatchRequest->setConsumerGroup(m_consumerGroup); - unlockBatchRequest->setClientId(m_clientInstance->getClientId()); + unlockBatchRequest->setConsumerGroup(consumer_group_); + unlockBatchRequest->setClientId(client_instance_->getClientId()); unlockBatchRequest->setMqSet(mqs); try { - m_clientInstance->getMQClientAPIImpl()->unlockBatchMQ(findBrokerResult->brokerAddr, unlockBatchRequest.get(), + client_instance_->getMQClientAPIImpl()->unlockBatchMQ(findBrokerResult->broker_addr(), unlockBatchRequest.get(), 1000); for (const auto& mq : mqs) { ProcessQueuePtr processQueue = getProcessQueue(mq); if (processQueue) { - processQueue->setLocked(false); + processQueue->set_locked(false); LOG_INFO("the message queue unlock OK, mq:%s", mq.toString().c_str()); } else { LOG_ERROR("the message queue unlock Failed, mq:%s", mq.toString().c_str()); @@ -111,7 +111,7 @@ std::shared_ptr RebalanceImpl::buildProcessQueueTableByBrokerName() auto processQueueTable = getProcessQueueTable(); for (const auto& it : processQueueTable) { const auto& mq = it.first; - std::string brokerName = mq.getBrokerName(); + std::string brokerName = mq.broker_name(); if (brokerMqs->find(brokerName) == brokerMqs->end()) { brokerMqs->emplace(brokerName, std::vector()); } @@ -122,18 +122,18 @@ std::shared_ptr RebalanceImpl::buildProcessQueueTableByBrokerName() bool RebalanceImpl::lock(MQMessageQueue mq) { std::unique_ptr findBrokerResult( - m_clientInstance->findBrokerAddressInSubscribe(mq.getBrokerName(), MASTER_ID, true)); + client_instance_->findBrokerAddressInSubscribe(mq.broker_name(), MASTER_ID, true)); if (findBrokerResult) { std::unique_ptr lockBatchRequest(new LockBatchRequestBody()); - lockBatchRequest->setConsumerGroup(m_consumerGroup); - lockBatchRequest->setClientId(m_clientInstance->getClientId()); + lockBatchRequest->setConsumerGroup(consumer_group_); + lockBatchRequest->setClientId(client_instance_->getClientId()); lockBatchRequest->getMqSet().push_back(mq); try { LOG_DEBUG("try to lock mq:%s", mq.toString().c_str()); std::vector lockedMq; - m_clientInstance->getMQClientAPIImpl()->lockBatchMQ(findBrokerResult->brokerAddr, lockBatchRequest.get(), + client_instance_->getMQClientAPIImpl()->lockBatchMQ(findBrokerResult->broker_addr(), lockBatchRequest.get(), lockedMq, 1000); bool lockOK = false; @@ -141,8 +141,8 @@ bool RebalanceImpl::lock(MQMessageQueue mq) { for (const auto& mmqq : lockedMq) { ProcessQueuePtr processQueue = getProcessQueue(mq); if (processQueue) { - processQueue->setLocked(true); - processQueue->setLastLockTimestamp(UtilAll::currentTimeMillis()); + processQueue->set_locked(true); + processQueue->set_last_lock_timestamp(UtilAll::currentTimeMillis()); lockOK = true; LOG_INFO("the message queue locked OK, mq:%s", mmqq.toString().c_str()); } else { @@ -160,7 +160,7 @@ bool RebalanceImpl::lock(MQMessageQueue mq) { LOG_ERROR("lockBatchMQ exception, mq:%s", mq.toString().c_str()); } } else { - LOG_ERROR("lock findBrokerAddressInSubscribe ret null for broker:%s", mq.getBrokerName().data()); + LOG_ERROR("lock findBrokerAddressInSubscribe ret null for broker:%s", mq.broker_name().data()); } return false; @@ -179,17 +179,17 @@ void RebalanceImpl::lockAll() { } std::unique_ptr findBrokerResult( - m_clientInstance->findBrokerAddressInSubscribe(brokerName, MASTER_ID, true)); + client_instance_->findBrokerAddressInSubscribe(brokerName, MASTER_ID, true)); if (findBrokerResult) { std::unique_ptr lockBatchRequest(new LockBatchRequestBody()); - lockBatchRequest->setConsumerGroup(m_consumerGroup); - lockBatchRequest->setClientId(m_clientInstance->getClientId()); + lockBatchRequest->setConsumerGroup(consumer_group_); + lockBatchRequest->setClientId(client_instance_->getClientId()); lockBatchRequest->setMqSet(mqs); LOG_INFO("try to lock:" SIZET_FMT " mqs of broker:%s", mqs.size(), brokerName.c_str()); try { std::vector lockOKMQVec; - m_clientInstance->getMQClientAPIImpl()->lockBatchMQ(findBrokerResult->brokerAddr, lockBatchRequest.get(), + client_instance_->getMQClientAPIImpl()->lockBatchMQ(findBrokerResult->broker_addr(), lockBatchRequest.get(), lockOKMQVec, 1000); std::set lockOKMQSet; @@ -198,8 +198,8 @@ void RebalanceImpl::lockAll() { ProcessQueuePtr processQueue = getProcessQueue(mq); if (processQueue) { - processQueue->setLocked(true); - processQueue->setLastLockTimestamp(UtilAll::currentTimeMillis()); + processQueue->set_locked(true); + processQueue->set_last_lock_timestamp(UtilAll::currentTimeMillis()); LOG_INFO("the message queue locked OK, mq:%s", mq.toString().c_str()); } else { LOG_WARN("the message queue locked OK, but it is released, mq:%s", mq.toString().c_str()); @@ -211,7 +211,7 @@ void RebalanceImpl::lockAll() { ProcessQueuePtr processQueue = getProcessQueue(mq); if (processQueue) { LOG_WARN("the message queue locked Failed, mq:%s", mq.toString().c_str()); - processQueue->setLocked(false); + processQueue->set_locked(false); } } } @@ -226,7 +226,7 @@ void RebalanceImpl::lockAll() { void RebalanceImpl::doRebalance(const bool isOrder) { LOG_DEBUG("start doRebalance"); - for (const auto& it : m_subscriptionInner) { + for (const auto& it : subscription_inner_) { const std::string& topic = it.first; LOG_INFO("current topic is:%s", topic.c_str()); try { @@ -241,7 +241,7 @@ void RebalanceImpl::doRebalance(const bool isOrder) { void RebalanceImpl::rebalanceByTopic(const std::string& topic, const bool isOrder) { // msg model - switch (m_messageModel) { + switch (message_model_) { case BROADCASTING: { std::vector mqSet; if (!getTopicSubscribeInfo(topic, mqSet)) { @@ -250,23 +250,23 @@ void RebalanceImpl::rebalanceByTopic(const std::string& topic, const bool isOrde messageQueueChanged(topic, mqSet, mqSet); } } else { - LOG_WARN("doRebalance, %s, but the topic[%s] not exist.", m_consumerGroup.c_str(), topic.c_str()); + LOG_WARN("doRebalance, %s, but the topic[%s] not exist.", consumer_group_.c_str(), topic.c_str()); } } break; case CLUSTERING: { std::vector mqAll; if (!getTopicSubscribeInfo(topic, mqAll)) { if (!UtilAll::isRetryTopic(topic)) { - LOG_WARN("doRebalance, %s, but the topic[%s] not exist.", m_consumerGroup.c_str(), topic.c_str()); + LOG_WARN("doRebalance, %s, but the topic[%s] not exist.", consumer_group_.c_str(), topic.c_str()); } return; } std::vector cidAll; - m_clientInstance->findConsumerIds(topic, m_consumerGroup, cidAll); + client_instance_->findConsumerIds(topic, consumer_group_, cidAll); if (cidAll.empty()) { - LOG_WARN("doRebalance, %s %s, get consumer id list failed", m_consumerGroup.c_str(), topic.c_str()); + LOG_WARN("doRebalance, %s %s, get consumer id list failed", consumer_group_.c_str(), topic.c_str()); return; } @@ -282,7 +282,7 @@ void RebalanceImpl::rebalanceByTopic(const std::string& topic, const bool isOrde // allocate mqs std::vector allocateResult; try { - m_allocateMQStrategy->allocate(m_clientInstance->getClientId(), mqAll, cidAll, allocateResult); + allocate_mq_strategy_->allocate(client_instance_->getClientId(), mqAll, cidAll, allocateResult); } catch (MQException& e) { LOG_ERROR("AllocateMessageQueueStrategy.allocate Exception: %s", e.what()); return; @@ -293,7 +293,7 @@ void RebalanceImpl::rebalanceByTopic(const std::string& topic, const bool isOrde if (changed) { LOG_INFO("rebalanced result changed. group=%s, topic=%s, clientId=%s, mqAllSize=" SIZET_FMT ", cidAllSize=" SIZET_FMT ", rebalanceResultSize=" SIZET_FMT ", rebalanceResultSet:", - m_consumerGroup.c_str(), topic.c_str(), m_clientInstance->getClientId().c_str(), mqAll.size(), + consumer_group_.c_str(), topic.c_str(), client_instance_->getClientId().c_str(), mqAll.size(), cidAll.size(), allocateResult.size()); for (auto& mq : allocateResult) { LOG_INFO("allocate mq:%s", mq.toString().c_str()); @@ -310,11 +310,11 @@ void RebalanceImpl::truncateMessageQueueNotMyTopic() { auto& subTable = getSubscriptionInner(); std::vector mqs = getAllocatedMQ(); for (const auto& mq : mqs) { - if (subTable.find(mq.getTopic()) == subTable.end()) { + if (subTable.find(mq.topic()) == subTable.end()) { auto pq = removeProcessQueueDirectly(mq); if (pq != nullptr) { - pq->setDropped(true); - LOG_INFO("doRebalance, %s, truncateMessageQueueNotMyTopic remove unnecessary mq, {}", m_consumerGroup.c_str(), + pq->set_dropped(true); + LOG_INFO("doRebalance, %s, truncateMessageQueueNotMyTopic remove unnecessary mq, {}", consumer_group_.c_str(), mq.toString().c_str()); } } @@ -329,30 +329,30 @@ bool RebalanceImpl::updateProcessQueueTableInRebalance(const std::string& topic, bool changed = false; // remove - MQ2PQ processQueueTable(getProcessQueueTable()); // get copy of m_processQueueTable + MQ2PQ processQueueTable(getProcessQueueTable()); // get copy of process_queue_table_ for (const auto& it : processQueueTable) { const auto& mq = it.first; auto pq = it.second; - if (mq.getTopic() == topic) { + if (mq.topic() == topic) { if (mqSet.empty() || (find(mqSet.begin(), mqSet.end(), mq) == mqSet.end())) { - pq->setDropped(true); + pq->set_dropped(true); if (removeUnnecessaryMessageQueue(mq, pq)) { removeProcessQueueDirectly(mq); changed = true; - LOG_INFO("doRebalance, %s, remove unnecessary mq, %s", m_consumerGroup.c_str(), mq.toString().c_str()); + LOG_INFO("doRebalance, %s, remove unnecessary mq, %s", consumer_group_.c_str(), mq.toString().c_str()); } } else if (pq->isPullExpired()) { switch (consumeType()) { case CONSUME_ACTIVELY: break; case CONSUME_PASSIVELY: - pq->setDropped(true); + pq->set_dropped(true); if (removeUnnecessaryMessageQueue(mq, pq)) { removeProcessQueueDirectly(mq); changed = true; LOG_ERROR("[BUG]doRebalance, %s, remove unnecessary mq, %s, because pull is pause, so try to fixed it", - m_consumerGroup.c_str(), mq.toString().c_str()); + consumer_group_.c_str(), mq.toString().c_str()); } break; default: @@ -368,7 +368,7 @@ bool RebalanceImpl::updateProcessQueueTableInRebalance(const std::string& topic, ProcessQueuePtr pq = getProcessQueue(mq); if (nullptr == pq) { if (isOrder && !lock(mq)) { - LOG_WARN("doRebalance, %s, add a new mq failed, %s, because lock failed", m_consumerGroup.c_str(), + LOG_WARN("doRebalance, %s, add a new mq failed, %s, because lock failed", consumer_group_.c_str(), mq.toString().c_str()); continue; } @@ -379,19 +379,19 @@ bool RebalanceImpl::updateProcessQueueTableInRebalance(const std::string& topic, if (nextOffset >= 0) { auto pre = putProcessQueueIfAbsent(mq, pq); if (pre) { - LOG_INFO("doRebalance, %s, mq already exists, %s", m_consumerGroup.c_str(), mq.toString().c_str()); + LOG_INFO("doRebalance, %s, mq already exists, %s", consumer_group_.c_str(), mq.toString().c_str()); } else { - LOG_INFO("doRebalance, %s, add a new mq, %s", m_consumerGroup.c_str(), mq.toString().c_str()); + LOG_INFO("doRebalance, %s, add a new mq, %s", consumer_group_.c_str(), mq.toString().c_str()); PullRequestPtr pullRequest(new PullRequest()); - pullRequest->setConsumerGroup(m_consumerGroup); - pullRequest->setNextOffset(nextOffset); - pullRequest->setMessageQueue(mq); - pullRequest->setProcessQueue(pq); + pullRequest->set_consumer_group(consumer_group_); + pullRequest->set_next_offset(nextOffset); + pullRequest->set_message_queue(mq); + pullRequest->set_process_queue(pq); pullRequestList.push_back(std::move(pullRequest)); changed = true; } } else { - LOG_WARN("doRebalance, %s, add new mq failed, %s", m_consumerGroup.c_str(), mq.toString().c_str()); + LOG_WARN("doRebalance, %s, add new mq failed, %s", consumer_group_.c_str(), mq.toString().c_str()); } } } @@ -403,46 +403,46 @@ bool RebalanceImpl::updateProcessQueueTableInRebalance(const std::string& topic, } void RebalanceImpl::removeProcessQueue(const MQMessageQueue& mq) { - std::lock_guard lock(m_processQueueTableMutex); - const auto& it = m_processQueueTable.find(mq); - if (it != m_processQueueTable.end()) { + std::lock_guard lock(process_queue_table_mutex_); + const auto& it = process_queue_table_.find(mq); + if (it != process_queue_table_.end()) { auto prev = it->second; - m_processQueueTable.erase(it); + process_queue_table_.erase(it); - bool dropped = prev->isDropped(); - prev->setDropped(true); + bool dropped = prev->dropped(); + prev->set_dropped(true); removeUnnecessaryMessageQueue(mq, prev); - LOG_INFO("Fix Offset, {}, remove unnecessary mq, {} Dropped: {}", m_consumerGroup, mq.toString(), + LOG_INFO("Fix Offset, {}, remove unnecessary mq, {} Dropped: {}", consumer_group_, mq.toString(), UtilAll::to_string(dropped)); } } ProcessQueuePtr RebalanceImpl::removeProcessQueueDirectly(const MQMessageQueue& mq) { - std::lock_guard lock(m_processQueueTableMutex); - const auto& it = m_processQueueTable.find(mq); - if (it != m_processQueueTable.end()) { + std::lock_guard lock(process_queue_table_mutex_); + const auto& it = process_queue_table_.find(mq); + if (it != process_queue_table_.end()) { auto old = it->second; - m_processQueueTable.erase(it); + process_queue_table_.erase(it); return old; } return nullptr; } ProcessQueuePtr RebalanceImpl::putProcessQueueIfAbsent(const MQMessageQueue& mq, ProcessQueuePtr pq) { - std::lock_guard lock(m_processQueueTableMutex); - const auto& it = m_processQueueTable.find(mq); - if (it != m_processQueueTable.end()) { + std::lock_guard lock(process_queue_table_mutex_); + const auto& it = process_queue_table_.find(mq); + if (it != process_queue_table_.end()) { return it->second; } else { - m_processQueueTable[mq] = pq; + process_queue_table_[mq] = pq; return nullptr; } } ProcessQueuePtr RebalanceImpl::getProcessQueue(const MQMessageQueue& mq) { - std::lock_guard lock(m_processQueueTableMutex); - const auto& it = m_processQueueTable.find(mq); - if (it != m_processQueueTable.end()) { + std::lock_guard lock(process_queue_table_mutex_); + const auto& it = process_queue_table_.find(mq); + if (it != process_queue_table_.end()) { return it->second; } else { return nullptr; @@ -450,54 +450,54 @@ ProcessQueuePtr RebalanceImpl::getProcessQueue(const MQMessageQueue& mq) { } MQ2PQ RebalanceImpl::getProcessQueueTable() { - std::lock_guard lock(m_processQueueTableMutex); - return m_processQueueTable; + std::lock_guard lock(process_queue_table_mutex_); + return process_queue_table_; } std::vector RebalanceImpl::getAllocatedMQ() { std::vector mqs; - std::lock_guard lock(m_processQueueTableMutex); - for (const auto& it : m_processQueueTable) { + std::lock_guard lock(process_queue_table_mutex_); + for (const auto& it : process_queue_table_) { mqs.push_back(it.first); } return mqs; } void RebalanceImpl::destroy() { - std::lock_guard lock(m_processQueueTableMutex); - for (const auto& it : m_processQueueTable) { - it.second->setDropped(true); + std::lock_guard lock(process_queue_table_mutex_); + for (const auto& it : process_queue_table_) { + it.second->set_dropped(true); } - m_processQueueTable.clear(); + process_queue_table_.clear(); } TOPIC2SD& RebalanceImpl::getSubscriptionInner() { - return m_subscriptionInner; + return subscription_inner_; } -SubscriptionDataPtr RebalanceImpl::getSubscriptionData(const std::string& topic) { - const auto& it = m_subscriptionInner.find(topic); - if (it != m_subscriptionInner.end()) { +SubscriptionData* RebalanceImpl::getSubscriptionData(const std::string& topic) { + const auto& it = subscription_inner_.find(topic); + if (it != subscription_inner_.end()) { return it->second; } return nullptr; } -void RebalanceImpl::setSubscriptionData(const std::string& topic, SubscriptionDataPtr subscriptionData) noexcept { +void RebalanceImpl::setSubscriptionData(const std::string& topic, SubscriptionData* subscriptionData) noexcept { if (subscriptionData != nullptr) { - const auto& it = m_subscriptionInner.find(topic); - if (it != m_subscriptionInner.end()) { + const auto& it = subscription_inner_.find(topic); + if (it != subscription_inner_.end()) { deleteAndZero(it->second); } - m_subscriptionInner[topic] = subscriptionData; + subscription_inner_[topic] = subscriptionData; } } bool RebalanceImpl::getTopicSubscribeInfo(const std::string& topic, std::vector& mqs) { - std::lock_guard lock(m_topicSubscribeInfoTableMutex); - const auto& it = m_topicSubscribeInfoTable.find(topic); - if (it != m_topicSubscribeInfoTable.end()) { + std::lock_guard lock(topic_subscribe_info_table_mutex_); + const auto& it = topic_subscribe_info_table_.find(topic); + if (it != topic_subscribe_info_table_.end()) { mqs = it->second; // mqs will out return true; } @@ -505,13 +505,13 @@ bool RebalanceImpl::getTopicSubscribeInfo(const std::string& topic, std::vector< } void RebalanceImpl::setTopicSubscribeInfo(const std::string& topic, std::vector& mqs) { - if (m_subscriptionInner.find(topic) == m_subscriptionInner.end()) { + if (subscription_inner_.find(topic) == subscription_inner_.end()) { return; } { - std::lock_guard lock(m_topicSubscribeInfoTableMutex); - m_topicSubscribeInfoTable[topic] = mqs; + std::lock_guard lock(topic_subscribe_info_table_mutex_); + topic_subscribe_info_table_[topic] = mqs; } // log diff --git a/src/consumer/RebalanceImpl.h b/src/consumer/RebalanceImpl.h index 18b555b81..8648aa2c5 100755 --- a/src/consumer/RebalanceImpl.h +++ b/src/consumer/RebalanceImpl.h @@ -14,14 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __REBALANCE_IMPL_H__ -#define __REBALANCE_IMPL_H__ +#ifndef ROCKETMQ_CONSUMER_REBALANCEIMPL_H_ +#define ROCKETMQ_CONSUMER_REBALANCEIMPL_H_ #include #include "AllocateMQStrategy.h" #include "ConsumeType.h" -#include "MQClientException.h" +#include "MQException.h" #include "MQClientInstance.h" #include "MQMessageQueue.h" #include "ProcessQueue.h" @@ -32,7 +32,7 @@ namespace rocketmq { typedef std::map MQ2PQ; typedef std::map> TOPIC2MQS; -typedef std::map TOPIC2SD; +typedef std::map TOPIC2SD; typedef std::map> BROKER2MQS; class RebalanceImpl { @@ -74,8 +74,8 @@ class RebalanceImpl { public: TOPIC2SD& getSubscriptionInner(); - SubscriptionDataPtr getSubscriptionData(const std::string& topic); - void setSubscriptionData(const std::string& topic, SubscriptionDataPtr sd) noexcept; + SubscriptionData* getSubscriptionData(const std::string& topic); + void setSubscriptionData(const std::string& topic, SubscriptionData* sd) noexcept; bool getTopicSubscribeInfo(const std::string& topic, std::vector& mqs); void setTopicSubscribeInfo(const std::string& topic, std::vector& mqs); @@ -88,26 +88,28 @@ class RebalanceImpl { std::vector getAllocatedMQ(); public: - void setConsumerGroup(const std::string& groupname) { m_consumerGroup = groupname; } - void setMessageModel(MessageModel messageModel) { m_messageModel = messageModel; } - void setAllocateMQStrategy(AllocateMQStrategy* allocateMqStrategy) { m_allocateMQStrategy = allocateMqStrategy; } - void setClientInstance(MQClientInstance* instance) { m_clientInstance = instance; } + inline void set_consumer_group(const std::string& groupname) { consumer_group_ = groupname; } + inline void set_message_model(MessageModel messageModel) { message_model_ = messageModel; } + inline void set_allocate_mq_strategy(AllocateMQStrategy* allocateMqStrategy) { + allocate_mq_strategy_ = allocateMqStrategy; + } + inline void set_client_instance(MQClientInstance* instance) { client_instance_ = instance; } protected: - MQ2PQ m_processQueueTable; - std::mutex m_processQueueTableMutex; + MQ2PQ process_queue_table_; + std::mutex process_queue_table_mutex_; - TOPIC2MQS m_topicSubscribeInfoTable; - std::mutex m_topicSubscribeInfoTableMutex; + TOPIC2MQS topic_subscribe_info_table_; + std::mutex topic_subscribe_info_table_mutex_; - TOPIC2SD m_subscriptionInner; // don't modify m_subscriptionInner after consumer start. + TOPIC2SD subscription_inner_; // don't modify subscription_inner_ after consumer start. - std::string m_consumerGroup; - MessageModel m_messageModel; - AllocateMQStrategy* m_allocateMQStrategy; - MQClientInstance* m_clientInstance; + std::string consumer_group_; + MessageModel message_model_; + AllocateMQStrategy* allocate_mq_strategy_; + MQClientInstance* client_instance_; }; } // namespace rocketmq -#endif // __REBALANCE_IMPL_H__ +#endif // ROCKETMQ_CONSUMER_REBALANCEIMPL_H_ diff --git a/src/consumer/RebalancePullImpl.h b/src/consumer/RebalancePullImpl.h index 447ce6040..d4f106c51 100755 --- a/src/consumer/RebalancePullImpl.h +++ b/src/consumer/RebalancePullImpl.h @@ -24,7 +24,7 @@ namespace rocketmq { typedef std::map MQ2PQ; typedef std::map> TOPIC2MQS; -typedef std::map TOPIC2SD; +typedef std::map TOPIC2SD; typedef std::map> BROKER2MQS; class RebalancePullImpl : public RebalanceImpl { diff --git a/src/consumer/RebalancePushImpl.cpp b/src/consumer/RebalancePushImpl.cpp index 7ba0a53ea..ecffc955a 100644 --- a/src/consumer/RebalancePushImpl.cpp +++ b/src/consumer/RebalancePushImpl.cpp @@ -21,28 +21,28 @@ namespace rocketmq { -RebalancePushImpl::RebalancePushImpl(DefaultMQPushConsumerImpl* consumer) - : RebalanceImpl("", CLUSTERING, nullptr, nullptr), m_defaultMQPushConsumer(consumer) {} +RebalancePushImpl::RebalancePushImpl(DefaultMQPushConsumerImpl* consumerImpl) + : RebalanceImpl(null, CLUSTERING, nullptr, nullptr), default_mq_push_consumer_impl_(consumerImpl) {} bool RebalancePushImpl::removeUnnecessaryMessageQueue(const MQMessageQueue& mq, ProcessQueuePtr pq) { - auto* pOffsetStore = m_defaultMQPushConsumer->getOffsetStore(); + auto* pOffsetStore = default_mq_push_consumer_impl_->getOffsetStore(); pOffsetStore->persist(mq); pOffsetStore->removeOffset(mq); - if (m_defaultMQPushConsumer->getMessageListenerType() == messageListenerOrderly && - CLUSTERING == m_defaultMQPushConsumer->messageModel()) { + if (default_mq_push_consumer_impl_->getMessageListenerType() == messageListenerOrderly && + CLUSTERING == default_mq_push_consumer_impl_->messageModel()) { try { - if (UtilAll::try_lock_for(pq->getLockConsume(), 1000)) { - std::lock_guard lock(pq->getLockConsume(), std::adopt_lock); + if (UtilAll::try_lock_for(pq->lock_consume(), 1000)) { + std::lock_guard lock(pq->lock_consume(), std::adopt_lock); // TODO: unlockDelay unlock(mq); return true; } else { LOG_WARN("[WRONG]mq is consuming, so can not unlock it, %s. maybe hanged for a while, %ld", - mq.toString().c_str(), pq->getTryUnlockTimes()); + mq.toString().c_str(), pq->try_unlock_times()); - pq->incTryUnlockTimes(); + pq->inc_try_unlock_times(); } } catch (const std::exception& e) { LOG_ERROR("removeUnnecessaryMessageQueue Exception: %s", e.what()); @@ -55,29 +55,30 @@ bool RebalancePushImpl::removeUnnecessaryMessageQueue(const MQMessageQueue& mq, } void RebalancePushImpl::removeDirtyOffset(const MQMessageQueue& mq) { - m_defaultMQPushConsumer->getOffsetStore()->removeOffset(mq); + default_mq_push_consumer_impl_->getOffsetStore()->removeOffset(mq); } int64_t RebalancePushImpl::computePullFromWhere(const MQMessageQueue& mq) { int64_t result = -1; - ConsumeFromWhere consumeFromWhere = m_defaultMQPushConsumer->getDefaultMQPushConsumerConfig()->getConsumeFromWhere(); - OffsetStore* offsetStore = m_defaultMQPushConsumer->getOffsetStore(); + ConsumeFromWhere consumeFromWhere = + default_mq_push_consumer_impl_->getDefaultMQPushConsumerConfig()->getConsumeFromWhere(); + OffsetStore* offsetStore = default_mq_push_consumer_impl_->getOffsetStore(); switch (consumeFromWhere) { case CONSUME_FROM_LAST_OFFSET: { - int64_t lastOffset = offsetStore->readOffset(mq, READ_FROM_STORE); + int64_t lastOffset = offsetStore->readOffset(mq, ReadOffsetType::READ_FROM_STORE); if (lastOffset >= 0) { LOG_INFO_NEW("CONSUME_FROM_LAST_OFFSET, lastOffset of mq:{} is {}", mq.toString(), lastOffset); result = lastOffset; } else if (-1 == lastOffset) { LOG_WARN_NEW("CONSUME_FROM_LAST_OFFSET, lastOffset of mq:%s is -1", mq.toString()); - if (UtilAll::isRetryTopic(mq.getTopic())) { + if (UtilAll::isRetryTopic(mq.topic())) { LOG_INFO_NEW("CONSUME_FROM_LAST_OFFSET, lastOffset of mq:%s is 0", mq.toString()); result = 0; } else { try { - result = m_defaultMQPushConsumer->maxOffset(mq); + result = default_mq_push_consumer_impl_->maxOffset(mq); LOG_INFO_NEW("CONSUME_FROM_LAST_OFFSET, maxOffset of mq:{} is {}", mq.toString(), result); - } catch (MQException& e) { + } catch (MQClientException& e) { LOG_ERROR_NEW("CONSUME_FROM_LAST_OFFSET error, lastOffset of mq:{} is -1", mq.toString()); result = -1; } @@ -88,7 +89,7 @@ int64_t RebalancePushImpl::computePullFromWhere(const MQMessageQueue& mq) { } } break; case CONSUME_FROM_FIRST_OFFSET: { - int64_t lastOffset = offsetStore->readOffset(mq, READ_FROM_STORE); + int64_t lastOffset = offsetStore->readOffset(mq, ReadOffsetType::READ_FROM_STORE); if (lastOffset >= 0) { LOG_INFO_NEW("CONSUME_FROM_FIRST_OFFSET, lastOffset of mq:{} is {}", mq.toString(), lastOffset); result = lastOffset; @@ -101,16 +102,16 @@ int64_t RebalancePushImpl::computePullFromWhere(const MQMessageQueue& mq) { } } break; case CONSUME_FROM_TIMESTAMP: { - int64_t lastOffset = offsetStore->readOffset(mq, READ_FROM_STORE); + int64_t lastOffset = offsetStore->readOffset(mq, ReadOffsetType::READ_FROM_STORE); if (lastOffset >= 0) { LOG_INFO_NEW("CONSUME_FROM_TIMESTAMP, lastOffset of mq:{} is {}", mq.toString().c_str(), lastOffset); result = lastOffset; } else if (-1 == lastOffset) { - if (UtilAll::isRetryTopic(mq.getTopic())) { + if (UtilAll::isRetryTopic(mq.topic())) { try { - result = m_defaultMQPushConsumer->maxOffset(mq); + result = default_mq_push_consumer_impl_->maxOffset(mq); LOG_INFO_NEW("CONSUME_FROM_TIMESTAMP, maxOffset of mq:{} is {}", mq.toString(), result); - } catch (MQException& e) { + } catch (MQClientException& e) { LOG_ERROR_NEW("CONSUME_FROM_TIMESTAMP error, maxOffset of mq:{} is -1", mq.toString()); result = -1; } @@ -118,9 +119,9 @@ int64_t RebalancePushImpl::computePullFromWhere(const MQMessageQueue& mq) { try { // FIXME: parseDate by YYYYMMDDHHMMSS auto timestamp = - std::stoull(m_defaultMQPushConsumer->getDefaultMQPushConsumerConfig()->getConsumeTimestamp()); - result = m_defaultMQPushConsumer->searchOffset(mq, timestamp); - } catch (MQException& e) { + std::stoull(default_mq_push_consumer_impl_->getDefaultMQPushConsumerConfig()->getConsumeTimestamp()); + result = default_mq_push_consumer_impl_->searchOffset(mq, timestamp); + } catch (MQClientException& e) { LOG_ERROR_NEW("CONSUME_FROM_TIMESTAMP error, searchOffset of mq:{}, return 0", mq.toString()); result = -1; } @@ -138,8 +139,8 @@ int64_t RebalancePushImpl::computePullFromWhere(const MQMessageQueue& mq) { void RebalancePushImpl::dispatchPullRequest(const std::vector& pullRequestList) { for (const auto& pullRequest : pullRequestList) { - m_defaultMQPushConsumer->executePullRequestImmediately(pullRequest); - LOG_INFO("doRebalance, %s, add a new pull request %s", m_consumerGroup.c_str(), pullRequest->toString().c_str()); + default_mq_push_consumer_impl_->executePullRequestImmediately(pullRequest); + LOG_INFO_NEW("doRebalance, {}, add a new pull request {}", consumer_group_, pullRequest->toString()); } } diff --git a/src/consumer/RebalancePushImpl.h b/src/consumer/RebalancePushImpl.h index fdba5a279..f0222631f 100644 --- a/src/consumer/RebalancePushImpl.h +++ b/src/consumer/RebalancePushImpl.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __REBALANCE_PUSH_IMPL_H__ -#define __REBALANCE_PUSH_IMPL_H__ +#ifndef ROCKETMQ_CONSUMER_REBALANCEPUSHIMPL_H_ +#define ROCKETMQ_CONSUMER_REBALANCEPUSHIMPL_H_ #include "DefaultMQPushConsumerImpl.h" #include "RebalanceImpl.h" @@ -24,7 +24,7 @@ namespace rocketmq { class RebalancePushImpl : public RebalanceImpl { public: - RebalancePushImpl(DefaultMQPushConsumerImpl* consumer); + RebalancePushImpl(DefaultMQPushConsumerImpl* consumerImpl); ConsumeType consumeType() override final { return CONSUME_PASSIVELY; } @@ -41,9 +41,9 @@ class RebalancePushImpl : public RebalanceImpl { std::vector& mqDivided) override; private: - DefaultMQPushConsumerImpl* m_defaultMQPushConsumer; + DefaultMQPushConsumerImpl* default_mq_push_consumer_impl_; }; } // namespace rocketmq -#endif // __REBALANCE_PUSH_IMPL_H__ +#endif // ROCKETMQ_CONSUMER_REBALANCEPUSHIMPL_H_ diff --git a/src/consumer/RebalanceService.h b/src/consumer/RebalanceService.h index 696335104..e684a7b76 100644 --- a/src/consumer/RebalanceService.h +++ b/src/consumer/RebalanceService.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __REBALANCE_SERVICE_H__ -#define __REBALANCE_SERVICE_H__ +#ifndef ROCKETMQ_CONSUMER_REBALANCESERVICE_H_ +#define ROCKETMQ_CONSUMER_REBALANCESERVICE_H_ #include "Logging.h" #include "MQClientInstance.h" @@ -25,14 +25,14 @@ namespace rocketmq { class RebalanceService : public ServiceThread { public: - RebalanceService(MQClientInstance* instance) : m_clientInstance(instance) {} + RebalanceService(MQClientInstance* instance) : client_instance_(instance) {} void run() override { LOG_INFO_NEW("{} service started", getServiceName()); while (!isStopped()) { waitForRunning(20000); - m_clientInstance->doRebalance(); + client_instance_->doRebalance(); } LOG_INFO_NEW("{} service end", getServiceName()); @@ -41,9 +41,9 @@ class RebalanceService : public ServiceThread { std::string getServiceName() override { return "RebalanceService"; } private: - MQClientInstance* m_clientInstance; + MQClientInstance* client_instance_; }; } // namespace rocketmq -#endif // __REBALANCE_SERVICE_H__ +#endif // ROCKETMQ_CONSUMER_REBALANCESERVICE_H_ diff --git a/src/consumer/RemoteBrokerOffsetStore.cpp b/src/consumer/RemoteBrokerOffsetStore.cpp new file mode 100644 index 000000000..8754d8b7a --- /dev/null +++ b/src/consumer/RemoteBrokerOffsetStore.cpp @@ -0,0 +1,153 @@ +/* + * 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 "RemoteBrokerOffsetStore.h" + +#include "Logging.h" +#include "MQClientAPIImpl.h" +#include "MQClientInstance.h" +#include "MessageQueue.h" +#include "UtilAll.h" + +namespace rocketmq { + +RemoteBrokerOffsetStore::RemoteBrokerOffsetStore(MQClientInstance* instance, const std::string& groupName) + : client_instance_(instance), group_name_(groupName) {} + +RemoteBrokerOffsetStore::~RemoteBrokerOffsetStore() { + client_instance_ = nullptr; + offset_table_.clear(); +} + +void RemoteBrokerOffsetStore::load() {} + +void RemoteBrokerOffsetStore::updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) { + std::lock_guard lock(lock_); + const auto& it = offset_table_.find(mq); + if (it == offset_table_.end() || !increaseOnly || offset > it->second) { + offset_table_[mq] = offset; + } +} + +int64_t RemoteBrokerOffsetStore::readOffset(const MQMessageQueue& mq, ReadOffsetType type) { + switch (type) { + case MEMORY_FIRST_THEN_STORE: + case READ_FROM_MEMORY: { + std::lock_guard lock(lock_); + + const auto& it = offset_table_.find(mq); + if (it != offset_table_.end()) { + return it->second; + } else if (READ_FROM_MEMORY == type) { + return -1; + } + } + case READ_FROM_STORE: { + try { + int64_t brokerOffset = fetchConsumeOffsetFromBroker(mq); + // update + updateOffset(mq, brokerOffset, false); + return brokerOffset; + } catch (MQBrokerException& e) { + LOG_ERROR(e.what()); + return -1; + } catch (MQException& e) { + LOG_ERROR(e.what()); + return -2; + } + } + default: + break; + } + return -1; +} + +void RemoteBrokerOffsetStore::persist(const MQMessageQueue& mq) { + std::map offsetTable; + { + std::lock_guard lock(lock_); + offsetTable = offset_table_; + } + + const auto& it = offsetTable.find(mq); + if (it != offsetTable.end()) { + try { + updateConsumeOffsetToBroker(mq, it->second); + } catch (MQException& e) { + LOG_ERROR("updateConsumeOffsetToBroker error"); + } + } +} + +void RemoteBrokerOffsetStore::persistAll(const std::vector& mq) {} + +void RemoteBrokerOffsetStore::removeOffset(const MQMessageQueue& mq) { + std::lock_guard lock(lock_); + const auto& it = offset_table_.find(mq); + if (it != offset_table_.end()) { + offset_table_.erase(it); + } +} + +void RemoteBrokerOffsetStore::updateConsumeOffsetToBroker(const MQMessageQueue& mq, int64_t offset) { + std::unique_ptr findBrokerResult(client_instance_->findBrokerAddressInAdmin(mq.broker_name())); + + if (findBrokerResult == nullptr) { + client_instance_->updateTopicRouteInfoFromNameServer(mq.topic()); + findBrokerResult.reset(client_instance_->findBrokerAddressInAdmin(mq.broker_name())); + } + + if (findBrokerResult != nullptr) { + UpdateConsumerOffsetRequestHeader* requestHeader = new UpdateConsumerOffsetRequestHeader(); + requestHeader->topic = mq.topic(); + requestHeader->consumerGroup = group_name_; + requestHeader->queueId = mq.queue_id(); + requestHeader->commitOffset = offset; + + try { + LOG_INFO("oneway updateConsumeOffsetToBroker of mq:%s, its offset is:%lld", mq.toString().c_str(), offset); + return client_instance_->getMQClientAPIImpl()->updateConsumerOffsetOneway(findBrokerResult->broker_addr(), + requestHeader, 1000 * 5); + } catch (MQException& e) { + LOG_ERROR(e.what()); + } + } + LOG_WARN("The broker not exist"); +} + +int64_t RemoteBrokerOffsetStore::fetchConsumeOffsetFromBroker(const MQMessageQueue& mq) { + std::unique_ptr findBrokerResult(client_instance_->findBrokerAddressInAdmin(mq.broker_name())); + + if (findBrokerResult == nullptr) { + client_instance_->updateTopicRouteInfoFromNameServer(mq.topic()); + findBrokerResult.reset(client_instance_->findBrokerAddressInAdmin(mq.broker_name())); + } + + if (findBrokerResult != nullptr) { + QueryConsumerOffsetRequestHeader* requestHeader = new QueryConsumerOffsetRequestHeader(); + requestHeader->topic = mq.topic(); + requestHeader->consumerGroup = group_name_; + requestHeader->queueId = mq.queue_id(); + + return client_instance_->getMQClientAPIImpl()->queryConsumerOffset(findBrokerResult->broker_addr(), requestHeader, + 1000 * 5); + } else { + LOG_ERROR("The broker not exist when fetchConsumeOffsetFromBroker"); + THROW_MQEXCEPTION(MQClientException, "The broker not exist", -1); + } +} + +} // namespace rocketmq diff --git a/src/consumer/RemoteBrokerOffsetStore.h b/src/consumer/RemoteBrokerOffsetStore.h new file mode 100644 index 000000000..ba6598eeb --- /dev/null +++ b/src/consumer/RemoteBrokerOffsetStore.h @@ -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 ROCKETMQ_CONSUMER_REMOTEBROKEROFFSETSTORE_H_ +#define ROCKETMQ_CONSUMER_REMOTEBROKEROFFSETSTORE_H_ + +#include // std::map +#include // std::mutex + +#include "MQClientInstance.h" +#include "OffsetStore.h" + +namespace rocketmq { + +class RemoteBrokerOffsetStore : public OffsetStore { + public: + RemoteBrokerOffsetStore(MQClientInstance* instance, const std::string& groupName); + virtual ~RemoteBrokerOffsetStore(); + + void load() override; + void updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) override; + int64_t readOffset(const MQMessageQueue& mq, ReadOffsetType type) override; + void persist(const MQMessageQueue& mq) override; + void persistAll(const std::vector& mq) override; + void removeOffset(const MQMessageQueue& mq) override; + + private: + void updateConsumeOffsetToBroker(const MQMessageQueue& mq, int64_t offset); + int64_t fetchConsumeOffsetFromBroker(const MQMessageQueue& mq); + + private: + MQClientInstance* client_instance_; + std::string group_name_; + + std::map offset_table_; + std::mutex lock_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_CONSUMER_REMOTEBROKEROFFSETSTORE_H_ diff --git a/src/consumer/SubscriptionData.cpp b/src/consumer/SubscriptionData.cpp index e67a5b805..ad1f21f4d 100644 --- a/src/consumer/SubscriptionData.cpp +++ b/src/consumer/SubscriptionData.cpp @@ -26,74 +26,42 @@ namespace rocketmq { SubscriptionData::SubscriptionData() { - m_subVersion = UtilAll::currentTimeMillis(); + sub_version_ = UtilAll::currentTimeMillis(); } SubscriptionData::SubscriptionData(const std::string& topic, const std::string& subString) - : m_topic(topic), m_subString(subString) { - m_subVersion = UtilAll::currentTimeMillis(); + : topic_(topic), sub_string_(subString) { + sub_version_ = 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 std::string& SubscriptionData::getTopic() const { - return m_topic; -} - -const std::string& SubscriptionData::getSubString() const { - return m_subString; -} - -void SubscriptionData::setSubString(const std::string& sub) { - m_subString = sub; -} - -int64_t SubscriptionData::getSubVersion() const { - return m_subVersion; -} - -void SubscriptionData::putTagsSet(const std::string& tag) { - m_tagSet.push_back(tag); -} - -bool SubscriptionData::containTag(const std::string& tag) { - return std::find(m_tagSet.begin(), m_tagSet.end(), tag) != m_tagSet.end(); -} - -std::vector& SubscriptionData::getTagsSet() { - return m_tagSet; -} - -void SubscriptionData::putCodeSet(int32_t code) { - m_codeSet.push_back(code); + sub_string_ = other.sub_string_; + sub_version_ = other.sub_version_; + tag_set_ = other.tag_set_; + topic_ = other.topic_; + code_set_ = other.code_set_; } bool SubscriptionData::operator==(const SubscriptionData& other) const { - if (!m_topic.compare(other.m_topic)) { + if (topic_ != other.topic_) { return false; } - if (!m_subString.compare(other.m_subString)) { + if (sub_string_ != other.sub_string_) { return false; } - if (m_subVersion != other.m_subVersion) { + if (sub_version_ != other.sub_version_) { return false; } - if (m_tagSet.size() != other.m_tagSet.size()) { + if (tag_set_.size() != other.tag_set_.size()) { return false; } return true; } bool SubscriptionData::operator<(const SubscriptionData& other) const { - int ret = m_topic.compare(other.m_topic); + int ret = topic_.compare(other.topic_); if (ret == 0) { - return m_subString.compare(other.m_subString) < 0; + return sub_string_.compare(other.sub_string_) < 0; } else { return ret < 0; } @@ -101,15 +69,15 @@ bool SubscriptionData::operator<(const SubscriptionData& other) const { Json::Value SubscriptionData::toJson() const { Json::Value outJson; - outJson["topic"] = m_topic; - outJson["subString"] = m_subString; - outJson["subVersion"] = UtilAll::to_string(m_subVersion); + outJson["topic"] = topic_; + outJson["subString"] = sub_string_; + outJson["subVersion"] = UtilAll::to_string(sub_version_); - for (const auto& tag : m_tagSet) { + for (const auto& tag : tag_set_) { outJson["tagsSet"].append(tag); } - for (const auto& code : m_codeSet) { + for (const auto& code : code_set_) { outJson["codeSet"].append(code); } diff --git a/src/extern/MQClientErrorContainer.cpp b/src/extern/CErrorContainer.cpp similarity index 68% rename from src/extern/MQClientErrorContainer.cpp rename to src/extern/CErrorContainer.cpp index a9e0e5d31..9a5690e67 100644 --- a/src/extern/MQClientErrorContainer.cpp +++ b/src/extern/CErrorContainer.cpp @@ -14,18 +14,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "MQClientErrorContainer.h" +#include "CErrorContainer.h" + +#include // std::move namespace rocketmq { -thread_local std::string MQClientErrorContainer::t_err; +static thread_local std::string tErrorMessage; + +const std::string& CErrorContainer::getErrorMessage() { + return tErrorMessage; +} -void MQClientErrorContainer::setErr(const std::string& str) { - t_err = str; +void CErrorContainer::setErrorMessage(const std::string& message) { + tErrorMessage = message; } -const std::string& MQClientErrorContainer::getErr() { - return t_err; +void CErrorContainer::setErrorMessage(std::string&& message) { + tErrorMessage = std::move(message); } } // namespace rocketmq diff --git a/src/consumer/FindBrokerResult.h b/src/extern/CErrorContainer.h similarity index 71% rename from src/consumer/FindBrokerResult.h rename to src/extern/CErrorContainer.h index d1eaa131b..268627fa0 100644 --- a/src/consumer/FindBrokerResult.h +++ b/src/extern/CErrorContainer.h @@ -14,19 +14,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __FIND_BROKER_RESULT_H__ -#define __FIND_BROKER_RESULT_H__ +#ifndef ROCKETMQ_EXTERN_CERRORCONTAINER_H_ +#define ROCKETMQ_EXTERN_CERRORCONTAINER_H_ -namespace rocketmq { +#include // std::string -struct FindBrokerResult { - FindBrokerResult(const std::string& sbrokerAddr, bool bslave) : brokerAddr(sbrokerAddr), slave(bslave) {} +namespace rocketmq { +class CErrorContainer { public: - std::string brokerAddr; - bool slave; + static const std::string& getErrorMessage(); + static void setErrorMessage(const std::string& message); + static void setErrorMessage(std::string&& message); }; } // namespace rocketmq -#endif // __FIND_BROKER_RESULT_H__ +#endif // ROCKETMQ_EXTERN_MQERRORCONTAINER_H_ diff --git a/src/extern/CErrorMessage.cpp b/src/extern/CErrorMessage.cpp index bb156c9c4..ce61f194e 100644 --- a/src/extern/CErrorMessage.cpp +++ b/src/extern/CErrorMessage.cpp @@ -16,7 +16,7 @@ */ #include "c/CErrorMessage.h" -#include "MQClientErrorContainer.h" +#include "CErrorContainer.h" #ifdef __cplusplus extern "C" { @@ -25,7 +25,7 @@ extern "C" { using namespace rocketmq; const char* GetLatestErrorMessage() { - return MQClientErrorContainer::getErr().c_str(); + return CErrorContainer::getErrorMessage().c_str(); } #ifdef __cplusplus diff --git a/src/extern/CProducer.cpp b/src/extern/CProducer.cpp index cf2df53ff..33dd4da45 100644 --- a/src/extern/CProducer.cpp +++ b/src/extern/CProducer.cpp @@ -20,10 +20,10 @@ #include #include +#include "CErrorContainer.h" #include "ClientRPCHook.h" #include "DefaultMQProducer.h" #include "Logging.h" -#include "MQClientErrorContainer.h" #include "TransactionMQProducer.h" #include "UtilAll.h" @@ -32,30 +32,30 @@ using namespace rocketmq; class LocalTransactionExecutorInner { public: LocalTransactionExecutorInner(CLocalTransactionExecutorCallback callback, CMessage* message, void* userData) - : m_excutorCallback(callback), m_message(message), m_userData(userData) {} + : excutor_callback_(callback), message_(message), user_data_(userData) {} ~LocalTransactionExecutorInner() = default; public: - CLocalTransactionExecutorCallback m_excutorCallback; - CMessage* m_message; - void* m_userData; + CLocalTransactionExecutorCallback excutor_callback_; + CMessage* message_; + void* user_data_; }; class LocalTransactionListenerInner : public TransactionListener { public: LocalTransactionListenerInner(CProducer* producer, CLocalTransactionCheckerCallback callback, void* userData) - : m_producer(producer), m_checkerCallback(callback), m_userData(userData) {} + : producer_(producer), checker_callback_(callback), user_data_(userData) {} ~LocalTransactionListenerInner() = default; LocalTransactionState executeLocalTransaction(const MQMessage& message, void* arg) override { - if (m_checkerCallback == nullptr) { + if (checker_callback_ == nullptr) { return LocalTransactionState::UNKNOWN; } auto* msg = reinterpret_cast(const_cast(&message)); auto* executorInner = reinterpret_cast(arg); - auto status = executorInner->m_excutorCallback(m_producer, msg, executorInner->m_userData); + auto status = executorInner->excutor_callback_(producer_, msg, executorInner->user_data_); switch (status) { case E_COMMIT_TRANSACTION: return LocalTransactionState::COMMIT_MESSAGE; @@ -67,11 +67,11 @@ class LocalTransactionListenerInner : public TransactionListener { } LocalTransactionState checkLocalTransaction(const MQMessageExt& message) override { - if (m_checkerCallback == NULL) { + if (checker_callback_ == NULL) { return LocalTransactionState::UNKNOWN; } auto* msgExt = reinterpret_cast(const_cast(&message)); - auto status = m_checkerCallback(m_producer, msgExt, m_userData); + auto status = checker_callback_(producer_, msgExt, user_data_); switch (status) { case E_COMMIT_TRANSACTION: return LocalTransactionState::COMMIT_MESSAGE; @@ -83,9 +83,9 @@ class LocalTransactionListenerInner : public TransactionListener { } private: - CProducer* m_producer; - CLocalTransactionCheckerCallback m_checkerCallback; - void* m_userData; + CProducer* producer_; + CLocalTransactionCheckerCallback checker_callback_; + void* user_data_; }; class SelectMessageQueueInner : public MessageQueueSelector { @@ -99,17 +99,17 @@ class SelectMessageQueueInner : public MessageQueueSelector { class SelectMessageQueue : public MessageQueueSelector { public: - SelectMessageQueue(QueueSelectorCallback callback) { m_callback = callback; } + SelectMessageQueue(QueueSelectorCallback callback) { callback_ = callback; } MQMessageQueue select(const std::vector& mqs, const MQMessage& msg, void* arg) override { auto* message = reinterpret_cast(const_cast(&msg)); // Get the index of sending MQMessageQueue through callback function. - auto index = m_callback(mqs.size(), message, arg); + auto index = callback_(mqs.size(), message, arg); return mqs[index]; } private: - QueueSelectorCallback m_callback; + QueueSelectorCallback callback_; }; class COnSendCallback : public AutoDeleteSendCallback { @@ -118,10 +118,10 @@ class COnSendCallback : public AutoDeleteSendCallback { COnSendExceptionCallback sendExceptionCallback, CMessage* message, void* userData) - : m_sendSuccessCallback(sendSuccessCallback), - m_sendExceptionCallback(sendExceptionCallback), - m_message(message), - m_userData(userData) {} + : send_success_callback_(sendSuccessCallback), + send_exception_callback_(sendExceptionCallback), + message_(message), + user_data_(userData) {} virtual ~COnSendCallback() = default; @@ -131,7 +131,7 @@ class COnSendCallback : public AutoDeleteSendCallback { 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_sendSuccessCallback(result, m_message, m_userData); + send_success_callback_(result, message_, user_data_); } void onException(MQException& e) noexcept override { @@ -140,20 +140,20 @@ class COnSendCallback : public AutoDeleteSendCallback { 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_sendExceptionCallback(exception, m_message, m_userData); + send_exception_callback_(exception, message_, user_data_); } private: - COnSendSuccessCallback m_sendSuccessCallback; - COnSendExceptionCallback m_sendExceptionCallback; - CMessage* m_message; - void* m_userData; + COnSendSuccessCallback send_success_callback_; + COnSendExceptionCallback send_exception_callback_; + CMessage* message_; + void* user_data_; }; class CSendCallback : public AutoDeleteSendCallback { public: CSendCallback(CSendSuccessCallback sendSuccessCallback, CSendExceptionCallback sendExceptionCallback) - : m_sendSuccessCallback(sendSuccessCallback), m_sendExceptionCallback(sendExceptionCallback) {} + : send_success_callback_(sendSuccessCallback), send_exception_callback_(sendExceptionCallback) {} virtual ~CSendCallback() = default; @@ -163,7 +163,7 @@ class CSendCallback : public AutoDeleteSendCallback { 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_sendSuccessCallback(result); + send_success_callback_(result); } void onException(MQException& e) noexcept override { @@ -172,12 +172,12 @@ class CSendCallback : public AutoDeleteSendCallback { 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_sendExceptionCallback(exception); + send_exception_callback_(exception); } private: - CSendSuccessCallback m_sendSuccessCallback; - CSendExceptionCallback m_sendExceptionCallback; + CSendSuccessCallback send_success_callback_; + CSendExceptionCallback send_exception_callback_; }; CProducer* CreateProducer(const char* groupId) { @@ -218,7 +218,7 @@ int StartProducer(CProducer* producer) { try { reinterpret_cast(producer)->start(); } catch (std::exception& e) { - MQClientErrorContainer::setErr(std::string(e.what())); + CErrorContainer::setErrorMessage(e.what()); return PRODUCER_START_FAILED; } return OK; @@ -278,7 +278,7 @@ int SendMessageSync(CProducer* producer, CMessage* msg, CSendResult* result) { strncpy(result->msgId, sendResult.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1); result->msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0; } catch (std::exception& e) { - MQClientErrorContainer::setErr(std::string(e.what())); + CErrorContainer::setErrorMessage(e.what()); return PRODUCER_SEND_SYNC_FAILED; } return OK; @@ -371,7 +371,7 @@ int SendMessageOnewayOrderly(CProducer* producer, CMessage* msg, QueueSelectorCa SelectMessageQueue selectMessageQueue(selector); defaultMQProducer->sendOneway(*message, &selectMessageQueue, arg); } catch (std::exception& e) { - MQClientErrorContainer::setErr(std::string(e.what())); + CErrorContainer::setErrorMessage(e.what()); return PRODUCER_SEND_ONEWAY_FAILED; } return OK; @@ -410,14 +410,14 @@ int SendMessageOrderly(CProducer* producer, try { // Constructing SelectMessageQueue objects through function pointer callback SelectMessageQueue selectMessageQueue(selectorCallback); - SendResult sendResult = defaultMQProducer->send(*message, &selectMessageQueue, arg); + SendResult send_result = defaultMQProducer->send(*message, &selectMessageQueue, arg); // 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->sendStatus = CSendStatus((int)send_result.getSendStatus()); + result->offset = send_result.getQueueOffset(); + strncpy(result->msgId, send_result.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1); result->msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0; } catch (std::exception& e) { - MQClientErrorContainer::setErr(std::string(e.what())); + CErrorContainer::setErrorMessage(e.what()); return PRODUCER_SEND_ORDERLY_FAILED; } return OK; @@ -433,14 +433,14 @@ int SendMessageOrderlyByShardingKey(CProducer* producer, CMessage* msg, const ch // Constructing SelectMessageQueue objects through function pointer callback int retryTimes = 3; SelectMessageQueueInner selectMessageQueue; - SendResult sendResult = defaultMQProducer->send(*message, &selectMessageQueue, (void*)shardingKey, retryTimes); + SendResult send_esult = defaultMQProducer->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->sendStatus = CSendStatus((int)send_esult.getSendStatus()); + result->offset = send_esult.getQueueOffset(); + strncpy(result->msgId, send_esult.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1); result->msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0; } catch (std::exception& e) { - MQClientErrorContainer::setErr(std::string(e.what())); + CErrorContainer::setErrorMessage(e.what()); return PRODUCER_SEND_ORDERLY_FAILED; } return OK; @@ -458,13 +458,13 @@ int SendMessageTransaction(CProducer* producer, auto* transactionMQProducer = reinterpret_cast(producer); auto* message = reinterpret_cast(msg); LocalTransactionExecutorInner executorInner(callback, msg, userData); - auto sendResult = transactionMQProducer->sendMessageInTransaction(*message, &executorInner); - result->sendStatus = CSendStatus((int)sendResult.getSendStatus()); - result->offset = sendResult.getQueueOffset(); - strncpy(result->msgId, sendResult.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1); + auto send_result = transactionMQProducer->sendMessageInTransaction(*message, &executorInner); + result->sendStatus = CSendStatus((int)send_result.getSendStatus()); + result->offset = send_result.getQueueOffset(); + strncpy(result->msgId, send_result.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1); result->msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0; } catch (std::exception& e) { - MQClientErrorContainer::setErr(std::string(e.what())); + CErrorContainer::setErrorMessage(e.what()); return PRODUCER_SEND_TRANSACTION_FAILED; } return OK; @@ -511,7 +511,7 @@ int SetProducerLogFileNumAndSize(CProducer* producer, int fileNum, long fileSize if (producer == NULL) { return NULL_POINTER; } - ALOG_ADAPTER->setLogFileNumAndSize(fileNum, fileSize); + DEFAULT_LOG_ADAPTER->setLogFileNumAndSize(fileNum, fileSize); return OK; } @@ -519,7 +519,7 @@ int SetProducerLogLevel(CProducer* producer, CLogLevel level) { if (producer == NULL) { return NULL_POINTER; } - ALOG_ADAPTER->setLogLevel((elogLevel)level); + DEFAULT_LOG_ADAPTER->set_log_level((LogLevel)level); return OK; } diff --git a/src/extern/CPullConsumer.cpp b/src/extern/CPullConsumer.cpp index f3fe10356..bce4b6148 100644 --- a/src/extern/CPullConsumer.cpp +++ b/src/extern/CPullConsumer.cpp @@ -18,10 +18,10 @@ #include +#include "CErrorContainer.h" #include "ClientRPCHook.h" #include "DefaultMQPullConsumer.h" #include "Logging.h" -#include "MQClientErrorContainer.h" using namespace rocketmq; @@ -48,7 +48,7 @@ int StartPullConsumer(CPullConsumer* consumer) { try { reinterpret_cast(consumer)->start(); } catch (std::exception& e) { - MQClientErrorContainer::setErr(std::string(e.what())); + CErrorContainer::setErrorMessage(e.what()); return PULLCONSUMER_START_FAILED; } return OK; @@ -118,7 +118,7 @@ int SetPullConsumerLogFileNumAndSize(CPullConsumer* consumer, int fileNum, long if (consumer == NULL) { return NULL_POINTER; } - ALOG_ADAPTER->setLogFileNumAndSize(fileNum, fileSize); + DEFAULT_LOG_ADAPTER->setLogFileNumAndSize(fileNum, fileSize); return OK; } @@ -126,7 +126,7 @@ int SetPullConsumerLogLevel(CPullConsumer* consumer, CLogLevel level) { if (consumer == NULL) { return NULL_POINTER; } - ALOG_ADAPTER->setLogLevel((elogLevel)level); + DEFAULT_LOG_ADAPTER->set_log_level((LogLevel)level); return OK; } @@ -150,15 +150,15 @@ int FetchSubscriptionMessageQueues(CPullConsumer* consumer, const char* topic, C } 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(); + strncpy(temMQ[index].topic, iter->topic().c_str(), MAX_TOPIC_LENGTH - 1); + strncpy(temMQ[index].brokerName, iter->broker_name().c_str(), MAX_BROKER_NAME_ID_LENGTH - 1); + temMQ[index].queueId = iter->queue_id(); } *mqs = temMQ; } catch (MQException& e) { *size = 0; *mqs = NULL; - MQClientErrorContainer::setErr(std::string(e.what())); + CErrorContainer::setErrorMessage(e.what()); return PULLCONSUMER_FETCH_MQ_FAILED; } return OK; @@ -186,7 +186,7 @@ CPullResult Pull(CPullConsumer* consumer, cppPullResult = reinterpret_cast(consumer)->pull(messageQueue, subExpression, offset, maxNums); } catch (std::exception& e) { - MQClientErrorContainer::setErr(std::string(e.what())); + CErrorContainer::setErrorMessage(e.what()); cppPullResult.set_pull_status(BROKER_TIMEOUT); } @@ -242,7 +242,7 @@ int ReleasePullResult(CPullResult pullResult) { try { delete ((PullResult*)pullResult.pData); } catch (std::exception& e) { - MQClientErrorContainer::setErr(std::string(e.what())); + CErrorContainer::setErrorMessage(e.what()); return NULL_POINTER; } } diff --git a/src/extern/CPushConsumer.cpp b/src/extern/CPushConsumer.cpp index c8755271c..6287a2e1c 100644 --- a/src/extern/CPushConsumer.cpp +++ b/src/extern/CPushConsumer.cpp @@ -18,28 +18,28 @@ #include // std::map +#include "CErrorContainer.h" #include "ClientRPCHook.h" #include "DefaultMQPushConsumer.h" #include "Logging.h" -#include "MQClientErrorContainer.h" using namespace rocketmq; -class MessageListenerInner : public MessageListenerConcurrently { +class MessageListenerConcurrentlyInner : public MessageListenerConcurrently { public: - MessageListenerInner(CPushConsumer* consumer, MessageCallBack callback) - : m_consumer(consumer), m_msgReceivedCallback(callback) {} + MessageListenerConcurrentlyInner(CPushConsumer* consumer, MessageCallBack callback) + : consumer_(consumer), msg_received_callback_(callback) {} - ~MessageListenerInner() = default; + ~MessageListenerConcurrentlyInner() = default; ConsumeStatus consumeMessage(std::vector& msgs) override { // to do user call back - if (m_msgReceivedCallback == nullptr) { + if (msg_received_callback_ == nullptr) { return RECONSUME_LATER; } for (auto msg : msgs) { auto* message = reinterpret_cast(&msg); - if (m_msgReceivedCallback(m_consumer, message) != E_CONSUME_SUCCESS) { + if (msg_received_callback_(consumer_, message) != E_CONSUME_SUCCESS) { return RECONSUME_LATER; } } @@ -47,22 +47,22 @@ class MessageListenerInner : public MessageListenerConcurrently { } private: - CPushConsumer* m_consumer; - MessageCallBack m_msgReceivedCallback; + CPushConsumer* consumer_; + MessageCallBack msg_received_callback_; }; class MessageListenerOrderlyInner : public MessageListenerOrderly { public: MessageListenerOrderlyInner(CPushConsumer* consumer, MessageCallBack callback) - : m_consumer(consumer), m_msgReceivedCallback(callback) {} + : consumer_(consumer), msg_received_callback_(callback) {} ConsumeStatus consumeMessage(std::vector& msgs) override { - if (m_msgReceivedCallback == nullptr) { + if (msg_received_callback_ == nullptr) { return RECONSUME_LATER; } for (auto msg : msgs) { auto* message = reinterpret_cast(&msg); - if (m_msgReceivedCallback(m_consumer, message) != E_CONSUME_SUCCESS) { + if (msg_received_callback_(consumer_, message) != E_CONSUME_SUCCESS) { return RECONSUME_LATER; } } @@ -70,8 +70,8 @@ class MessageListenerOrderlyInner : public MessageListenerOrderly { } private: - CPushConsumer* m_consumer; - MessageCallBack m_msgReceivedCallback; + CPushConsumer* consumer_; + MessageCallBack msg_received_callback_; }; CPushConsumer* CreatePushConsumer(const char* groupId) { @@ -98,7 +98,7 @@ int StartPushConsumer(CPushConsumer* consumer) { try { reinterpret_cast(consumer)->start(); } catch (std::exception& e) { - MQClientErrorContainer::setErr(std::string(e.what())); + CErrorContainer::setErrorMessage(e.what()); return PUSHCONSUMER_START_FAILED; } return OK; @@ -155,30 +155,30 @@ int RegisterMessageCallback(CPushConsumer* consumer, MessageCallBack callback) { if (consumer == NULL || callback == NULL) { return NULL_POINTER; } - auto* listenerInner = new MessageListenerInner(consumer, callback); + auto* listenerInner = new MessageListenerConcurrentlyInner(consumer, callback); reinterpret_cast(consumer)->registerMessageListener(listenerInner); return OK; } -int RegisterMessageCallbackOrderly(CPushConsumer* consumer, MessageCallBack callback) { - if (consumer == NULL || callback == NULL) { +int UnregisterMessageCallback(CPushConsumer* consumer) { + if (consumer == NULL) { return NULL_POINTER; } - auto* messageListenerOrderlyInner = new MessageListenerOrderlyInner(consumer, callback); - reinterpret_cast(consumer)->registerMessageListener(messageListenerOrderlyInner); + auto* listenerInner = reinterpret_cast(consumer)->getMessageListener(); + delete listenerInner; return OK; } -int UnregisterMessageCallbackOrderly(CPushConsumer* consumer) { - if (consumer == NULL) { +int RegisterMessageCallbackOrderly(CPushConsumer* consumer, MessageCallBack callback) { + if (consumer == NULL || callback == NULL) { return NULL_POINTER; } - auto* listenerInner = reinterpret_cast(consumer)->getMessageListener(); - delete listenerInner; + auto* messageListenerOrderlyInner = new MessageListenerOrderlyInner(consumer, callback); + reinterpret_cast(consumer)->registerMessageListener(messageListenerOrderlyInner); return OK; } -int UnregisterMessageCallback(CPushConsumer* consumer) { +int UnregisterMessageCallbackOrderly(CPushConsumer* consumer) { if (consumer == NULL) { return NULL_POINTER; } @@ -258,7 +258,7 @@ int SetPushConsumerLogFileNumAndSize(CPushConsumer* consumer, int fileNum, long if (consumer == NULL) { return NULL_POINTER; } - ALOG_ADAPTER->setLogFileNumAndSize(fileNum, fileSize); + DEFAULT_LOG_ADAPTER->setLogFileNumAndSize(fileNum, fileSize); return OK; } @@ -266,6 +266,6 @@ int SetPushConsumerLogLevel(CPushConsumer* consumer, CLogLevel level) { if (consumer == NULL) { return NULL_POINTER; } - ALOG_ADAPTER->setLogLevel((elogLevel)level); + DEFAULT_LOG_ADAPTER->set_log_level((LogLevel)level); return OK; } diff --git a/src/log/Logging.cpp b/src/log/Logging.cpp index b7bd051cf..8b77528ac 100644 --- a/src/log/Logging.cpp +++ b/src/log/Logging.cpp @@ -16,7 +16,7 @@ */ #include "Logging.h" -#include +#include // std::cerr, std::endl #if SPDLOG_VER_MAJOR >= 1 #include @@ -29,103 +29,94 @@ namespace rocketmq { -logAdapter::~logAdapter() { - spdlog::drop("default"); -} - -logAdapter* logAdapter::getLogInstance() { - static logAdapter singleton_; +LogAdapter* LogAdapter::getLogInstance() { + static LogAdapter singleton_; return &singleton_; } -logAdapter::logAdapter() : m_logLevel(eLOG_LEVEL_INFO) { - std::string logDir; +LogAdapter::LogAdapter() : log_level_(LOG_LEVEL_INFO) { + std::string log_dir; const char* dir = std::getenv(ROCKETMQ_CPP_LOG_DIR_ENV.c_str()); if (dir != nullptr && dir[0] != '\0') { // FIXME: replace '~' by home directory. - logDir = dir; + log_dir = dir; } else { - logDir = UtilAll::getHomeDirectory(); - logDir.append("/logs/rocketmq-cpp/"); + log_dir = UtilAll::getHomeDirectory(); + log_dir.append("/logs/rocketmq-cpp/"); } - if (logDir[logDir.size() - 1] != '/') { - logDir.append("/"); + if (log_dir[log_dir.size() - 1] != '/') { + log_dir.append("/"); } - if (!UtilAll::existDirectory(logDir)) { - UtilAll::createDirectory(logDir); + if (!UtilAll::existDirectory(log_dir)) { + UtilAll::createDirectory(log_dir); } - if (!UtilAll::existDirectory(logDir)) { + if (!UtilAll::existDirectory(log_dir)) { std::cerr << "create log dir error, will exit" << std::endl; exit(1); } std::string fileName = UtilAll::to_string(UtilAll::getProcessId()) + "_" + "rocketmq-cpp.log"; - m_logFile = logDir + fileName; + log_file_ = log_dir + fileName; #if SPDLOG_VER_MAJOR >= 1 spdlog::init_thread_pool(8192, 1); - auto rotating_sink = std::make_shared(m_logFile, 1024 * 1024 * 100, 3); + auto rotating_sink = std::make_shared(log_file_, 1024 * 1024 * 100, 3); rotating_sink->set_level(spdlog::level::debug); rotating_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [thread@%t] - %v"); - m_logSinks.push_back(rotating_sink); + log_sinks_.push_back(rotating_sink); - m_logger = std::make_shared("default", m_logSinks.begin(), m_logSinks.end(), - spdlog::thread_pool(), spdlog::async_overflow_policy::block); + logger_ = std::make_shared("default", log_sinks_.begin(), log_sinks_.end(), + spdlog::thread_pool(), spdlog::async_overflow_policy::block); // register it if you need to access it globally - spdlog::register_logger(m_logger); + spdlog::register_logger(logger_); // when an error occurred, flush disk immediately - m_logger->flush_on(spdlog::level::err); + logger_->flush_on(spdlog::level::err); spdlog::flush_every(std::chrono::seconds(3)); #else size_t q_size = 4096; spdlog::set_async_mode(q_size); - m_logger = spdlog::rotating_logger_mt("default", m_logFile, 1024 * 1024 * 100, 3); - m_logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [thread@%t] - %v"); + logger_ = spdlog::rotating_logger_mt("default", log_file_, 1024 * 1024 * 100, 3); + logger_->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [thread@%t] - %v"); #endif - setLogLevelInner(m_logLevel); + setLogLevelInner(log_level_); +} + +LogAdapter::~LogAdapter() { + spdlog::drop("default"); } -void logAdapter::setLogLevelInner(elogLevel logLevel) { - switch (logLevel) { - case eLOG_LEVEL_FATAL: - m_logger->set_level(spdlog::level::critical); +void LogAdapter::setLogLevelInner(LogLevel log_level) { + switch (log_level) { + case LOG_LEVEL_FATAL: + logger_->set_level(spdlog::level::critical); break; - case eLOG_LEVEL_ERROR: - m_logger->set_level(spdlog::level::err); + case LOG_LEVEL_ERROR: + logger_->set_level(spdlog::level::err); break; - case eLOG_LEVEL_WARN: - m_logger->set_level(spdlog::level::warn); + case LOG_LEVEL_WARN: + logger_->set_level(spdlog::level::warn); break; - case eLOG_LEVEL_INFO: - m_logger->set_level(spdlog::level::info); + case LOG_LEVEL_INFO: + logger_->set_level(spdlog::level::info); break; - case eLOG_LEVEL_DEBUG: - m_logger->set_level(spdlog::level::debug); + case LOG_LEVEL_DEBUG: + logger_->set_level(spdlog::level::debug); break; - case eLOG_LEVEL_TRACE: - m_logger->set_level(spdlog::level::trace); + case LOG_LEVEL_TRACE: + logger_->set_level(spdlog::level::trace); break; default: - m_logger->set_level(spdlog::level::info); + logger_->set_level(spdlog::level::info); break; } } -void logAdapter::setLogLevel(elogLevel logLevel) { - m_logLevel = logLevel; - setLogLevelInner(logLevel); -} - -elogLevel logAdapter::getLogLevel() { - return m_logLevel; -} - -void logAdapter::setLogFileNumAndSize(int logNum, int sizeOfPerFile) {} +void LogAdapter::setLogFileNumAndSize(int logNum, int sizeOfPerFile) {} } // namespace rocketmq diff --git a/src/log/Logging.h b/src/log/Logging.h index e60e3061f..6c361e577 100644 --- a/src/log/Logging.h +++ b/src/log/Logging.h @@ -14,11 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __ROCKETMQ_LOGGING_H__ -#define __ROCKETMQ_LOGGING_H__ +#ifndef ROCKETMQ_LOG_LOGGING_H_ +#define ROCKETMQ_LOG_LOGGING_H_ -#include -#include +#include // std::shared_ptr +#include // std::string +#include // std::vector // clang-format off #include @@ -27,44 +28,48 @@ namespace rocketmq { -enum elogLevel { - eLOG_LEVEL_FATAL = 1, - eLOG_LEVEL_ERROR = 2, - eLOG_LEVEL_WARN = 3, - eLOG_LEVEL_INFO = 4, - eLOG_LEVEL_DEBUG = 5, - eLOG_LEVEL_TRACE = 6, - eLOG_LEVEL_LEVEL_NUM = 7 +enum LogLevel { + LOG_LEVEL_FATAL = 1, + LOG_LEVEL_ERROR = 2, + LOG_LEVEL_WARN = 3, + LOG_LEVEL_INFO = 4, + LOG_LEVEL_DEBUG = 5, + LOG_LEVEL_TRACE = 6, + LOG_LEVEL_LEVEL_NUM = 7 }; -class logAdapter { +class LogAdapter { public: - ~logAdapter(); + virtual ~LogAdapter(); - static logAdapter* getLogInstance(); + static LogAdapter* getLogInstance(); - void setLogLevel(elogLevel logLevel); - elogLevel getLogLevel(); + inline spdlog::logger* getSeverityLogger() { return logger_.get(); } void setLogFileNumAndSize(int logNum, int sizeOfPerFile); - spdlog::logger* getSeverityLogger() { return m_logger.get(); } + inline LogLevel log_level() const { return log_level_; } + inline void set_log_level(LogLevel logLevel) { + log_level_ = logLevel; + setLogLevelInner(logLevel); + } private: - logAdapter(); - void setLogLevelInner(elogLevel logLevel); + LogAdapter(); + void setLogLevelInner(LogLevel logLevel); - elogLevel m_logLevel; - std::string m_logFile; + private: + LogLevel log_level_; + std::string log_file_; - std::shared_ptr m_logger; + std::shared_ptr logger_; #if SPDLOG_VER_MAJOR >= 1 - std::vector m_logSinks; + std::vector log_sinks_; #endif }; -#define ALOG_ADAPTER logAdapter::getLogInstance() -#define AGENT_LOGGER ALOG_ADAPTER->getSeverityLogger() +#define DEFAULT_LOG_ADAPTER LogAdapter::getLogInstance() +#define DEFAULT_LOGGER DEFAULT_LOG_ADAPTER->getSeverityLogger() #define SPDLOG_PRINTF(logger, level, format, ...) \ do { \ @@ -74,23 +79,23 @@ class logAdapter { } \ } while (0) -#define LOG_FATAL(...) SPDLOG_PRINTF(AGENT_LOGGER, spdlog::level::critical, __VA_ARGS__) -#define LOG_ERROR(...) SPDLOG_PRINTF(AGENT_LOGGER, spdlog::level::err, __VA_ARGS__) -#define LOG_WARN(...) SPDLOG_PRINTF(AGENT_LOGGER, spdlog::level::warn, __VA_ARGS__) -#define LOG_INFO(...) SPDLOG_PRINTF(AGENT_LOGGER, spdlog::level::info, __VA_ARGS__) -#define LOG_DEBUG(...) SPDLOG_PRINTF(AGENT_LOGGER, spdlog::level::debug, __VA_ARGS__) +#define LOG_FATAL(...) SPDLOG_PRINTF(DEFAULT_LOGGER, spdlog::level::critical, __VA_ARGS__) +#define LOG_ERROR(...) SPDLOG_PRINTF(DEFAULT_LOGGER, spdlog::level::err, __VA_ARGS__) +#define LOG_WARN(...) SPDLOG_PRINTF(DEFAULT_LOGGER, spdlog::level::warn, __VA_ARGS__) +#define LOG_INFO(...) SPDLOG_PRINTF(DEFAULT_LOGGER, spdlog::level::info, __VA_ARGS__) +#define LOG_DEBUG(...) SPDLOG_PRINTF(DEFAULT_LOGGER, spdlog::level::debug, __VA_ARGS__) #define SPDLOG_EXT(logger, level, format, ...) \ do { \ logger->log(level, format " [{}:{}]", ##__VA_ARGS__, __FUNCTION__, __LINE__); \ } while (0) -#define LOG_FATAL_NEW(...) SPDLOG_EXT(AGENT_LOGGER, spdlog::level::critical, __VA_ARGS__) -#define LOG_ERROR_NEW(...) SPDLOG_EXT(AGENT_LOGGER, spdlog::level::err, __VA_ARGS__) -#define LOG_WARN_NEW(...) SPDLOG_EXT(AGENT_LOGGER, spdlog::level::warn, __VA_ARGS__) -#define LOG_INFO_NEW(...) SPDLOG_EXT(AGENT_LOGGER, spdlog::level::info, __VA_ARGS__) -#define LOG_DEBUG_NEW(...) SPDLOG_EXT(AGENT_LOGGER, spdlog::level::debug, __VA_ARGS__) +#define LOG_FATAL_NEW(...) SPDLOG_EXT(DEFAULT_LOGGER, spdlog::level::critical, __VA_ARGS__) +#define LOG_ERROR_NEW(...) SPDLOG_EXT(DEFAULT_LOGGER, spdlog::level::err, __VA_ARGS__) +#define LOG_WARN_NEW(...) SPDLOG_EXT(DEFAULT_LOGGER, spdlog::level::warn, __VA_ARGS__) +#define LOG_INFO_NEW(...) SPDLOG_EXT(DEFAULT_LOGGER, spdlog::level::info, __VA_ARGS__) +#define LOG_DEBUG_NEW(...) SPDLOG_EXT(DEFAULT_LOGGER, spdlog::level::debug, __VA_ARGS__) } // namespace rocketmq -#endif // __ROCKETMQ_LOGGING_H__ +#endif // ROCKETMQ_LOG_LOGGING_H_ diff --git a/src/message/MQMessageExt.cpp b/src/message/MQMessageExt.cpp index 09b7e2c2a..957c02392 100644 --- a/src/message/MQMessageExt.cpp +++ b/src/message/MQMessageExt.cpp @@ -34,115 +34,115 @@ MQMessageExt::MQMessageExt(int queueId, MQMessageExt::~MQMessageExt() = default; int32_t MQMessageExt::getStoreSize() const { - return std::dynamic_pointer_cast(message_impl_)->getStoreSize(); + return dynamic_cast(message_impl_.get())->getStoreSize(); } void MQMessageExt::setStoreSize(int32_t storeSize) { - std::dynamic_pointer_cast(message_impl_)->setStoreSize(storeSize); + dynamic_cast(message_impl_.get())->setStoreSize(storeSize); } int32_t MQMessageExt::getBodyCRC() const { - return std::dynamic_pointer_cast(message_impl_)->getBodyCRC(); + return dynamic_cast(message_impl_.get())->getBodyCRC(); } void MQMessageExt::setBodyCRC(int32_t bodyCRC) { - std::dynamic_pointer_cast(message_impl_)->setBodyCRC(bodyCRC); + dynamic_cast(message_impl_.get())->setBodyCRC(bodyCRC); } int32_t MQMessageExt::getQueueId() const { - return std::dynamic_pointer_cast(message_impl_)->getQueueId(); + return dynamic_cast(message_impl_.get())->getQueueId(); } void MQMessageExt::setQueueId(int32_t queueId) { - std::dynamic_pointer_cast(message_impl_)->setQueueId(queueId); + dynamic_cast(message_impl_.get())->setQueueId(queueId); } int64_t MQMessageExt::getQueueOffset() const { - return std::dynamic_pointer_cast(message_impl_)->getQueueOffset(); + return dynamic_cast(message_impl_.get())->getQueueOffset(); } void MQMessageExt::setQueueOffset(int64_t queueOffset) { - std::dynamic_pointer_cast(message_impl_)->setQueueOffset(queueOffset); + dynamic_cast(message_impl_.get())->setQueueOffset(queueOffset); } int64_t MQMessageExt::getCommitLogOffset() const { - return std::dynamic_pointer_cast(message_impl_)->getCommitLogOffset(); + return dynamic_cast(message_impl_.get())->getCommitLogOffset(); } void MQMessageExt::setCommitLogOffset(int64_t physicOffset) { - std::dynamic_pointer_cast(message_impl_)->setCommitLogOffset(physicOffset); + dynamic_cast(message_impl_.get())->setCommitLogOffset(physicOffset); } int32_t MQMessageExt::getSysFlag() const { - return std::dynamic_pointer_cast(message_impl_)->getSysFlag(); + return dynamic_cast(message_impl_.get())->getSysFlag(); } void MQMessageExt::setSysFlag(int32_t sysFlag) { - std::dynamic_pointer_cast(message_impl_)->setSysFlag(sysFlag); + dynamic_cast(message_impl_.get())->setSysFlag(sysFlag); } int64_t MQMessageExt::getBornTimestamp() const { - return std::dynamic_pointer_cast(message_impl_)->getBornTimestamp(); + return dynamic_cast(message_impl_.get())->getBornTimestamp(); } void MQMessageExt::setBornTimestamp(int64_t bornTimestamp) { - std::dynamic_pointer_cast(message_impl_)->setBornTimestamp(bornTimestamp); + dynamic_cast(message_impl_.get())->setBornTimestamp(bornTimestamp); } std::string MQMessageExt::getBornHostString() const { - return std::dynamic_pointer_cast(message_impl_)->getBornHostString(); + return dynamic_cast(message_impl_.get())->getBornHostString(); } const struct sockaddr* MQMessageExt::getBornHost() const { - return std::dynamic_pointer_cast(message_impl_)->getBornHost(); + return dynamic_cast(message_impl_.get())->getBornHost(); } void MQMessageExt::setBornHost(const struct sockaddr* bornHost) { - std::dynamic_pointer_cast(message_impl_)->setBornHost(bornHost); + dynamic_cast(message_impl_.get())->setBornHost(bornHost); } int64_t MQMessageExt::getStoreTimestamp() const { - return std::dynamic_pointer_cast(message_impl_)->getStoreTimestamp(); + return dynamic_cast(message_impl_.get())->getStoreTimestamp(); } void MQMessageExt::setStoreTimestamp(int64_t storeTimestamp) { - std::dynamic_pointer_cast(message_impl_)->setStoreTimestamp(storeTimestamp); + dynamic_cast(message_impl_.get())->setStoreTimestamp(storeTimestamp); } std::string MQMessageExt::getStoreHostString() const { - return std::dynamic_pointer_cast(message_impl_)->getStoreHostString(); + return dynamic_cast(message_impl_.get())->getStoreHostString(); } const struct sockaddr* MQMessageExt::getStoreHost() const { - return std::dynamic_pointer_cast(message_impl_)->getStoreHost(); + return dynamic_cast(message_impl_.get())->getStoreHost(); } void MQMessageExt::setStoreHost(const struct sockaddr* storeHost) { - std::dynamic_pointer_cast(message_impl_)->setStoreHost(storeHost); + dynamic_cast(message_impl_.get())->setStoreHost(storeHost); } int32_t MQMessageExt::getReconsumeTimes() const { - return std::dynamic_pointer_cast(message_impl_)->getReconsumeTimes(); + return dynamic_cast(message_impl_.get())->getReconsumeTimes(); } void MQMessageExt::setReconsumeTimes(int32_t reconsumeTimes) { - std::dynamic_pointer_cast(message_impl_)->setReconsumeTimes(reconsumeTimes); + dynamic_cast(message_impl_.get())->setReconsumeTimes(reconsumeTimes); } int64_t MQMessageExt::getPreparedTransactionOffset() const { - return std::dynamic_pointer_cast(message_impl_)->getPreparedTransactionOffset(); + return dynamic_cast(message_impl_.get())->getPreparedTransactionOffset(); } void MQMessageExt::setPreparedTransactionOffset(int64_t preparedTransactionOffset) { - std::dynamic_pointer_cast(message_impl_)->setPreparedTransactionOffset(preparedTransactionOffset); + dynamic_cast(message_impl_.get())->setPreparedTransactionOffset(preparedTransactionOffset); } const std::string& MQMessageExt::getMsgId() const { - return std::dynamic_pointer_cast(message_impl_)->getMsgId(); + return dynamic_cast(message_impl_.get())->getMsgId(); } void MQMessageExt::setMsgId(const std::string& msgId) { - std::dynamic_pointer_cast(message_impl_)->setMsgId(msgId); + dynamic_cast(message_impl_.get())->setMsgId(msgId); } } // namespace rocketmq diff --git a/src/message/MessageAccessor.h b/src/message/MessageAccessor.hpp similarity index 92% rename from src/message/MessageAccessor.h rename to src/message/MessageAccessor.hpp index ea6f6a24d..c10f9e08d 100644 --- a/src/message/MessageAccessor.h +++ b/src/message/MessageAccessor.hpp @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MESSAGE_ACCESSOR_H__ -#define __MESSAGE_ACCESSOR_H__ +#ifndef ROCKETMQ_MESSAGE_MESSAGEACCESSOR_HPP_ +#define ROCKETMQ_MESSAGE_MESSAGEACCESSOR_HPP_ #include @@ -50,4 +50,4 @@ class MessageAccessor { } // namespace rocketmq -#endif // __MESSAGE_ACCESSOR_H__ +#endif // ROCKETMQ_CCOMMON_MESSAGEACCESSOR_HPP_ diff --git a/src/message/MessageBatch.cpp b/src/message/MessageBatch.cpp index ab49b7469..1f859f6e8 100644 --- a/src/message/MessageBatch.cpp +++ b/src/message/MessageBatch.cpp @@ -56,7 +56,7 @@ std::shared_ptr MessageBatch::generateFromList(std::vector generateFromList(std::vector& messages); public: - MessageBatch(std::vector& messages) : MessageImpl(), m_messages(messages) {} + MessageBatch(std::vector& messages) : MessageImpl(), messages_(messages) {} public: // Message bool isBatch() const override final { return true; } @@ -35,12 +35,12 @@ class MessageBatch : public MessageImpl { public: std::string encode(); - const std::vector& getMessages() const { return m_messages; } + const std::vector& messages() const { return messages_; } protected: - std::vector m_messages; + std::vector messages_; }; } // namespace rocketmq -#endif // __MESSAGE_BATCH_H__ \ No newline at end of file +#endif // ROCKETMQ_MESSAGE_MESSAGEBATCH_H_ diff --git a/src/message/MessageClientIDSetter.cpp b/src/message/MessageClientIDSetter.cpp index 450273ec5..dda45df62 100644 --- a/src/message/MessageClientIDSetter.cpp +++ b/src/message/MessageClientIDSetter.cpp @@ -42,11 +42,11 @@ MessageClientIDSetter::MessageClientIDSetter() { std::memcpy(bin_buf, &ip, 4); std::memcpy(bin_buf + 6, &random_num, 4); - kFixString = UtilAll::bytes2string(bin_buf, 10); + fix_string_ = UtilAll::bytes2string(bin_buf, 10); setStartTime(UtilAll::currentTimeMillis()); - mCounter = 0; + counter_ = 0; } MessageClientIDSetter::~MessageClientIDSetter() = default; @@ -79,25 +79,25 @@ void MessageClientIDSetter::setStartTime(uint64_t millis) { nextMonthBegin.tm_min = 0; nextMonthBegin.tm_sec = 0; - mStartTime = std::mktime(&curMonthBegin) * 1000; - mNextStartTime = std::mktime(&nextMonthBegin) * 1000; + start_time_ = std::mktime(&curMonthBegin) * 1000; + next_start_time_ = std::mktime(&nextMonthBegin) * 1000; } std::string MessageClientIDSetter::createUniqueID() { uint64_t current = UtilAll::currentTimeMillis(); - if (current >= mNextStartTime) { + if (current >= next_start_time_) { setStartTime(current); current = UtilAll::currentTimeMillis(); } - uint32_t period = ByteOrderUtil::NorminalBigEndian(static_cast(current - mStartTime)); - uint16_t seqid = ByteOrderUtil::NorminalBigEndian(mCounter++); + uint32_t period = ByteOrderUtil::NorminalBigEndian(static_cast(current - start_time_)); + uint16_t seqid = ByteOrderUtil::NorminalBigEndian(counter_++); char bin_buf[6]; std::memcpy(bin_buf, &period, 4); std::memcpy(bin_buf + 4, &seqid, 2); - return kFixString + UtilAll::bytes2string(bin_buf, 6); + return fix_string_ + UtilAll::bytes2string(bin_buf, 6); } } // namespace rocketmq diff --git a/src/message/MessageClientIDSetter.h b/src/message/MessageClientIDSetter.h index 90f2ec52c..222115ebd 100644 --- a/src/message/MessageClientIDSetter.h +++ b/src/message/MessageClientIDSetter.h @@ -14,15 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MESSAGE_CLIENT_ID_SETTER_H__ -#define __MESSAGE_CLIENT_ID_SETTER_H__ +#ifndef ROCKETMQ_MESSAGE_MESSAGECLIENTIDSETTER_H_ +#define ROCKETMQ_MESSAGE_MESSAGECLIENTIDSETTER_H_ #include #include #include #include "MQMessage.h" -#include "MessageAccessor.h" +#include "MessageAccessor.hpp" namespace rocketmq { @@ -34,12 +34,13 @@ class MessageClientIDSetter { return singleton_; } - /* ID format: - * ip: 4 bytes - * pid: 2 bytes - * random: 4 bytes - * time: 4 bytes - * auto num: 2 bytes + /** + * ID format: + * 4 bytes - ip + * 2 bytes - pid + * 4 bytes - random + * 4 bytes - time + * 2 bytes - auto num */ static std::string createUniqID() { return getInstance().createUniqueID(); } @@ -63,13 +64,13 @@ class MessageClientIDSetter { std::string createUniqueID(); private: - uint64_t mStartTime; - uint64_t mNextStartTime; - std::atomic mCounter; + uint64_t start_time_; + uint64_t next_start_time_; + std::atomic counter_; - std::string kFixString; + std::string fix_string_; }; } // namespace rocketmq -#endif // __MESSAGE_CLIENT_ID_SETTER_H__ +#endif // ROCKETMQ_MESSAGE_MESSAGECLIENTIDSETTER_H_ diff --git a/src/message/MessageDecoder.cpp b/src/message/MessageDecoder.cpp index d0ac623ae..128ca7f90 100644 --- a/src/message/MessageDecoder.cpp +++ b/src/message/MessageDecoder.cpp @@ -26,21 +26,14 @@ #include "ByteOrder.h" #include "Logging.h" #include "MessageExtImpl.h" -#include "MessageAccessor.h" +#include "MessageAccessor.hpp" #include "MessageSysFlag.h" #include "UtilAll.h" -namespace rocketmq { - -const int MessageDecoder::MSG_ID_LENGTH = 8 + 8; +static const char NAME_VALUE_SEPARATOR = 1; +static const char PROPERTY_SEPARATOR = 2; -const char MessageDecoder::NAME_VALUE_SEPARATOR = 1; -const char MessageDecoder::PROPERTY_SEPARATOR = 2; - -int MessageDecoder::MessageMagicCodePostion = 4; -int MessageDecoder::MessageFlagPostion = 16; -int MessageDecoder::MessagePhysicOffsetPostion = 28; -int MessageDecoder::MessageStoreTimestampPostion = 56; +namespace rocketmq { std::string MessageDecoder::createMessageId(const struct sockaddr* sa, int64_t offset) { int msgIDLength = sa->sa_family == AF_INET ? 16 : 28; @@ -172,10 +165,10 @@ MessageExtPtr MessageDecoder::decode(ByteBuffer& byteBuffer, bool readBody, bool uncompress_failed = true; } } else { - // c_str safety msgExt->setBody(std::string(body.array(), body.size())); } } else { + // skip body byteBuffer.position(byteBuffer.position() + bodyLen); } } diff --git a/src/message/MessageDecoder.h b/src/message/MessageDecoder.h index 1dd259c99..ad0b82d37 100644 --- a/src/message/MessageDecoder.h +++ b/src/message/MessageDecoder.h @@ -18,7 +18,7 @@ #define ROCKETMQ_MESSAGE_MESSAGEDECODER_H_ #include "ByteBuffer.hpp" -#include "MQClientException.h" +#include "MQException.h" #include "MQMessageExt.h" #include "MessageId.h" @@ -42,16 +42,6 @@ class MessageDecoder { static std::string encodeMessage(Message& message); static std::string encodeMessages(std::vector& msgs); - - public: - static const char NAME_VALUE_SEPARATOR; - static const char PROPERTY_SEPARATOR; - static const int MSG_ID_LENGTH; - - static int MessageMagicCodePostion; - static int MessageFlagPostion; - static int MessagePhysicOffsetPostion; - static int MessageStoreTimestampPostion; }; } // namespace rocketmq diff --git a/src/message/MessageUtil.cpp b/src/message/MessageUtil.cpp index 418750a61..32d3e16de 100644 --- a/src/message/MessageUtil.cpp +++ b/src/message/MessageUtil.cpp @@ -19,7 +19,7 @@ #include "ByteArray.h" #include "ClientErrorCode.h" #include "MessageImpl.h" -#include "MessageAccessor.h" +#include "MessageAccessor.hpp" #include "MQMessageConst.h" #include "UtilAll.h" diff --git a/src/producer/CorrelationIdUtil.hpp b/src/producer/CorrelationIdUtil.hpp index e34bd116c..c7cf96daf 100644 --- a/src/producer/CorrelationIdUtil.hpp +++ b/src/producer/CorrelationIdUtil.hpp @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __CORRELATION_ID_UTIL_HPP__ -#define __CORRELATION_ID_UTIL_HPP__ +#ifndef ROCKETMQ_PRODUCER_CORRELATIONIDUTIL_HPP_ +#define ROCKETMQ_PRODUCER_CORRELATIONIDUTIL_HPP_ #include #include @@ -34,4 +34,4 @@ class CorrelationIdUtil { } // namespace rocketmq -#endif // __CORRELATION_ID_UTIL_HPP__ +#endif // ROCKETMQ_PRODUCER_CORRELATIONIDUTIL_HPP_ diff --git a/src/producer/DefaultMQProducer.cpp b/src/producer/DefaultMQProducer.cpp index 179dfdbe4..f4c61f468 100644 --- a/src/producer/DefaultMQProducer.cpp +++ b/src/producer/DefaultMQProducer.cpp @@ -16,7 +16,7 @@ */ #include "DefaultMQProducer.h" -#include "DefaultMQProducerConfigImpl.h" +#include "DefaultMQProducerConfigImpl.hpp" #include "DefaultMQProducerImpl.h" #include "UtilAll.h" @@ -38,7 +38,8 @@ DefaultMQProducer::DefaultMQProducer(const std::string& groupname, setGroupName(groupname); } - producer_impl_ = DefaultMQProducerImpl::create(getRealConfig(), rpcHook); + // create DefaultMQProducerImpl + producer_impl_ = DefaultMQProducerImpl::create(real_config(), rpcHook); } DefaultMQProducer::~DefaultMQProducer() = default; @@ -174,15 +175,15 @@ void DefaultMQProducer::request(MQMessage& msg, } bool DefaultMQProducer::isSendLatencyFaultEnable() const { - return std::dynamic_pointer_cast(producer_impl_)->isSendLatencyFaultEnable(); + return dynamic_cast(producer_impl_.get())->isSendLatencyFaultEnable(); } void DefaultMQProducer::setSendLatencyFaultEnable(bool sendLatencyFaultEnable) { - std::dynamic_pointer_cast(producer_impl_)->setSendLatencyFaultEnable(sendLatencyFaultEnable); + dynamic_cast(producer_impl_.get())->setSendLatencyFaultEnable(sendLatencyFaultEnable); } void DefaultMQProducer::setRPCHook(RPCHookPtr rpcHook) { - std::dynamic_pointer_cast(producer_impl_)->setRPCHook(rpcHook); + dynamic_cast(producer_impl_.get())->setRPCHook(rpcHook); } } // namespace rocketmq diff --git a/src/producer/DefaultMQProducerConfigImpl.cpp b/src/producer/DefaultMQProducerConfigImpl.cpp deleted file mode 100644 index 19545a12f..000000000 --- a/src/producer/DefaultMQProducerConfigImpl.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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 "DefaultMQProducerConfigImpl.h" - -namespace rocketmq { - -DefaultMQProducerConfigImpl::DefaultMQProducerConfigImpl() - : m_maxMessageSize(1024 * 1024 * 4), // 4MB - m_compressMsgBodyOverHowmuch(1024 * 4), // 4KB - m_compressLevel(5), - m_sendMsgTimeout(3000), - m_retryTimes(2), - m_retryTimes4Async(2), - m_retryAnotherBrokerWhenNotStoreOK(false) {} - -int DefaultMQProducerConfigImpl::getMaxMessageSize() const { - return m_maxMessageSize; -} - -void DefaultMQProducerConfigImpl::setMaxMessageSize(int maxMessageSize) { - m_maxMessageSize = maxMessageSize; -} - -int DefaultMQProducerConfigImpl::getCompressMsgBodyOverHowmuch() const { - return m_compressMsgBodyOverHowmuch; -} - -void DefaultMQProducerConfigImpl::setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch) { - m_compressMsgBodyOverHowmuch = compressMsgBodyOverHowmuch; -} - -int DefaultMQProducerConfigImpl::getCompressLevel() const { - return m_compressLevel; -} - -void DefaultMQProducerConfigImpl::setCompressLevel(int compressLevel) { - if ((compressLevel >= 0 && compressLevel <= 9) || compressLevel == -1) { - m_compressLevel = compressLevel; - } -} - -int DefaultMQProducerConfigImpl::getSendMsgTimeout() const { - return m_sendMsgTimeout; -} - -void DefaultMQProducerConfigImpl::setSendMsgTimeout(int sendMsgTimeout) { - m_sendMsgTimeout = sendMsgTimeout; -} - -int DefaultMQProducerConfigImpl::getRetryTimes() const { - return m_retryTimes; -} - -void DefaultMQProducerConfigImpl::setRetryTimes(int times) { - m_retryTimes = std::min(std::max(0, times), 15); -} - -int DefaultMQProducerConfigImpl::getRetryTimes4Async() const { - return m_retryTimes4Async; -} - -void DefaultMQProducerConfigImpl::setRetryTimes4Async(int times) { - m_retryTimes4Async = std::min(std::max(0, times), 15); -} - -bool DefaultMQProducerConfigImpl::isRetryAnotherBrokerWhenNotStoreOK() const { - return m_retryAnotherBrokerWhenNotStoreOK; -} - -void DefaultMQProducerConfigImpl::setRetryAnotherBrokerWhenNotStoreOK(bool retryAnotherBrokerWhenNotStoreOK) { - m_retryAnotherBrokerWhenNotStoreOK = retryAnotherBrokerWhenNotStoreOK; -} - -} // namespace rocketmq diff --git a/src/producer/DefaultMQProducerConfigImpl.h b/src/producer/DefaultMQProducerConfigImpl.h deleted file mode 100644 index 3ae0530e8..000000000 --- a/src/producer/DefaultMQProducerConfigImpl.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 __DEFAULT_MQ_PRODUCER_CONFIG_IMPL_H__ -#define __DEFAULT_MQ_PRODUCER_CONFIG_IMPL_H__ - -#include "DefaultMQProducerConfig.h" -#include "MQClientConfigImpl.h" - -namespace rocketmq { - -class DefaultMQProducerConfigImpl : virtual public DefaultMQProducerConfig, public MQClientConfigImpl { - public: - DefaultMQProducerConfigImpl(); - virtual ~DefaultMQProducerConfigImpl() = default; - - int getMaxMessageSize() const override; - void setMaxMessageSize(int maxMessageSize) override; - - int getCompressMsgBodyOverHowmuch() const override; - void setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch) override; - - int getCompressLevel() const override; - void setCompressLevel(int compressLevel) override; - - int getSendMsgTimeout() const override; - void setSendMsgTimeout(int sendMsgTimeout) override; - - int getRetryTimes() const override; - void setRetryTimes(int times) override; - - int getRetryTimes4Async() const override; - void setRetryTimes4Async(int times) override; - - bool isRetryAnotherBrokerWhenNotStoreOK() const override; - void setRetryAnotherBrokerWhenNotStoreOK(bool retryAnotherBrokerWhenNotStoreOK) override; - - protected: - int m_maxMessageSize; // default: 4 MB - int m_compressMsgBodyOverHowmuch; // default: 4 KB - int m_compressLevel; - int m_sendMsgTimeout; - int m_retryTimes; - int m_retryTimes4Async; - bool m_retryAnotherBrokerWhenNotStoreOK; -}; - -} // namespace rocketmq - -#endif // __DEFAULT_MQ_PRODUCER_CONFIG_IMPL_H__ diff --git a/src/producer/DefaultMQProducerConfigImpl.hpp b/src/producer/DefaultMQProducerConfigImpl.hpp new file mode 100644 index 000000000..11d822385 --- /dev/null +++ b/src/producer/DefaultMQProducerConfigImpl.hpp @@ -0,0 +1,84 @@ +/* + * 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_PRODUCER_DEFAULTMQPRODUCERCONFIGIMPL_HPP_ +#define ROCKETMQ_PRODUCER_DEFAULTMQPRODUCERCONFIGIMPL_HPP_ + +#include // std::min, std::max + +#include "DefaultMQProducerConfig.h" +#include "MQClientConfigImpl.hpp" + +namespace rocketmq { + +/** + * DefaultMQProducerConfigImpl - implement for DefaultMQProducerConfig + */ +class DefaultMQProducerConfigImpl : virtual public DefaultMQProducerConfig, public MQClientConfigImpl { + public: + DefaultMQProducerConfigImpl() + : max_message_size_(1024 * 1024 * 4), // 4MB + compress_msg_body_over_howmuch_(1024 * 4), // 4KB + compress_level_(5), + send_msg_timeout_(3000), + retry_times_(2), + retry_times_for_async_(2), + retry_another_broker_when_not_store_ok_(false) {} + + virtual ~DefaultMQProducerConfigImpl() = default; + + int getMaxMessageSize() const override { return max_message_size_; } + void setMaxMessageSize(int maxMessageSize) override { max_message_size_ = maxMessageSize; } + + int getCompressMsgBodyOverHowmuch() const override { return compress_msg_body_over_howmuch_; } + void setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch) override { + compress_msg_body_over_howmuch_ = compressMsgBodyOverHowmuch; + } + + int getCompressLevel() const override { return compress_level_; } + void setCompressLevel(int compressLevel) override { + if ((compressLevel >= 0 && compressLevel <= 9) || compressLevel == -1) { + compress_level_ = compressLevel; + } + } + + int getSendMsgTimeout() const override { return send_msg_timeout_; } + void setSendMsgTimeout(int sendMsgTimeout) override { send_msg_timeout_ = sendMsgTimeout; } + + int getRetryTimes() const override { return retry_times_; } + void setRetryTimes(int times) override { retry_times_ = std::min(std::max(0, times), 15); } + + int getRetryTimesForAsync() const override { return retry_times_for_async_; } + void setRetryTimesForAsync(int times) override { retry_times_for_async_ = std::min(std::max(0, times), 15); } + + bool isRetryAnotherBrokerWhenNotStoreOK() const override { return retry_another_broker_when_not_store_ok_; } + void setRetryAnotherBrokerWhenNotStoreOK(bool retryAnotherBrokerWhenNotStoreOK) override { + retry_another_broker_when_not_store_ok_ = retryAnotherBrokerWhenNotStoreOK; + } + + protected: + int max_message_size_; // default: 4 MB + int compress_msg_body_over_howmuch_; // default: 4 KB + int compress_level_; + int send_msg_timeout_; + int retry_times_; + int retry_times_for_async_; + bool retry_another_broker_when_not_store_ok_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_PRODUCER_DEFAULTMQPRODUCERCONFIGIMPL_HPP_ diff --git a/src/producer/DefaultMQProducerImpl.cpp b/src/producer/DefaultMQProducerImpl.cpp index e5ef3b04b..3c6b9e3a5 100644 --- a/src/producer/DefaultMQProducerImpl.cpp +++ b/src/producer/DefaultMQProducerImpl.cpp @@ -28,7 +28,7 @@ #include "CorrelationIdUtil.hpp" #include "Logging.h" #include "MQClientAPIImpl.h" -#include "MQClientException.h" +#include "MQException.h" #include "MQClientInstance.h" #include "MQClientManager.h" #include "MessageDecoder.h" @@ -38,7 +38,7 @@ #include "MessageClientIDSetter.h" #include "MessageSysFlag.h" #include "RequestFutureTable.h" -#include "TopicPublishInfo.h" +#include "TopicPublishInfo.hpp" #include "TransactionMQProducer.h" #include "Validators.h" #include "protocol/header/CommandHeader.h" @@ -49,12 +49,12 @@ class RequestSendCallback : public AutoDeleteSendCallback { public: RequestSendCallback(std::shared_ptr requestFuture) : request_future_(requestFuture) {} - void onSuccess(SendResult& sendResult) override { request_future_->setSendRequestOk(true); } + void onSuccess(SendResult& sendResult) override { request_future_->set_send_request_ok(true); } void onException(MQException& e) noexcept override { - request_future_->setSendRequestOk(false); + request_future_->set_send_request_ok(false); request_future_->putResponseMessage(nullptr); - request_future_->setCause(std::make_exception_ptr(e)); + request_future_->set_cause(std::make_exception_ptr(e)); } private: @@ -65,14 +65,14 @@ class AsyncRequestSendCallback : public AutoDeleteSendCallback { public: AsyncRequestSendCallback(std::shared_ptr requestFuture) : request_future_(requestFuture) {} - void onSuccess(SendResult& sendResult) override { request_future_->setSendRequestOk(true); } + void onSuccess(SendResult& sendResult) override { request_future_->set_send_request_ok(true); } void onException(MQException& e) noexcept override { - request_future_->setCause(std::make_exception_ptr(e)); - auto response_future = RequestFutureTable::removeRequestFuture(request_future_->getCorrelationId()); + request_future_->set_cause(std::make_exception_ptr(e)); + auto response_future = RequestFutureTable::removeRequestFuture(request_future_->correlation_id()); if (response_future != nullptr) { // response_future is same as request_future_ - response_future->setSendRequestOk(false); + response_future->set_send_request_ok(false); response_future->putResponseMessage(nullptr); try { response_future->executeRequestCallback(); @@ -90,10 +90,7 @@ DefaultMQProducerImpl::DefaultMQProducerImpl(DefaultMQProducerConfigPtr config) : DefaultMQProducerImpl(config, nullptr) {} DefaultMQProducerImpl::DefaultMQProducerImpl(DefaultMQProducerConfigPtr config, RPCHookPtr rpcHook) - : MQClientImpl(config, rpcHook), - m_producerConfig(config), - m_mqFaultStrategy(new MQFaultStrategy()), - m_checkTransactionExecutor(nullptr) {} + : MQClientImpl(config, rpcHook), mq_fault_strategy_(new MQFaultStrategy()), check_transaction_executor_(nullptr) {} DefaultMQProducerImpl::~DefaultMQProducerImpl() = default; @@ -107,48 +104,51 @@ void DefaultMQProducerImpl::start() { ::sigaction(SIGPIPE, &sa, 0); #endif - switch (m_serviceState) { + switch (service_state_) { case CREATE_JUST: { - m_serviceState = START_FAILED; + LOG_INFO_NEW("DefaultMQProducerImpl: {} start", client_config_->getGroupName()); - m_producerConfig->changeInstanceNameToPID(); + service_state_ = START_FAILED; - LOG_INFO_NEW("DefaultMQProducerImpl: {} start", m_producerConfig->getGroupName()); + client_config_->changeInstanceNameToPID(); MQClientImpl::start(); - bool registerOK = m_clientInstance->registerProducer(m_producerConfig->getGroupName(), this); + bool registerOK = client_instance_->registerProducer( + dynamic_cast(client_config_.get())->getGroupName(), this); if (!registerOK) { - m_serviceState = CREATE_JUST; - THROW_MQEXCEPTION(MQClientException, "The producer group[" + m_producerConfig->getGroupName() + + service_state_ = CREATE_JUST; + THROW_MQEXCEPTION(MQClientException, "The producer group[" + client_config_->getGroupName() + "] has been created before, specify another name please.", -1); } - m_clientInstance->start(); - LOG_INFO_NEW("the producer [{}] start OK.", m_producerConfig->getGroupName()); - m_serviceState = RUNNING; + client_instance_->start(); + + LOG_INFO_NEW("the producer [{}] start OK.", client_config_->getGroupName()); + service_state_ = RUNNING; break; } case RUNNING: case START_FAILED: case SHUTDOWN_ALREADY: + THROW_MQEXCEPTION(MQClientException, "The producer service state not OK, maybe started once", -1); break; default: break; } - m_clientInstance->sendHeartbeatToAllBrokerWithLock(); + client_instance_->sendHeartbeatToAllBrokerWithLock(); } void DefaultMQProducerImpl::shutdown() { - switch (m_serviceState) { + switch (service_state_) { case RUNNING: { LOG_INFO("DefaultMQProducerImpl shutdown"); - m_clientInstance->unregisterProducer(m_producerConfig->getGroupName()); - m_clientInstance->shutdown(); + client_instance_->unregisterProducer(client_config_->getGroupName()); + client_instance_->shutdown(); - m_serviceState = SHUTDOWN_ALREADY; + service_state_ = SHUTDOWN_ALREADY; break; } case SHUTDOWN_ALREADY: @@ -159,25 +159,13 @@ void DefaultMQProducerImpl::shutdown() { } } -void DefaultMQProducerImpl::initTransactionEnv() { - if (nullptr == m_checkTransactionExecutor) { - m_checkTransactionExecutor.reset(new thread_pool_executor(1, false)); - } - m_checkTransactionExecutor->startup(); -} - -void DefaultMQProducerImpl::destroyTransactionEnv() { - m_checkTransactionExecutor->shutdown(); -} - SendResult DefaultMQProducerImpl::send(MQMessage& msg) { - return send(msg, m_producerConfig->getSendMsgTimeout()); + return send(msg, dynamic_cast(client_config_.get())->getSendMsgTimeout()); } SendResult DefaultMQProducerImpl::send(MQMessage& msg, long timeout) { try { - std::unique_ptr sendResult( - sendDefaultImpl(msg.getMessageImpl(), CommunicationMode::SYNC, nullptr, timeout)); + std::unique_ptr sendResult(sendDefaultImpl(msg.getMessageImpl(), SYNC, nullptr, timeout)); return *sendResult; } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); @@ -186,19 +174,18 @@ SendResult DefaultMQProducerImpl::send(MQMessage& msg, long timeout) { } SendResult DefaultMQProducerImpl::send(MQMessage& msg, const MQMessageQueue& mq) { - return send(msg, mq, m_producerConfig->getSendMsgTimeout()); + return send(msg, mq, dynamic_cast(client_config_.get())->getSendMsgTimeout()); } SendResult DefaultMQProducerImpl::send(MQMessage& msg, const MQMessageQueue& mq, long timeout) { - Validators::checkMessage(msg, m_producerConfig->getMaxMessageSize()); + Validators::checkMessage(msg, dynamic_cast(client_config_.get())->getMaxMessageSize()); - if (msg.getTopic() != mq.getTopic()) { + if (msg.getTopic() != mq.topic()) { THROW_MQEXCEPTION(MQClientException, "message's topic not equal mq's topic", -1); } try { - std::unique_ptr sendResult( - sendKernelImpl(msg.getMessageImpl(), mq, CommunicationMode::SYNC, nullptr, nullptr, timeout)); + std::unique_ptr sendResult(sendKernelImpl(msg.getMessageImpl(), mq, SYNC, nullptr, nullptr, timeout)); return *sendResult; } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); @@ -207,12 +194,12 @@ SendResult DefaultMQProducerImpl::send(MQMessage& msg, const MQMessageQueue& mq, } void DefaultMQProducerImpl::send(MQMessage& msg, SendCallback* sendCallback) noexcept { - return send(msg, sendCallback, m_producerConfig->getSendMsgTimeout()); + return send(msg, sendCallback, dynamic_cast(client_config_.get())->getSendMsgTimeout()); } void DefaultMQProducerImpl::send(MQMessage& msg, SendCallback* sendCallback, long timeout) noexcept { try { - (void)sendDefaultImpl(msg.getMessageImpl(), CommunicationMode::ASYNC, sendCallback, timeout); + (void)sendDefaultImpl(msg.getMessageImpl(), ASYNC, sendCallback, timeout); } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); sendCallback->onException(e); @@ -226,7 +213,7 @@ void DefaultMQProducerImpl::send(MQMessage& msg, SendCallback* sendCallback, lon } void DefaultMQProducerImpl::send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept { - return send(msg, mq, sendCallback, m_producerConfig->getSendMsgTimeout()); + return send(msg, mq, sendCallback, dynamic_cast(client_config_.get())->getSendMsgTimeout()); } void DefaultMQProducerImpl::send(MQMessage& msg, @@ -234,14 +221,14 @@ void DefaultMQProducerImpl::send(MQMessage& msg, SendCallback* sendCallback, long timeout) noexcept { try { - Validators::checkMessage(msg, m_producerConfig->getMaxMessageSize()); + Validators::checkMessage(msg, dynamic_cast(client_config_.get())->getMaxMessageSize()); - if (msg.getTopic() != mq.getTopic()) { + if (msg.getTopic() != mq.topic()) { THROW_MQEXCEPTION(MQClientException, "message's topic not equal mq's topic", -1); } try { - sendKernelImpl(msg.getMessageImpl(), mq, CommunicationMode::ASYNC, sendCallback, nullptr, timeout); + sendKernelImpl(msg.getMessageImpl(), mq, ASYNC, sendCallback, nullptr, timeout); } catch (MQBrokerException& e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); @@ -260,7 +247,8 @@ void DefaultMQProducerImpl::send(MQMessage& msg, void DefaultMQProducerImpl::sendOneway(MQMessage& msg) { try { - sendDefaultImpl(msg.getMessageImpl(), CommunicationMode::ONEWAY, nullptr, m_producerConfig->getSendMsgTimeout()); + sendDefaultImpl(msg.getMessageImpl(), ONEWAY, nullptr, + dynamic_cast(client_config_.get())->getSendMsgTimeout()); } catch (MQBrokerException& e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); @@ -268,15 +256,15 @@ void DefaultMQProducerImpl::sendOneway(MQMessage& msg) { } void DefaultMQProducerImpl::sendOneway(MQMessage& msg, const MQMessageQueue& mq) { - Validators::checkMessage(msg, m_producerConfig->getMaxMessageSize()); + Validators::checkMessage(msg, dynamic_cast(client_config_.get())->getMaxMessageSize()); - if (msg.getTopic() != mq.getTopic()) { + if (msg.getTopic() != mq.topic()) { THROW_MQEXCEPTION(MQClientException, "message's topic not equal mq's topic", -1); } try { - sendKernelImpl(msg.getMessageImpl(), mq, CommunicationMode::ONEWAY, nullptr, nullptr, - m_producerConfig->getSendMsgTimeout()); + sendKernelImpl(msg.getMessageImpl(), mq, ONEWAY, nullptr, nullptr, + dynamic_cast(client_config_.get())->getSendMsgTimeout()); } catch (MQBrokerException& e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); @@ -284,13 +272,12 @@ void DefaultMQProducerImpl::sendOneway(MQMessage& msg, const MQMessageQueue& mq) } SendResult DefaultMQProducerImpl::send(MQMessage& msg, MessageQueueSelector* selector, void* arg) { - return send(msg, selector, arg, m_producerConfig->getSendMsgTimeout()); + return send(msg, selector, arg, dynamic_cast(client_config_.get())->getSendMsgTimeout()); } SendResult DefaultMQProducerImpl::send(MQMessage& msg, MessageQueueSelector* selector, void* arg, long timeout) { try { - std::unique_ptr result( - sendSelectImpl(msg.getMessageImpl(), selector, arg, CommunicationMode::SYNC, nullptr, timeout)); + std::unique_ptr result(sendSelectImpl(msg.getMessageImpl(), selector, arg, SYNC, nullptr, timeout)); return *result.get(); } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); @@ -302,7 +289,8 @@ void DefaultMQProducerImpl::send(MQMessage& msg, MessageQueueSelector* selector, void* arg, SendCallback* sendCallback) noexcept { - return send(msg, selector, arg, sendCallback, m_producerConfig->getSendMsgTimeout()); + return send(msg, selector, arg, sendCallback, + dynamic_cast(client_config_.get())->getSendMsgTimeout()); } void DefaultMQProducerImpl::send(MQMessage& msg, @@ -312,7 +300,7 @@ void DefaultMQProducerImpl::send(MQMessage& msg, long timeout) noexcept { try { try { - sendSelectImpl(msg.getMessageImpl(), selector, arg, CommunicationMode::ASYNC, sendCallback, timeout); + sendSelectImpl(msg.getMessageImpl(), selector, arg, ASYNC, sendCallback, timeout); } catch (MQBrokerException& e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); @@ -331,8 +319,8 @@ void DefaultMQProducerImpl::send(MQMessage& msg, void DefaultMQProducerImpl::sendOneway(MQMessage& msg, MessageQueueSelector* selector, void* arg) { try { - sendSelectImpl(msg.getMessageImpl(), selector, arg, CommunicationMode::ONEWAY, nullptr, - m_producerConfig->getSendMsgTimeout()); + sendSelectImpl(msg.getMessageImpl(), selector, arg, ONEWAY, nullptr, + dynamic_cast(client_config_.get())->getSendMsgTimeout()); } catch (MQBrokerException& e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); @@ -341,8 +329,8 @@ void DefaultMQProducerImpl::sendOneway(MQMessage& msg, MessageQueueSelector* sel TransactionSendResult DefaultMQProducerImpl::sendMessageInTransaction(MQMessage& msg, void* arg) { try { - std::unique_ptr sendResult( - sendMessageInTransactionImpl(msg.getMessageImpl(), arg, m_producerConfig->getSendMsgTimeout())); + std::unique_ptr sendResult(sendMessageInTransactionImpl( + msg.getMessageImpl(), arg, dynamic_cast(client_config_.get())->getSendMsgTimeout())); return *sendResult; } catch (MQException& e) { LOG_ERROR_NEW("sendMessageInTransaction failed, exception:{}", e.what()); @@ -377,8 +365,9 @@ MessagePtr DefaultMQProducerImpl::batch(std::vector& msgs) { try { auto messageBatch = MessageBatch::generateFromList(msgs); - for (auto& message : messageBatch->getMessages()) { - Validators::checkMessage(message, m_producerConfig->getMaxMessageSize()); + for (auto& message : messageBatch->messages()) { + Validators::checkMessage(message, + dynamic_cast(client_config_.get())->getMaxMessageSize()); MessageClientIDSetter::setUniqID(const_cast(message)); } messageBatch->setBody(messageBatch->encode()); @@ -405,13 +394,13 @@ MQMessage DefaultMQProducerImpl::request(MQMessage& msg, long timeout) { responseMessage = requestResponseFuture->waitResponseMessage(timeout - cost); if (responseMessage == nullptr) { - if (requestResponseFuture->isSendRequestOk()) { + if (requestResponseFuture->send_request_ok()) { std::string info = "send request message to <" + msg.getTopic() + "> OK, but wait reply message timeout, " + UtilAll::to_string(timeout) + " ms."; THROW_MQEXCEPTION(RequestTimeoutException, info, ClientErrorCode::REQUEST_TIMEOUT_EXCEPTION); } else { std::string info = "send request message to <" + msg.getTopic() + "> fail"; - THROW_MQEXCEPTION2(MQClientException, info, -1, requestResponseFuture->getCause()); + THROW_MQEXCEPTION2(MQClientException, info, -1, requestResponseFuture->cause()); } } } catch (...) { @@ -458,13 +447,13 @@ MQMessage DefaultMQProducerImpl::request(MQMessage& msg, const MQMessageQueue& m responseMessage = requestResponseFuture->waitResponseMessage(timeout - cost); if (responseMessage == nullptr) { - if (requestResponseFuture->isSendRequestOk()) { + if (requestResponseFuture->send_request_ok()) { std::string info = "send request message to <" + msg.getTopic() + "> OK, but wait reply message timeout, " + UtilAll::to_string(timeout) + " ms."; THROW_MQEXCEPTION(RequestTimeoutException, info, ClientErrorCode::REQUEST_TIMEOUT_EXCEPTION); } else { std::string info = "send request message to <" + msg.getTopic() + "> fail"; - THROW_MQEXCEPTION2(MQClientException, info, -1, requestResponseFuture->getCause()); + THROW_MQEXCEPTION2(MQClientException, info, -1, requestResponseFuture->cause()); } } } catch (...) { @@ -514,13 +503,13 @@ MQMessage DefaultMQProducerImpl::request(MQMessage& msg, MessageQueueSelector* s responseMessage = requestResponseFuture->waitResponseMessage(timeout - cost); if (responseMessage == nullptr) { - if (requestResponseFuture->isSendRequestOk()) { + if (requestResponseFuture->send_request_ok()) { std::string info = "send request message to <" + msg.getTopic() + "> OK, but wait reply message timeout, " + UtilAll::to_string(timeout) + " ms."; THROW_MQEXCEPTION(RequestTimeoutException, info, ClientErrorCode::REQUEST_TIMEOUT_EXCEPTION); } else { std::string info = "send request message to <" + msg.getTopic() + "> fail"; - THROW_MQEXCEPTION2(MQClientException, info, -1, requestResponseFuture->getCause()); + THROW_MQEXCEPTION2(MQClientException, info, -1, requestResponseFuture->cause()); } } } catch (...) { @@ -556,16 +545,16 @@ void DefaultMQProducerImpl::request(MQMessage& msg, void DefaultMQProducerImpl::prepareSendRequest(Message& msg, long timeout) { const auto correlationId = CorrelationIdUtil::createCorrelationId(); - const auto& requestClientId = m_clientInstance->getClientId(); + const auto& requestClientId = client_instance_->getClientId(); MessageAccessor::putProperty(msg, MQMessageConst::PROPERTY_CORRELATION_ID, correlationId); MessageAccessor::putProperty(msg, MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT, requestClientId); MessageAccessor::putProperty(msg, MQMessageConst::PROPERTY_MESSAGE_TTL, UtilAll::to_string(timeout)); - auto hasRouteData = m_clientInstance->getTopicRouteData(msg.getTopic()) != nullptr; + auto hasRouteData = client_instance_->getTopicRouteData(msg.getTopic()) != nullptr; if (!hasRouteData) { auto beginTimestamp = UtilAll::currentTimeMillis(); - m_clientInstance->tryToFindTopicPublishInfo(msg.getTopic()); - m_clientInstance->sendHeartbeatToAllBrokerWithLock(); + client_instance_->tryToFindTopicPublishInfo(msg.getTopic()); + client_instance_->sendHeartbeatToAllBrokerWithLock(); auto cost = UtilAll::currentTimeMillis() - beginTimestamp; if (cost > 500) { LOG_WARN_NEW("prepare send request for <{}> cost {} ms", msg.getTopic(), cost); @@ -573,34 +562,27 @@ void DefaultMQProducerImpl::prepareSendRequest(Message& msg, long timeout) { } } -const MQMessageQueue& DefaultMQProducerImpl::selectOneMessageQueue(const TopicPublishInfo* tpInfo, - const std::string& lastBrokerName) { - return m_mqFaultStrategy->selectOneMessageQueue(tpInfo, lastBrokerName); -} - -void DefaultMQProducerImpl::updateFaultItem(const std::string& brokerName, const long currentLatency, bool isolation) { - m_mqFaultStrategy->updateFaultItem(brokerName, currentLatency, isolation); -} - SendResult* DefaultMQProducerImpl::sendDefaultImpl(MessagePtr msg, CommunicationMode communicationMode, SendCallback* sendCallback, long timeout) { - Validators::checkMessage(*msg, m_producerConfig->getMaxMessageSize()); + Validators::checkMessage(*msg, dynamic_cast(client_config_.get())->getMaxMessageSize()); uint64_t beginTimestampFirst = UtilAll::currentTimeMillis(); uint64_t beginTimestampPrev = beginTimestampFirst; uint64_t endTimestamp = beginTimestampFirst; - auto topicPublishInfo = m_clientInstance->tryToFindTopicPublishInfo(msg->getTopic()); + auto topicPublishInfo = client_instance_->tryToFindTopicPublishInfo(msg->getTopic()); if (topicPublishInfo != nullptr && topicPublishInfo->ok()) { bool callTimeout = false; std::unique_ptr sendResult; - int timesTotal = communicationMode == CommunicationMode::SYNC ? 1 + m_producerConfig->getRetryTimes() : 1; + int timesTotal = communicationMode == CommunicationMode::SYNC + ? 1 + dynamic_cast(client_config_.get())->getRetryTimes() + : 1; int times = 0; std::string lastBrokerName; for (; times < timesTotal; times++) { const auto& mq = selectOneMessageQueue(topicPublishInfo.get(), lastBrokerName); - lastBrokerName = mq.getBrokerName(); + lastBrokerName = mq.broker_name(); try { LOG_DEBUG_NEW("send to mq: {}", mq.toString()); @@ -618,15 +600,15 @@ SendResult* DefaultMQProducerImpl::sendDefaultImpl(MessagePtr msg, sendResult.reset( sendKernelImpl(msg, mq, communicationMode, sendCallback, topicPublishInfo, timeout - costTime)); endTimestamp = UtilAll::currentTimeMillis(); - updateFaultItem(mq.getBrokerName(), endTimestamp - beginTimestampPrev, false); + updateFaultItem(mq.broker_name(), endTimestamp - beginTimestampPrev, false); switch (communicationMode) { - case CommunicationMode::ASYNC: + case ASYNC: return nullptr; - case CommunicationMode::ONEWAY: + case ONEWAY: return nullptr; - case CommunicationMode::SYNC: + case SYNC: if (sendResult->getSendStatus() != SEND_OK) { - if (m_producerConfig->isRetryAnotherBrokerWhenNotStoreOK()) { + if (dynamic_cast(client_config_.get())->isRetryAnotherBrokerWhenNotStoreOK()) { continue; } } @@ -638,8 +620,8 @@ SendResult* DefaultMQProducerImpl::sendDefaultImpl(MessagePtr msg, } catch (const std::exception& e) { // TODO: 区分异常类型 endTimestamp = UtilAll::currentTimeMillis(); - updateFaultItem(mq.getBrokerName(), endTimestamp - beginTimestampPrev, true); - LOG_WARN_NEW("send failed of times:{}, brokerName:{}. exception:{}", times, mq.getBrokerName(), e.what()); + updateFaultItem(mq.broker_name(), endTimestamp - beginTimestampPrev, true); + LOG_WARN_NEW("send failed of times:{}, brokerName:{}. exception:{}", times, mq.broker_name(), e.what()); continue; } @@ -658,6 +640,15 @@ SendResult* DefaultMQProducerImpl::sendDefaultImpl(MessagePtr msg, THROW_MQEXCEPTION(MQClientException, "No route info of this topic: " + msg->getTopic(), -1); } +const MQMessageQueue& DefaultMQProducerImpl::selectOneMessageQueue(const TopicPublishInfo* tpInfo, + const std::string& lastBrokerName) { + return mq_fault_strategy_->selectOneMessageQueue(tpInfo, lastBrokerName); +} + +void DefaultMQProducerImpl::updateFaultItem(const std::string& brokerName, const long currentLatency, bool isolation) { + mq_fault_strategy_->updateFaultItem(brokerName, currentLatency, isolation); +} + SendResult* DefaultMQProducerImpl::sendKernelImpl(MessagePtr msg, const MQMessageQueue& mq, CommunicationMode communicationMode, @@ -665,10 +656,10 @@ SendResult* DefaultMQProducerImpl::sendKernelImpl(MessagePtr msg, TopicPublishInfoPtr topicPublishInfo, long timeout) { uint64_t beginStartTime = UtilAll::currentTimeMillis(); - std::string brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); + std::string brokerAddr = client_instance_->findBrokerAddressInPublish(mq.broker_name()); if (brokerAddr.empty()) { - m_clientInstance->tryToFindTopicPublishInfo(mq.getTopic()); - brokerAddr = m_clientInstance->findBrokerAddressInPublish(mq.getBrokerName()); + client_instance_->tryToFindTopicPublishInfo(mq.topic()); + brokerAddr = client_instance_->findBrokerAddressInPublish(mq.broker_name()); } if (!brokerAddr.empty()) { @@ -694,11 +685,11 @@ SendResult* DefaultMQProducerImpl::sendKernelImpl(MessagePtr msg, // TOOD: send message hook std::unique_ptr requestHeader(new SendMessageRequestHeader()); - requestHeader->producerGroup = m_producerConfig->getGroupName(); + requestHeader->producerGroup = client_config_->getGroupName(); requestHeader->topic = msg->getTopic(); requestHeader->defaultTopic = AUTO_CREATE_TOPIC_KEY_TOPIC; requestHeader->defaultTopicQueueNums = 4; - requestHeader->queueId = mq.getQueueId(); + requestHeader->queueId = mq.queue_id(); requestHeader->sysFlag = sysFlag; requestHeader->bornTimestamp = UtilAll::currentTimeMillis(); requestHeader->flag = msg->getFlag(); @@ -707,7 +698,7 @@ SendResult* DefaultMQProducerImpl::sendKernelImpl(MessagePtr msg, requestHeader->unitMode = false; requestHeader->batch = msg->isBatch(); - if (UtilAll::isRetryTopic(mq.getTopic())) { + if (UtilAll::isRetryTopic(mq.topic())) { const auto& reconsumeTimes = MessageAccessor::getReconsumeTime(*msg); if (!reconsumeTimes.empty()) { requestHeader->reconsumeTimes = std::stoi(reconsumeTimes); @@ -723,22 +714,24 @@ SendResult* DefaultMQProducerImpl::sendKernelImpl(MessagePtr msg, SendResult* sendResult = nullptr; switch (communicationMode) { - case CommunicationMode::ASYNC: { + case ASYNC: { long costTimeAsync = UtilAll::currentTimeMillis() - beginStartTime; if (timeout < costTimeAsync) { THROW_MQEXCEPTION(RemotingTooMuchRequestException, "sendKernelImpl call timeout", -1); } - sendResult = m_clientInstance->getMQClientAPIImpl()->sendMessage( - brokerAddr, mq.getBrokerName(), msg, std::move(requestHeader), timeout, communicationMode, sendCallback, - topicPublishInfo, m_clientInstance, m_producerConfig->getRetryTimes4Async(), shared_from_this()); + sendResult = client_instance_->getMQClientAPIImpl()->sendMessage( + brokerAddr, mq.broker_name(), msg, std::move(requestHeader), timeout, communicationMode, sendCallback, + topicPublishInfo, client_instance_, + dynamic_cast(client_config_.get())->getRetryTimesForAsync(), + shared_from_this()); } break; - case CommunicationMode::ONEWAY: - case CommunicationMode::SYNC: { + case ONEWAY: + case SYNC: { long costTimeSync = UtilAll::currentTimeMillis() - beginStartTime; if (timeout < costTimeSync) { THROW_MQEXCEPTION(RemotingTooMuchRequestException, "sendKernelImpl call timeout", -1); } - sendResult = m_clientInstance->getMQClientAPIImpl()->sendMessage(brokerAddr, mq.getBrokerName(), msg, + sendResult = client_instance_->getMQClientAPIImpl()->sendMessage(brokerAddr, mq.broker_name(), msg, std::move(requestHeader), timeout, communicationMode, shared_from_this()); } break; @@ -753,7 +746,32 @@ SendResult* DefaultMQProducerImpl::sendKernelImpl(MessagePtr msg, } } - THROW_MQEXCEPTION(MQClientException, "The broker[" + mq.getBrokerName() + "] not exist", -1); + THROW_MQEXCEPTION(MQClientException, "The broker[" + mq.broker_name() + "] not exist", -1); +} + +bool DefaultMQProducerImpl::tryToCompressMessage(Message& msg) { + if (msg.isBatch()) { + // batch dose not support compressing right now + return false; + } + + // already compressed + if (UtilAll::stob(msg.getProperty(MQMessageConst::PROPERTY_ALREADY_COMPRESSED_FLAG))) { + return true; + } + + const auto& body = msg.getBody(); + if (body.size() >= dynamic_cast(client_config_.get())->getCompressMsgBodyOverHowmuch()) { + std::string out_body; + if (UtilAll::deflate(body, out_body, + dynamic_cast(client_config_.get())->getCompressLevel())) { + msg.setBody(std::move(out_body)); + msg.putProperty(MQMessageConst::PROPERTY_ALREADY_COMPRESSED_FLAG, "true"); + return true; + } + } + + return false; } SendResult* DefaultMQProducerImpl::sendSelectImpl(MessagePtr msg, @@ -763,9 +781,9 @@ SendResult* DefaultMQProducerImpl::sendSelectImpl(MessagePtr msg, SendCallback* sendCallback, long timeout) { auto beginStartTime = UtilAll::currentTimeMillis(); - Validators::checkMessage(*msg, m_producerConfig->getMaxMessageSize()); + Validators::checkMessage(*msg, dynamic_cast(client_config_.get())->getMaxMessageSize()); - TopicPublishInfoPtr topicPublishInfo = m_clientInstance->tryToFindTopicPublishInfo(msg->getTopic()); + TopicPublishInfoPtr topicPublishInfo = client_instance_->tryToFindTopicPublishInfo(msg->getTopic()); if (topicPublishInfo != nullptr && topicPublishInfo->ok()) { MQMessageQueue mq = selector->select(topicPublishInfo->getMessageQueueList(), MQMessage(msg), arg); @@ -781,6 +799,25 @@ SendResult* DefaultMQProducerImpl::sendSelectImpl(MessagePtr msg, THROW_MQEXCEPTION(MQClientException, info, -1); } +void DefaultMQProducerImpl::initTransactionEnv() { + if (nullptr == check_transaction_executor_) { + check_transaction_executor_.reset(new thread_pool_executor(1, false)); + } + check_transaction_executor_->startup(); +} + +void DefaultMQProducerImpl::destroyTransactionEnv() { + check_transaction_executor_->shutdown(); +} + +TransactionListener* DefaultMQProducerImpl::getCheckListener() { + auto transactionProducerConfig = dynamic_cast(client_config_.get()); + if (transactionProducerConfig != nullptr) { + return transactionProducerConfig->getTransactionListener(); + } + return nullptr; +}; + TransactionSendResult* DefaultMQProducerImpl::sendMessageInTransactionImpl(MessagePtr msg, void* arg, long timeout) { auto* transactionListener = getCheckListener(); if (nullptr == transactionListener) { @@ -789,9 +826,9 @@ TransactionSendResult* DefaultMQProducerImpl::sendMessageInTransactionImpl(Messa std::unique_ptr sendResult; MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_TRANSACTION_PREPARED, "true"); - MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_PRODUCER_GROUP, m_producerConfig->getGroupName()); + MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_PRODUCER_GROUP, client_config_->getGroupName()); try { - sendResult.reset(sendDefaultImpl(msg, CommunicationMode::SYNC, nullptr, timeout)); + sendResult.reset(sendDefaultImpl(msg, SYNC, nullptr, timeout)); } catch (MQException& e) { THROW_MQEXCEPTION(MQClientException, "send message Exception", -1); } @@ -841,13 +878,39 @@ TransactionSendResult* DefaultMQProducerImpl::sendMessageInTransactionImpl(Messa return transactionSendResult; } -TransactionListener* DefaultMQProducerImpl::getCheckListener() { - auto transactionProducerConfig = std::dynamic_pointer_cast(m_producerConfig); - if (transactionProducerConfig != nullptr) { - return transactionProducerConfig->getTransactionListener(); +void DefaultMQProducerImpl::endTransaction(SendResult& sendResult, + LocalTransactionState localTransactionState, + std::exception_ptr& localException) { + const auto& msg_id = !sendResult.getOffsetMsgId().empty() ? sendResult.getOffsetMsgId() : sendResult.getMsgId(); + auto id = MessageDecoder::decodeMessageId(msg_id); + const auto& transactionId = sendResult.getTransactionId(); + std::string brokerAddr = client_instance_->findBrokerAddressInPublish(sendResult.getMessageQueue().broker_name()); + EndTransactionRequestHeader* requestHeader = new EndTransactionRequestHeader(); + requestHeader->transactionId = transactionId; + requestHeader->commitLogOffset = id.getOffset(); + switch (localTransactionState) { + case COMMIT_MESSAGE: + requestHeader->commitOrRollback = MessageSysFlag::TRANSACTION_COMMIT_TYPE; + break; + case ROLLBACK_MESSAGE: + requestHeader->commitOrRollback = MessageSysFlag::TRANSACTION_ROLLBACK_TYPE; + break; + case UNKNOWN: + requestHeader->commitOrRollback = MessageSysFlag::TRANSACTION_NOT_TYPE; + break; + default: + break; } - return nullptr; -}; + + requestHeader->producerGroup = client_config_->getGroupName(); + requestHeader->tranStateTableOffset = sendResult.getQueueOffset(); + requestHeader->msgId = sendResult.getMsgId(); + + std::string remark = + localException ? ("executeLocalTransactionBranch exception: " + UtilAll::to_string(localException)) : null; + + client_instance_->getMQClientAPIImpl()->endTransactionOneway(brokerAddr, requestHeader, remark); +} void DefaultMQProducerImpl::checkTransactionState(const std::string& addr, MessageExtPtr msg, @@ -858,9 +921,9 @@ void DefaultMQProducerImpl::checkTransactionState(const std::string& addr, std::string transactionId = checkRequestHeader->transactionId; std::string offsetMsgId = checkRequestHeader->offsetMsgId; - m_checkTransactionExecutor->submit(std::bind(&DefaultMQProducerImpl::checkTransactionStateImpl, this, addr, msg, - tranStateTableOffset, commitLogOffset, msgId, transactionId, - offsetMsgId)); + check_transaction_executor_->submit(std::bind(&DefaultMQProducerImpl::checkTransactionStateImpl, this, addr, msg, + tranStateTableOffset, commitLogOffset, msgId, transactionId, + offsetMsgId)); } void DefaultMQProducerImpl::checkTransactionStateImpl(const std::string& addr, @@ -873,7 +936,7 @@ void DefaultMQProducerImpl::checkTransactionStateImpl(const std::string& addr, auto* transactionCheckListener = getCheckListener(); if (nullptr == transactionCheckListener) { LOG_WARN_NEW("CheckTransactionState, pick transactionCheckListener by group[{}] failed", - m_producerConfig->getGroupName()); + client_config_->getGroupName()); return; } @@ -888,7 +951,7 @@ void DefaultMQProducerImpl::checkTransactionStateImpl(const std::string& addr, EndTransactionRequestHeader* endHeader = new EndTransactionRequestHeader(); endHeader->commitLogOffset = commitLogOffset; - endHeader->producerGroup = m_producerConfig->getGroupName(); + endHeader->producerGroup = client_config_->getGroupName(); endHeader->tranStateTableOffset = tranStateTableOffset; endHeader->fromTransactionCheck = true; @@ -921,76 +984,18 @@ void DefaultMQProducerImpl::checkTransactionStateImpl(const std::string& addr, } try { - m_clientInstance->getMQClientAPIImpl()->endTransactionOneway(addr, endHeader, remark); + client_instance_->getMQClientAPIImpl()->endTransactionOneway(addr, endHeader, remark); } catch (std::exception& e) { LOG_ERROR_NEW("endTransactionOneway exception: {}", e.what()); } } -void DefaultMQProducerImpl::endTransaction(SendResult& sendResult, - LocalTransactionState localTransactionState, - std::exception_ptr& localException) { - const auto& msg_id = !sendResult.getOffsetMsgId().empty() ? sendResult.getOffsetMsgId() : sendResult.getMsgId(); - auto id = MessageDecoder::decodeMessageId(msg_id); - const auto& transactionId = sendResult.getTransactionId(); - std::string brokerAddr = m_clientInstance->findBrokerAddressInPublish(sendResult.getMessageQueue().getBrokerName()); - EndTransactionRequestHeader* requestHeader = new EndTransactionRequestHeader(); - requestHeader->transactionId = transactionId; - requestHeader->commitLogOffset = id.getOffset(); - switch (localTransactionState) { - case COMMIT_MESSAGE: - requestHeader->commitOrRollback = MessageSysFlag::TRANSACTION_COMMIT_TYPE; - break; - case ROLLBACK_MESSAGE: - requestHeader->commitOrRollback = MessageSysFlag::TRANSACTION_ROLLBACK_TYPE; - break; - case UNKNOWN: - requestHeader->commitOrRollback = MessageSysFlag::TRANSACTION_NOT_TYPE; - break; - default: - break; - } - - requestHeader->producerGroup = m_producerConfig->getGroupName(); - requestHeader->tranStateTableOffset = sendResult.getQueueOffset(); - requestHeader->msgId = sendResult.getMsgId(); - - std::string remark = - localException ? ("executeLocalTransactionBranch exception: " + UtilAll::to_string(localException)) : null; - - m_clientInstance->getMQClientAPIImpl()->endTransactionOneway(brokerAddr, requestHeader, remark); -} - -bool DefaultMQProducerImpl::tryToCompressMessage(Message& msg) { - if (msg.isBatch()) { - // batch dose not support compressing right now - return false; - } - - // already compressed - if (UtilAll::stob(msg.getProperty(MQMessageConst::PROPERTY_ALREADY_COMPRESSED_FLAG))) { - return true; - } - - const auto& body = msg.getBody(); - if (body.size() >= m_producerConfig->getCompressMsgBodyOverHowmuch()) { - std::string out_body; - if (UtilAll::deflate(body, out_body, m_producerConfig->getCompressLevel())) { - msg.setBody(std::move(out_body)); - msg.putProperty(MQMessageConst::PROPERTY_ALREADY_COMPRESSED_FLAG, "true"); - return true; - } - } - - return false; -} - bool DefaultMQProducerImpl::isSendLatencyFaultEnable() const { - return m_mqFaultStrategy->isSendLatencyFaultEnable(); + return mq_fault_strategy_->isSendLatencyFaultEnable(); } void DefaultMQProducerImpl::setSendLatencyFaultEnable(bool sendLatencyFaultEnable) { - m_mqFaultStrategy->setSendLatencyFaultEnable(sendLatencyFaultEnable); + mq_fault_strategy_->setSendLatencyFaultEnable(sendLatencyFaultEnable); } } // namespace rocketmq diff --git a/src/producer/DefaultMQProducerImpl.h b/src/producer/DefaultMQProducerImpl.h index b3f42095b..d93d5ea33 100644 --- a/src/producer/DefaultMQProducerImpl.h +++ b/src/producer/DefaultMQProducerImpl.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __DEFAULT_MQ_PRODUCER_IMPL_H__ -#define __DEFAULT_MQ_PRODUCER_IMPL_H__ +#ifndef ROCKETMQ_PRODUCER_DEFAULTMQPRODUCERIMPL_H_ +#define ROCKETMQ_PRODUCER_DEFAULTMQPRODUCERIMPL_H_ #include "CommunicationMode.h" #include "DefaultMQProducer.h" @@ -32,11 +32,18 @@ class thread_pool_executor; class DefaultMQProducerImpl; typedef std::shared_ptr DefaultMQProducerImplPtr; +/** + * DefaultMQProducerImpl - implement of DefaultMQProducer + */ class DefaultMQProducerImpl : public std::enable_shared_from_this, public MQProducer, public MQClientImpl, public MQProducerInner { public: + /** + * create() - Factory method for DefaultMQProducerImpl, used to ensure that all objects of DefaultMQProducerImpl are + * managed by std::share_ptr + */ static DefaultMQProducerImplPtr create(DefaultMQProducerConfigPtr config, RPCHookPtr rpcHook = nullptr) { if (nullptr == rpcHook) { return DefaultMQProducerImplPtr(new DefaultMQProducerImpl(config)); @@ -111,31 +118,21 @@ class DefaultMQProducerImpl : public std::enable_shared_from_this topicPublishInfo, long timeout); + + bool tryToCompressMessage(Message& msg); + SendResult* sendSelectImpl(MessagePtr msg, MessageQueueSelector* selector, void* arg, @@ -144,6 +141,11 @@ class DefaultMQProducerImpl : public std::enable_shared_from_this& msgs); void prepareSendRequest(Message& msg, long timeout); + public: + const MQMessageQueue& selectOneMessageQueue(const TopicPublishInfo* tpInfo, const std::string& lastBrokerName); + void updateFaultItem(const std::string& brokerName, const long currentLatency, bool isolation); + + void initTransactionEnv(); + void destroyTransactionEnv(); + + public: + bool isSendLatencyFaultEnable() const; + void setSendLatencyFaultEnable(bool sendLatencyFaultEnable); + private: - DefaultMQProducerConfigPtr m_producerConfig; - std::unique_ptr m_mqFaultStrategy; - std::unique_ptr m_checkTransactionExecutor; + std::unique_ptr mq_fault_strategy_; + std::unique_ptr check_transaction_executor_; }; } // namespace rocketmq -#endif // __DEFAULT_MQ_PRODUCER_IMPL_H__ +#endif // ROCKETMQ_PRODUCER_DEFAULTMQPRODUCERIMPL_H_ diff --git a/src/producer/LatencyFaultTolerancyImpl.cpp b/src/producer/LatencyFaultTolerancyImpl.cpp index 7d428ed48..a055d6b3f 100644 --- a/src/producer/LatencyFaultTolerancyImpl.cpp +++ b/src/producer/LatencyFaultTolerancyImpl.cpp @@ -16,7 +16,9 @@ */ #include "LatencyFaultTolerancyImpl.h" -#include +#include // std::sort +#include // std::stringstream +#include // std::vector #include "UtilAll.h" @@ -25,70 +27,78 @@ namespace rocketmq { void LatencyFaultTolerancyImpl::updateFaultItem(const std::string& name, const long currentLatency, const long notAvailableDuration) { - std::lock_guard lock(m_faultItemTableMutex); - auto it = m_faultItemTable.find(name); - if (it == m_faultItemTable.end()) { - auto pair = m_faultItemTable.emplace(name, name); + std::lock_guard lock(fault_item_table_mutex_); + auto it = fault_item_table_.find(name); + if (it == fault_item_table_.end()) { + auto pair = fault_item_table_.emplace(name, name); it = pair.first; } auto& faultItem = it->second; - faultItem.m_currentLatency = currentLatency; - faultItem.m_startTimestamp = UtilAll::currentTimeMillis() + notAvailableDuration; + faultItem.current_latency_ = currentLatency; + faultItem.start_timestamp_ = UtilAll::currentTimeMillis() + notAvailableDuration; } bool LatencyFaultTolerancyImpl::isAvailable(const std::string& name) { - std::lock_guard lock(m_faultItemTableMutex); - const auto& it = m_faultItemTable.find(name); - if (it != m_faultItemTable.end()) { + std::lock_guard lock(fault_item_table_mutex_); + const auto& it = fault_item_table_.find(name); + if (it != fault_item_table_.end()) { return it->second.isAvailable(); } return true; } void LatencyFaultTolerancyImpl::remove(const std::string& name) { - std::lock_guard lock(m_faultItemTableMutex); - m_faultItemTable.erase(name); + std::lock_guard lock(fault_item_table_mutex_); + fault_item_table_.erase(name); } std::string LatencyFaultTolerancyImpl::pickOneAtLeast() { - std::lock_guard lock(m_faultItemTableMutex); - if (m_faultItemTable.empty()) { + std::lock_guard lock(fault_item_table_mutex_); + if (fault_item_table_.empty()) { return null; } - if (m_faultItemTable.size() == 1) { - return m_faultItemTable.begin()->second.m_name; + if (fault_item_table_.size() == 1) { + return fault_item_table_.begin()->second.name_; } std::vector tmpList; - tmpList.reserve(m_faultItemTable.size()); - for (const auto& it : m_faultItemTable) { + tmpList.reserve(fault_item_table_.size()); + for (const auto& it : fault_item_table_) { tmpList.push_back(ComparableFaultItem(it.second)); } std::sort(tmpList.begin(), tmpList.end()); auto half = tmpList.size() / 2; - auto i = m_whichItemWorst.fetch_add(1) % half; - return tmpList[i].m_name; + auto i = which_item_worst_.fetch_add(1) % half; + return tmpList[i].name_; } -LatencyFaultTolerancyImpl::FaultItem::FaultItem(const std::string& name) : m_name(name) {} +LatencyFaultTolerancyImpl::FaultItem::FaultItem(const std::string& name) : name_(name) {} bool LatencyFaultTolerancyImpl::FaultItem::isAvailable() const { - return UtilAll::currentTimeMillis() - m_startTimestamp >= 0; + return UtilAll::currentTimeMillis() - start_timestamp_ >= 0; +} + +std::string LatencyFaultTolerancyImpl::FaultItem::toString() const { + std::stringstream ss; + ss << "FaultItem{" + << "name='" << name_ << "'" + << ", currentLatency=" << current_latency_ << ", startTimestamp=" << start_timestamp_ << "}"; + return ss.str(); } bool LatencyFaultTolerancyImpl::ComparableFaultItem::operator<(const ComparableFaultItem& other) const { - if (m_isAvailable != other.m_isAvailable) { - return m_isAvailable; + if (is_available_ != other.is_available_) { + return is_available_; } - if (m_currentLatency != other.m_currentLatency) { - return m_currentLatency < other.m_currentLatency; + if (current_latency_ != other.current_latency_) { + return current_latency_ < other.current_latency_; } - return m_startTimestamp < other.m_startTimestamp; + return start_timestamp_ < other.start_timestamp_; } } // namespace rocketmq diff --git a/src/producer/LatencyFaultTolerancyImpl.h b/src/producer/LatencyFaultTolerancyImpl.h index fe74a32ac..de48b95f1 100644 --- a/src/producer/LatencyFaultTolerancyImpl.h +++ b/src/producer/LatencyFaultTolerancyImpl.h @@ -14,15 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __LATENCY_FAULT_TOLERANCY_IMPL__ -#define __LATENCY_FAULT_TOLERANCY_IMPL__ +#ifndef ROCKETMQ_PRODUCER_LATENCYFAULTTOLERANCYIMPL_H_ +#define ROCKETMQ_PRODUCER_LATENCYFAULTTOLERANCYIMPL_H_ -#include -#include -#include -#include -#include -#include +#include // std::atomic +#include // std::map +#include // std::mutex +#include // std::string namespace rocketmq { @@ -43,45 +41,39 @@ class LatencyFaultTolerancyImpl { bool isAvailable() const; - std::string toString() const { - std::stringstream ss; - ss << "FaultItem{" - << "name='" << m_name << "'" - << ", currentLatency=" << m_currentLatency << ", startTimestamp=" << m_startTimestamp << "}"; - return ss.str(); - } + std::string toString() const; public: - std::string m_name; - volatile long m_currentLatency; - volatile int64_t m_startTimestamp; + std::string name_; + volatile long current_latency_; + volatile int64_t start_timestamp_; }; class ComparableFaultItem { public: ComparableFaultItem(const FaultItem& item) - : m_name(item.m_name), - m_isAvailable(item.isAvailable()), - m_currentLatency(item.m_currentLatency), - m_startTimestamp(item.m_startTimestamp) {} + : name_(item.name_), + is_available_(item.isAvailable()), + current_latency_(item.current_latency_), + start_timestamp_(item.start_timestamp_) {} bool operator<(const ComparableFaultItem& other) const; public: - std::string m_name; - bool m_isAvailable; - long m_currentLatency; - int64_t m_startTimestamp; + std::string name_; + bool is_available_; + long current_latency_; + int64_t start_timestamp_; }; private: // brokerName -> FaultItem - std::map m_faultItemTable; - std::mutex m_faultItemTableMutex; + std::map fault_item_table_; + std::mutex fault_item_table_mutex_; - std::atomic m_whichItemWorst; + std::atomic which_item_worst_; }; } // namespace rocketmq -#endif // __LATENCY_FAULT_TOLERANCY_IMPL__ +#endif // ROCKETMQ_PRODUCER_LATENCYFAULTTOLERANCYIMPL_H_ diff --git a/src/producer/MQFaultStrategy.cpp b/src/producer/MQFaultStrategy.cpp index 9abef32c4..23f279ca3 100644 --- a/src/producer/MQFaultStrategy.cpp +++ b/src/producer/MQFaultStrategy.cpp @@ -32,7 +32,7 @@ const MQMessageQueue& MQFaultStrategy::selectOneMessageQueue(const TopicPublishI for (size_t i = 0; i < messageQueueList.size(); i++) { auto pos = index++ % messageQueueList.size(); const auto& mq = messageQueueList[pos]; - if (m_latencyFaultTolerance.isAvailable(mq.getBrokerName())) { + if (m_latencyFaultTolerance.isAvailable(mq.broker_name())) { return mq; } } @@ -45,8 +45,8 @@ const MQMessageQueue& MQFaultStrategy::selectOneMessageQueue(const TopicPublishI static thread_local MQMessageQueue mq; mq = tpInfo->selectOneMessageQueue(); if (!notBestBroker.empty()) { - mq.setBrokerName(notBestBroker); - mq.setQueueId(tpInfo->getSendWhichQueue().fetch_add(1) % writeQueueNums); + mq.set_broker_name(notBestBroker); + mq.set_queue_id(tpInfo->getSendWhichQueue().fetch_add(1) % writeQueueNums); } return mq; } else { diff --git a/src/producer/MQFaultStrategy.h b/src/producer/MQFaultStrategy.h index 4110d7fc9..8eccbb84c 100644 --- a/src/producer/MQFaultStrategy.h +++ b/src/producer/MQFaultStrategy.h @@ -14,15 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_FAULT_STRATEGY_H__ -#define __MQ_FAULT_STRATEGY_H__ +#ifndef ROCKETMQ_PRODUCER_MQFAULTSTRATEGY_H_ +#define ROCKETMQ_PRODUCER_MQFAULTSTRATEGY_H_ #include #include #include "LatencyFaultTolerancyImpl.h" #include "MQMessageQueue.h" -#include "TopicPublishInfo.h" +#include "TopicPublishInfo.hpp" namespace rocketmq { @@ -63,4 +63,4 @@ class MQFaultStrategy { } // namespace rocketmq -#endif // __MQ_FAULT_STRATEGY_H__ +#endif // ROCKETMQ_PRODUCER_MQFAULTSTRATEGY_H_ diff --git a/src/producer/MQProducerInner.h b/src/producer/MQProducerInner.h index c0538c33a..97476a0b6 100644 --- a/src/producer/MQProducerInner.h +++ b/src/producer/MQProducerInner.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_PRODUCER_INNER_H__ -#define __MQ_PRODUCER_INNER_H__ +#ifndef ROCKETMQ_PRODUCER_MQPRODUCERINNER_H_ +#define ROCKETMQ_PRODUCER_MQPRODUCERINNER_H_ #include "TransactionListener.h" @@ -40,4 +40,4 @@ class MQProducerInner { } // namespace rocketmq -#endif // __MQ_PRODUCER_INNER_H__ +#endif // ROCKETMQ_PRODUCER_MQPRODUCERINNER_H_ diff --git a/src/producer/RequestFutureTable.cpp b/src/producer/RequestFutureTable.cpp index 5a8b444d9..fba50d4d8 100644 --- a/src/producer/RequestFutureTable.cpp +++ b/src/producer/RequestFutureTable.cpp @@ -18,20 +18,20 @@ namespace rocketmq { -std::map> RequestFutureTable::s_futureTable; -std::mutex RequestFutureTable::s_futureTableMutex; +std::map> RequestFutureTable::future_table_; +std::mutex RequestFutureTable::future_table_mutex_; void RequestFutureTable::putRequestFuture(std::string correlationId, std::shared_ptr future) { - std::lock_guard lock(s_futureTableMutex); - s_futureTable[correlationId] = future; + std::lock_guard lock(future_table_mutex_); + future_table_[correlationId] = future; } std::shared_ptr RequestFutureTable::removeRequestFuture(std::string correlationId) { - std::lock_guard lock(s_futureTableMutex); - const auto& it = s_futureTable.find(correlationId); - if (it != s_futureTable.end()) { + std::lock_guard lock(future_table_mutex_); + const auto& it = future_table_.find(correlationId); + if (it != future_table_.end()) { auto requestFuture = it->second; - s_futureTable.erase(it); + future_table_.erase(it); return requestFuture; } return nullptr; diff --git a/src/producer/RequestFutureTable.h b/src/producer/RequestFutureTable.h index ed589ecc3..4f9630e79 100644 --- a/src/producer/RequestFutureTable.h +++ b/src/producer/RequestFutureTable.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __REQUEST_FUTURE_TABLE__ -#define __REQUEST_FUTURE_TABLE__ +#ifndef ROCKETMQ_PRODUCER_REQUESTFUTURETABLE_H_ +#define ROCKETMQ_PRODUCER_REQUESTFUTURETABLE_H_ #include #include @@ -31,10 +31,10 @@ class RequestFutureTable { static std::shared_ptr removeRequestFuture(std::string correlationId); private: - static std::map> s_futureTable; - static std::mutex s_futureTableMutex; + static std::map> future_table_; + static std::mutex future_table_mutex_; }; } // namespace rocketmq -#endif // __REQUEST_FUTURE_TABLE__ +#endif // ROCKETMQ_PRODUCER_REQUESTFUTURETABLE_H_ diff --git a/src/producer/RequestResponseFuture.cpp b/src/producer/RequestResponseFuture.cpp index d798057db..5bdcd61cc 100644 --- a/src/producer/RequestResponseFuture.cpp +++ b/src/producer/RequestResponseFuture.cpp @@ -24,85 +24,65 @@ namespace rocketmq { RequestResponseFuture::RequestResponseFuture(const std::string& correlationId, long timeoutMillis, RequestCallback* requestCallback) - : m_correlationId(correlationId), - m_requestCallback(requestCallback), - m_beginTimestamp(UtilAll::currentTimeMillis()), - m_requestMsg(nullptr), - m_timeoutMillis(timeoutMillis), - m_countDownLatch(nullptr), - m_responseMsg(nullptr), - m_sendRequestOk(false), - m_cause(nullptr) { + : correlation_id_(correlationId), + request_callback_(requestCallback), + begin_timestamp_(UtilAll::currentTimeMillis()), + request_msg_(nullptr), + timeout_millis_(timeoutMillis), + count_down_latch_(nullptr), + response_msg_(nullptr), + send_request_ok_(false), + cause_(nullptr) { if (nullptr == requestCallback) { - m_countDownLatch.reset(new latch(1)); + count_down_latch_.reset(new latch(1)); } } void RequestResponseFuture::executeRequestCallback() noexcept { - if (m_requestCallback != nullptr) { - if (m_sendRequestOk && m_cause == nullptr) { + if (request_callback_ != nullptr) { + if (send_request_ok_ && cause_ == nullptr) { try { - m_requestCallback->onSuccess(std::move(m_responseMsg)); + request_callback_->onSuccess(std::move(response_msg_)); } catch (const std::exception& e) { LOG_WARN_NEW("RequestCallback throw an exception: {}", e.what()); } } else { try { - std::rethrow_exception(m_cause); + std::rethrow_exception(cause_); } catch (MQException& e) { - m_requestCallback->onException(e); + request_callback_->onException(e); } catch (const std::exception& e) { LOG_WARN_NEW("unexpected exception in RequestResponseFuture: {}", e.what()); } } // auto delete callback - if (m_requestCallback->getRequestCallbackType() == REQUEST_CALLBACK_TYPE_AUTO_DELETE) { - deleteAndZero(m_requestCallback); + if (request_callback_->getRequestCallbackType() == REQUEST_CALLBACK_TYPE_AUTO_DELETE) { + deleteAndZero(request_callback_); } } } bool RequestResponseFuture::isTimeout() { - auto diff = UtilAll::currentTimeMillis() - m_beginTimestamp; - return diff > m_timeoutMillis; + auto diff = UtilAll::currentTimeMillis() - begin_timestamp_; + return diff > timeout_millis_; } MessagePtr RequestResponseFuture::waitResponseMessage(int64_t timeout) { - if (m_countDownLatch != nullptr) { + if (count_down_latch_ != nullptr) { if (timeout < 0) { timeout = 0; } - m_countDownLatch->wait(timeout, time_unit::milliseconds); + count_down_latch_->wait(timeout, time_unit::milliseconds); } - return m_responseMsg; + return response_msg_; } void RequestResponseFuture::putResponseMessage(MessagePtr responseMsg) { - m_responseMsg = std::move(responseMsg); - if (m_countDownLatch != nullptr) { - m_countDownLatch->count_down(); + response_msg_ = std::move(responseMsg); + if (count_down_latch_ != nullptr) { + count_down_latch_->count_down(); } } -const std::string& RequestResponseFuture::getCorrelationId() { - return m_correlationId; -} - -bool RequestResponseFuture::isSendRequestOk() { - return m_sendRequestOk; -} - -void RequestResponseFuture::setSendRequestOk(bool sendRequestOk) { - m_sendRequestOk = sendRequestOk; -} - -std::exception_ptr RequestResponseFuture::getCause() { - return m_cause; -} - -void RequestResponseFuture::setCause(std::exception_ptr cause) { - m_cause = cause; -} - } // namespace rocketmq diff --git a/src/producer/RequestResponseFuture.h b/src/producer/RequestResponseFuture.h index 9f82eb815..4e5ebb38f 100644 --- a/src/producer/RequestResponseFuture.h +++ b/src/producer/RequestResponseFuture.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __REQUEST_RESPONSE_FUTURE__ -#define __REQUEST_RESPONSE_FUTURE__ +#ifndef ROCKETMQ_PRODUCER_REQUESTRESPONSEFUTURE_H_ +#define ROCKETMQ_PRODUCER_REQUESTRESPONSEFUTURE_H_ #include #include @@ -37,26 +37,27 @@ class RequestResponseFuture { MessagePtr waitResponseMessage(int64_t timeout); void putResponseMessage(MessagePtr responseMsg); - const std::string& getCorrelationId(); + public: + inline const std::string& correlation_id() const { return correlation_id_; } - bool isSendRequestOk(); - void setSendRequestOk(bool sendRequestOk); + inline bool send_request_ok() const { return send_request_ok_; } + inline void set_send_request_ok(bool sendRequestOk) { send_request_ok_ = sendRequestOk; } - std::exception_ptr getCause(); - void setCause(std::exception_ptr cause); + inline std::exception_ptr cause() const { return cause_; } + inline void set_cause(std::exception_ptr cause) { cause_ = cause; } private: - std::string m_correlationId; - RequestCallback* m_requestCallback; - uint64_t m_beginTimestamp; - MessagePtr m_requestMsg; - long m_timeoutMillis; - std::unique_ptr m_countDownLatch; // use for synchronization rpc - MessagePtr m_responseMsg; - bool m_sendRequestOk; - std::exception_ptr m_cause; + std::string correlation_id_; + RequestCallback* request_callback_; + uint64_t begin_timestamp_; + MessagePtr request_msg_; + long timeout_millis_; + std::unique_ptr count_down_latch_; // use for synchronization rpc + MessagePtr response_msg_; + bool send_request_ok_; + std::exception_ptr cause_; }; } // namespace rocketmq -#endif // __REQUEST_RESPONSE_FUTURE__ +#endif // ROCKETMQ_PRODUCER_REQUESTRESPONSEFUTURE_H_ diff --git a/src/producer/SendResult.cpp b/src/producer/SendResult.cpp index 74f4f1344..4fc9270a9 100644 --- a/src/producer/SendResult.cpp +++ b/src/producer/SendResult.cpp @@ -18,74 +18,17 @@ #include -#include "UtilAll.h" -#include "VirtualEnvUtil.h" - namespace rocketmq { -SendResult::SendResult() : m_sendStatus(SEND_OK), m_queueOffset(0) {} - -SendResult::SendResult(const SendStatus& sendStatus, - const std::string& msgId, - const std::string& offsetMsgId, - const MQMessageQueue& messageQueue, - int64_t queueOffset) - : m_sendStatus(sendStatus), - m_msgId(msgId), - m_offsetMsgId(offsetMsgId), - m_messageQueue(messageQueue), - m_queueOffset(queueOffset) {} - -SendResult::SendResult(const SendResult& other) { - m_sendStatus = other.m_sendStatus; - m_msgId = other.m_msgId; - m_offsetMsgId = other.m_offsetMsgId; - m_messageQueue = other.m_messageQueue; - m_queueOffset = other.m_queueOffset; -} - -SendResult& SendResult::operator=(const SendResult& other) { - if (this != &other) { - m_sendStatus = other.m_sendStatus; - m_msgId = other.m_msgId; - m_offsetMsgId = other.m_offsetMsgId; - m_messageQueue = other.m_messageQueue; - m_queueOffset = other.m_queueOffset; - } - return *this; -} - -SendResult::~SendResult() = default; - -const std::string& SendResult::getMsgId() const { - return m_msgId; -} - -const std::string& SendResult::getOffsetMsgId() const { - return m_offsetMsgId; -} - -SendStatus SendResult::getSendStatus() const { - return m_sendStatus; -} - -const MQMessageQueue& SendResult::getMessageQueue() const { - return m_messageQueue; -} - -int64_t SendResult::getQueueOffset() const { - return m_queueOffset; -} - std::string SendResult::toString() const { std::stringstream ss; ss << "SendResult: "; - ss << "sendStatus:" << m_sendStatus; - ss << ", msgId:" << m_msgId; - ss << ", offsetMsgId:" << m_offsetMsgId; - ss << ", queueOffset:" << m_queueOffset; - ss << ", transactionId:" << m_transactionId; - ss << ", messageQueue:" << m_messageQueue.toString(); + ss << "sendStatus:" << send_status_; + ss << ", msgId:" << msg_id_; + ss << ", offsetMsgId:" << offset_msg_id_; + ss << ", queueOffset:" << queue_offset_; + ss << ", transactionId:" << transaction_id_; + ss << ", messageQueue:" << message_queue_.toString(); return ss.str(); } diff --git a/src/producer/TopicPublishInfo.h b/src/producer/TopicPublishInfo.h deleted file mode 100644 index af9c231a3..000000000 --- a/src/producer/TopicPublishInfo.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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 __TOPIC_PUBLISH_INFO_H__ -#define __TOPIC_PUBLISH_INFO_H__ - -#include -#include -#include - -#include "MQClientException.h" -#include "MQMessageQueue.h" -#include "TopicRouteData.h" - -namespace rocketmq { - -class TopicPublishInfo; -typedef std::shared_ptr TopicPublishInfoPtr; - -class TopicPublishInfo { - public: - typedef std::vector QueuesVec; - - public: - TopicPublishInfo() : m_orderTopic(false), m_haveTopicRouterInfo(false), m_sendWhichQueue(0) {} - - virtual ~TopicPublishInfo() = default; - - bool isOrderTopic() const { return m_orderTopic; } - - void setOrderTopic(bool orderTopic) { m_orderTopic = orderTopic; } - - bool ok() const { return !m_messageQueueList.empty(); } - - const QueuesVec& getMessageQueueList() const { return m_messageQueueList; } - - std::atomic& getSendWhichQueue() const { return m_sendWhichQueue; } - - bool isHaveTopicRouterInfo() { return m_haveTopicRouterInfo; } - - void setHaveTopicRouterInfo(bool haveTopicRouterInfo) { m_haveTopicRouterInfo = haveTopicRouterInfo; } - - const MQMessageQueue& selectOneMessageQueue(const std::string& lastBrokerName) const { - if (!lastBrokerName.empty()) { - auto mqSize = m_messageQueueList.size(); - if (mqSize <= 1) { - if (mqSize == 0) { - LOG_ERROR_NEW("[BUG] messageQueueList is empty"); - THROW_MQEXCEPTION(MQClientException, "messageQueueList is empty", -1); - } - return m_messageQueueList[0]; - } else { - // NOTE: If it possible, mq in same broker is nonadjacent. - auto index = m_sendWhichQueue.fetch_add(1); - for (size_t i = 0; i < 2; i++) { - auto pos = index++ % m_messageQueueList.size(); - auto& mq = m_messageQueueList[pos]; - if (mq.getBrokerName() != lastBrokerName) { - return mq; - } - } - return m_messageQueueList[(index - 2) % m_messageQueueList.size()]; - } - } - return selectOneMessageQueue(); - } - - const MQMessageQueue& selectOneMessageQueue() const { - auto index = m_sendWhichQueue.fetch_add(1); - auto pos = index % m_messageQueueList.size(); - return m_messageQueueList[pos]; - } - - int getQueueIdByBroker(const std::string& brokerName) const { - for (const auto& queueData : m_topicRouteData->getQueueDatas()) { - if (queueData.brokerName == brokerName) { - return queueData.writeQueueNums; - } - } - - return -1; - } - - void setTopicRouteData(TopicRouteDataPtr topicRouteData) { m_topicRouteData = topicRouteData; } - - private: - bool m_orderTopic; - bool m_haveTopicRouterInfo; - - QueuesVec m_messageQueueList; // no change after build - mutable std::atomic m_sendWhichQueue; - - TopicRouteDataPtr m_topicRouteData; // no change after set -}; - -} // namespace rocketmq - -#endif // __TOPIC_PUBLISH_INFO_H__ diff --git a/src/producer/TopicPublishInfo.hpp b/src/producer/TopicPublishInfo.hpp new file mode 100644 index 000000000..341e06616 --- /dev/null +++ b/src/producer/TopicPublishInfo.hpp @@ -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. + */ +#ifndef ROCKETMQ_PRODUCER_TOPICPUBLISHINFO_HPP_ +#define ROCKETMQ_PRODUCER_TOPICPUBLISHINFO_HPP_ + +#include // std::atomic +#include // std::shared_ptr +#include // std::mutex + +#include "MQException.h" +#include "MQMessageQueue.h" +#include "TopicRouteData.hpp" + +namespace rocketmq { + +class TopicPublishInfo; +typedef std::shared_ptr TopicPublishInfoPtr; + +class TopicPublishInfo { + public: + typedef std::vector QueuesVec; + + public: + TopicPublishInfo() : order_topic_(false), have_topic_router_info_(false), send_which_queue_(0) {} + + virtual ~TopicPublishInfo() = default; + + bool isOrderTopic() const { return order_topic_; } + + void setOrderTopic(bool orderTopic) { order_topic_ = orderTopic; } + + bool ok() const { return !message_queue_list_.empty(); } + + const QueuesVec& getMessageQueueList() const { return message_queue_list_; } + + std::atomic& getSendWhichQueue() const { return send_which_queue_; } + + bool isHaveTopicRouterInfo() { return have_topic_router_info_; } + + void setHaveTopicRouterInfo(bool haveTopicRouterInfo) { have_topic_router_info_ = haveTopicRouterInfo; } + + const MQMessageQueue& selectOneMessageQueue(const std::string& lastBrokerName) const { + if (!lastBrokerName.empty()) { + auto mqSize = message_queue_list_.size(); + if (mqSize <= 1) { + if (mqSize == 0) { + LOG_ERROR_NEW("[BUG] messageQueueList is empty"); + THROW_MQEXCEPTION(MQClientException, "messageQueueList is empty", -1); + } + return message_queue_list_[0]; + } else { + // NOTE: If it possible, mq in same broker is nonadjacent. + auto index = send_which_queue_.fetch_add(1); + for (size_t i = 0; i < 2; i++) { + auto pos = index++ % message_queue_list_.size(); + auto& mq = message_queue_list_[pos]; + if (mq.broker_name() != lastBrokerName) { + return mq; + } + } + return message_queue_list_[(index - 2) % message_queue_list_.size()]; + } + } + return selectOneMessageQueue(); + } + + const MQMessageQueue& selectOneMessageQueue() const { + auto index = send_which_queue_.fetch_add(1); + auto pos = index % message_queue_list_.size(); + return message_queue_list_[pos]; + } + + int getQueueIdByBroker(const std::string& brokerName) const { + for (const auto& queueData : topic_route_data_->queue_datas()) { + if (queueData.broker_name() == brokerName) { + return queueData.write_queue_nums(); + } + } + + return -1; + } + + void setTopicRouteData(TopicRouteDataPtr topicRouteData) { topic_route_data_ = topicRouteData; } + + private: + bool order_topic_; + bool have_topic_router_info_; + + QueuesVec message_queue_list_; // no change after build + mutable std::atomic send_which_queue_; + + TopicRouteDataPtr topic_route_data_; // no change after set +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_PRODUCER_TOPICPUBLISHINFO_HPP_ diff --git a/src/producer/TransactionMQProducer.cpp b/src/producer/TransactionMQProducer.cpp index cae9240e9..9ace2d9ef 100644 --- a/src/producer/TransactionMQProducer.cpp +++ b/src/producer/TransactionMQProducer.cpp @@ -17,7 +17,7 @@ #include "TransactionMQProducer.h" #include "DefaultMQProducerImpl.h" -#include "TransactionMQProducerConfigImpl.h" +#include "TransactionMQProducerConfigImpl.hpp" namespace rocketmq { @@ -29,8 +29,22 @@ TransactionMQProducer::TransactionMQProducer(const std::string& groupname, RPCHo TransactionMQProducer::~TransactionMQProducer() = default; +void TransactionMQProducer::start() { + dynamic_cast(producer_impl_.get())->initTransactionEnv(); + DefaultMQProducer::start(); +} + +void TransactionMQProducer::shutdown() { + DefaultMQProducer::shutdown(); + dynamic_cast(producer_impl_.get())->destroyTransactionEnv(); +} + +TransactionSendResult TransactionMQProducer::sendMessageInTransaction(MQMessage& msg, void* arg) { + return producer_impl_->sendMessageInTransaction(msg, arg); +} + TransactionListener* TransactionMQProducer::getTransactionListener() const { - auto transactionProducerConfig = std::dynamic_pointer_cast(getRealConfig()); + auto transactionProducerConfig = dynamic_cast(client_config_.get()); if (transactionProducerConfig != nullptr) { return transactionProducerConfig->getTransactionListener(); } @@ -38,24 +52,10 @@ TransactionListener* TransactionMQProducer::getTransactionListener() const { } void TransactionMQProducer::setTransactionListener(TransactionListener* transactionListener) { - auto transactionProducerConfig = std::dynamic_pointer_cast(getRealConfig()); + auto transactionProducerConfig = dynamic_cast(client_config_.get()); if (transactionProducerConfig != nullptr) { transactionProducerConfig->setTransactionListener(transactionListener); } } -void TransactionMQProducer::start() { - std::dynamic_pointer_cast(producer_impl_)->initTransactionEnv(); - DefaultMQProducer::start(); -} - -void TransactionMQProducer::shutdown() { - DefaultMQProducer::shutdown(); - std::dynamic_pointer_cast(producer_impl_)->destroyTransactionEnv(); -} - -TransactionSendResult TransactionMQProducer::sendMessageInTransaction(MQMessage& msg, void* arg) { - return producer_impl_->sendMessageInTransaction(msg, arg); -} - } // namespace rocketmq diff --git a/src/producer/TransactionMQProducerConfigImpl.cpp b/src/producer/TransactionMQProducerConfigImpl.cpp deleted file mode 100644 index d3a3dbdfa..000000000 --- a/src/producer/TransactionMQProducerConfigImpl.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 "TransactionMQProducerConfigImpl.h" - -namespace rocketmq { - -TransactionMQProducerConfigImpl::TransactionMQProducerConfigImpl() : m_transactionListener(nullptr) {} - -TransactionListener* TransactionMQProducerConfigImpl::getTransactionListener() const { - return m_transactionListener; -} - -void TransactionMQProducerConfigImpl::setTransactionListener(TransactionListener* transactionListener) { - m_transactionListener = transactionListener; -} - -} // namespace rocketmq diff --git a/src/producer/TransactionMQProducerConfigImpl.h b/src/producer/TransactionMQProducerConfigImpl.hpp similarity index 69% rename from src/producer/TransactionMQProducerConfigImpl.h rename to src/producer/TransactionMQProducerConfigImpl.hpp index c12205149..e2085a3f7 100644 --- a/src/producer/TransactionMQProducerConfigImpl.h +++ b/src/producer/TransactionMQProducerConfigImpl.hpp @@ -14,27 +14,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __TRANSACTION_MQ_PRODUCER_CONFIG_IMPL_H__ -#define __TRANSACTION_MQ_PRODUCER_CONFIG_IMPL_H__ +#ifndef ROCKETMQ_PRODUCER_TRANSACTIONMQPRODUCERCONFIGIMPL_HPP_ +#define ROCKETMQ_PRODUCER_TRANSACTIONMQPRODUCERCONFIGIMPL_HPP_ -#include "DefaultMQProducerConfigImpl.h" +#include "DefaultMQProducerConfigImpl.hpp" #include "TransactionMQProducerConfig.h" namespace rocketmq { class TransactionMQProducerConfigImpl : virtual public TransactionMQProducerConfig, public DefaultMQProducerConfigImpl { public: - TransactionMQProducerConfigImpl(); + TransactionMQProducerConfigImpl() : transaction_listener_(nullptr) {} virtual ~TransactionMQProducerConfigImpl() = default; public: // TransactionMQProducerConfig - TransactionListener* getTransactionListener() const override; - void setTransactionListener(TransactionListener* transactionListener) override; + TransactionListener* getTransactionListener() const override { return transaction_listener_; } + void setTransactionListener(TransactionListener* transactionListener) override { + transaction_listener_ = transactionListener; + } protected: - TransactionListener* m_transactionListener; + TransactionListener* transaction_listener_; }; } // namespace rocketmq -#endif // __TRANSACTION_MQ_PRODUCER_CONFIG_IMPL_H__ +#endif // ROCKETMQ_PRODUCER_TRANSACTIONMQPRODUCERCONFIGIMPL_HPP_ diff --git a/src/protocol/ConsumerRunningInfo.cpp b/src/protocol/ConsumerRunningInfo.cpp index 19f5fff61..f1ae14f95 100644 --- a/src/protocol/ConsumerRunningInfo.cpp +++ b/src/protocol/ConsumerRunningInfo.cpp @@ -28,26 +28,6 @@ const std::string ConsumerRunningInfo::PROP_CONSUME_TYPE = "PROP_CONSUME_TYPE"; const std::string ConsumerRunningInfo::PROP_CLIENT_VERSION = "PROP_CLIENT_VERSION"; const std::string ConsumerRunningInfo::PROP_CONSUMER_START_TIMESTAMP = "PROP_CONSUMER_START_TIMESTAMP"; -const std::map ConsumerRunningInfo::getProperties() const { - return properties; -} - -void ConsumerRunningInfo::setProperties(const std::map& properties) { - this->properties = properties; -} - -void ConsumerRunningInfo::setProperty(const std::string& key, const std::string& value) { - properties[key] = value; -} - -const std::map ConsumerRunningInfo::getMqTable() const { - return mqTable; -} - -void ConsumerRunningInfo::setMqTable(const MQMessageQueue& queue, ProcessQueueInfo queueInfo) { - mqTable[queue] = queueInfo; -} - /* const std::map ConsumerRunningInfo::getStatusTable() const { return statusTable; } @@ -56,37 +36,21 @@ void ConsumerRunningInfo::setStatusTable(const std::mapstatusTable = statusTable; } */ -const std::vector ConsumerRunningInfo::getSubscriptionSet() const { - return subscriptionSet; -} - -void ConsumerRunningInfo::setSubscriptionSet(const std::vector& subscriptionSet) { - this->subscriptionSet = subscriptionSet; -} - -const std::string ConsumerRunningInfo::getJstack() const { - return jstack; -} - -void ConsumerRunningInfo::setJstack(const std::string& jstack) { - this->jstack = jstack; -} - std::string ConsumerRunningInfo::encode() { Json::Value outData; - outData[PROP_NAMESERVER_ADDR] = properties[PROP_NAMESERVER_ADDR]; - outData[PROP_CONSUME_TYPE] = properties[PROP_CONSUME_TYPE]; - outData[PROP_CLIENT_VERSION] = properties[PROP_CLIENT_VERSION]; - outData[PROP_CONSUMER_START_TIMESTAMP] = properties[PROP_CONSUMER_START_TIMESTAMP]; - outData[PROP_CONSUME_ORDERLY] = properties[PROP_CONSUME_ORDERLY]; - outData[PROP_THREADPOOL_CORE_SIZE] = properties[PROP_THREADPOOL_CORE_SIZE]; + outData[PROP_NAMESERVER_ADDR] = properties_[PROP_NAMESERVER_ADDR]; + outData[PROP_CONSUME_TYPE] = properties_[PROP_CONSUME_TYPE]; + outData[PROP_CLIENT_VERSION] = properties_[PROP_CLIENT_VERSION]; + outData[PROP_CONSUMER_START_TIMESTAMP] = properties_[PROP_CONSUMER_START_TIMESTAMP]; + outData[PROP_CONSUME_ORDERLY] = properties_[PROP_CONSUME_ORDERLY]; + outData[PROP_THREADPOOL_CORE_SIZE] = properties_[PROP_THREADPOOL_CORE_SIZE]; Json::Value root; - root["jstack"] = jstack; + root["jstack"] = jstack_; root["properties"] = outData; - for (const auto& subscription : subscriptionSet) { + for (const auto& subscription : subscription_set_) { root["subscriptionSet"].append(subscription.toJson()); } @@ -95,7 +59,7 @@ std::string ConsumerRunningInfo::encode() { Json::Value mq; std::string key = "\"mqTable\":"; key.append("{"); - for (const auto& it : mqTable) { + for (const auto& it : mq_table_) { key.append(toJson(it.first).toStyledString()); key.erase(key.end() - 1); key.append(":"); diff --git a/src/protocol/ConsumerRunningInfo.h b/src/protocol/ConsumerRunningInfo.h index cdc23dc90..63d4c5d23 100644 --- a/src/protocol/ConsumerRunningInfo.h +++ b/src/protocol/ConsumerRunningInfo.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __CONSUMER_RUNNING_INFO_H__ -#define __CONSUMER_RUNNING_INFO_H__ +#ifndef ROCKETMQ_PROTOCOL_CONSUMERRUNNINGINFO_H_ +#define ROCKETMQ_PROTOCOL_CONSUMERRUNNINGINFO_H_ #include "MessageQueue.h" #include "ProcessQueueInfo.h" @@ -24,14 +24,6 @@ namespace rocketmq { class ConsumerRunningInfo { - public: - ConsumerRunningInfo() {} - virtual ~ConsumerRunningInfo() { - properties.clear(); - mqTable.clear(); - subscriptionSet.clear(); - } - public: static const std::string PROP_NAMESERVER_ADDR; static const std::string PROP_THREADPOOL_CORE_SIZE; @@ -41,27 +33,42 @@ class ConsumerRunningInfo { static const std::string PROP_CONSUMER_START_TIMESTAMP; public: - const std::map getProperties() const; - void setProperties(const std::map& properties); - void setProperty(const std::string& key, const std::string& value); - const std::map getMqTable() const; - void setMqTable(const MQMessageQueue& queue, ProcessQueueInfo queueInfo); + ConsumerRunningInfo() {} + virtual ~ConsumerRunningInfo() { + properties_.clear(); + mq_table_.clear(); + subscription_set_.clear(); + } + + std::string encode(); + + public: + inline const std::map getProperties() const { return properties_; } + inline void setProperties(const std::map& properties) { properties_ = properties; } + inline void setProperty(const std::string& key, const std::string& value) { properties_[key] = value; } + + inline const std::map getMqTable() const { return mq_table_; } + inline void setMqTable(const MQMessageQueue& queue, ProcessQueueInfo queueInfo) { mq_table_[queue] = queueInfo; } + // const std::map getStatusTable() const; // void setStatusTable(const std::map& statusTable) ; - const std::vector getSubscriptionSet() const; - void setSubscriptionSet(const std::vector& subscriptionSet); - const std::string getJstack() const; - void setJstack(const std::string& jstack); - std::string encode(); + + inline const std::vector getSubscriptionSet() const { return subscription_set_; } + inline void setSubscriptionSet(const std::vector& subscriptionSet) { + subscription_set_ = subscriptionSet; + } + + inline const std::string getJstack() const { return jstack_; } + inline void setJstack(const std::string& jstack) { this->jstack_ = jstack; } private: - std::map properties; - std::vector subscriptionSet; - std::map mqTable; + std::map properties_; + std::vector subscription_set_; + std::map mq_table_; // std::map statusTable; - std::string jstack; + std::string jstack_; }; } // namespace rocketmq -#endif // __CONSUMER_RUNNING_INFO_H__ +#endif // ROCKETMQ_PROTOCOL_CONSUMERRUNNINGINFO_H_ diff --git a/src/protocol/MQProtos.h b/src/protocol/MQProtos.h index 29c6d792a..263a9a421 100644 --- a/src/protocol/MQProtos.h +++ b/src/protocol/MQProtos.h @@ -14,10 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_PROTOS_H__ -#define __MQ_PROTOS_H__ +#ifndef ROCKETMQ_PROTOCOL_MQPROTOS_H_ +#define ROCKETMQ_PROTOCOL_MQPROTOS_H_ #include "RequestCode.h" #include "ResponseCode.h" -#endif // __MQ_PROTOS_H__ +#endif // ROCKETMQ_PROTOCOL_MQPROTOS_H_ diff --git a/src/protocol/MessageQueue.cpp b/src/protocol/MessageQueue.cpp index f92f85ea1..ab9af65cf 100644 --- a/src/protocol/MessageQueue.cpp +++ b/src/protocol/MessageQueue.cpp @@ -20,9 +20,9 @@ namespace rocketmq { Json::Value toJson(const MQMessageQueue& mq) { Json::Value outJson; - outJson["topic"] = mq.getTopic(); - outJson["brokerName"] = mq.getBrokerName(); - outJson["queueId"] = mq.getQueueId(); + outJson["topic"] = mq.topic(); + outJson["brokerName"] = mq.broker_name(); + outJson["queueId"] = mq.queue_id(); return outJson; } diff --git a/src/protocol/RemotingCommand.cpp b/src/protocol/RemotingCommand.cpp index 25415239a..4e6284f9c 100644 --- a/src/protocol/RemotingCommand.cpp +++ b/src/protocol/RemotingCommand.cpp @@ -44,8 +44,8 @@ RemotingCommand::RemotingCommand(int32_t code, CommandCustomHeader* customHeader RemotingCommand::RemotingCommand(int32_t code, const std::string& remark, CommandCustomHeader* customHeader) : RemotingCommand(code, - MQVersion::s_CurrentLanguage, - MQVersion::s_CurrentVersion, + MQVersion::CURRENT_LANGUAGE, + MQVersion::CURRENT_VERSION, createNewRequestId(), 0, remark, @@ -148,8 +148,7 @@ static RemotingCommand* Decode(ByteBuffer& byteBuffer, bool hasPackageLength) { int32_t oriHeaderLen = byteBuffer.getInt(); int32_t headerLength = getHeaderLength(oriHeaderLen); - // ByteArray headData(headerLength); - // byteBuffer.get(headerData); + // temporary ByteArray ByteArray headerData(byteBuffer.array() + byteBuffer.arrayOffset() + byteBuffer.position(), headerLength); byteBuffer.position(byteBuffer.position() + headerLength); @@ -187,8 +186,7 @@ static RemotingCommand* Decode(ByteBuffer& byteBuffer, bool hasPackageLength) { int32_t bodyLength = length - 4 - headerLength; if (bodyLength > 0) { - // ByteArrayRef bodyData = std::make_shared(bodyLength); - // byteBuffer.get(*bodyData); + // slice ByteArray of byteBuffer to avoid copy data. ByteArrayRef bodyData = slice(byteBuffer.byte_array(), byteBuffer.arrayOffset() + byteBuffer.position(), bodyLength); byteBuffer.position(byteBuffer.position() + bodyLength); diff --git a/src/protocol/RemotingSerializable.cpp b/src/protocol/RemotingSerializable.cpp index e86492668..bac34ca58 100644 --- a/src/protocol/RemotingSerializable.cpp +++ b/src/protocol/RemotingSerializable.cpp @@ -19,7 +19,7 @@ #include #include -#include "MQClientException.h" +#include "MQException.h" namespace rocketmq { diff --git a/src/protocol/RemotingSerializable.h b/src/protocol/RemotingSerializable.h index e5a37d852..62a289d27 100644 --- a/src/protocol/RemotingSerializable.h +++ b/src/protocol/RemotingSerializable.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __REMOTING_SERIALIZABLE_H__ -#define __REMOTING_SERIALIZABLE_H__ +#ifndef ROCKETMQ_PROTOCOL_REMOTINGSERIALIZABLE_H_ +#define ROCKETMQ_PROTOCOL_REMOTINGSERIALIZABLE_H_ #include @@ -56,4 +56,4 @@ class RemotingSerializable { } // namespace rocketmq -#endif // __REMOTING_SERIALIZABLE_H__ +#endif // ROCKETMQ_PROTOCOL_REMOTINGSERIALIZABLE_H_ diff --git a/src/protocol/RequestCode.h b/src/protocol/RequestCode.h index a2a7abc16..68b8f3100 100644 --- a/src/protocol/RequestCode.h +++ b/src/protocol/RequestCode.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __REQUEST_CODE_H__ -#define __REQUEST_CODE_H__ +#ifndef ROCKETMQ_PROTOCOL_REQUESTCODE_H_ +#define ROCKETMQ_PROTOCOL_REQUESTCODE_H_ namespace rocketmq { @@ -141,4 +141,4 @@ enum MQRequestCode { } // namespace rocketmq -#endif // __REQUEST_CODE_H__ +#endif // ROCKETMQ_PROTOCOL_REQUESTCODE_H_ diff --git a/src/protocol/ResponseCode.h b/src/protocol/ResponseCode.h index 16d2096ed..316e48e56 100644 --- a/src/protocol/ResponseCode.h +++ b/src/protocol/ResponseCode.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __RESPOONSE_CODE_H__ -#define __RESPOONSE_CODE_H__ +#ifndef ROCKETMQ_PROTOCOL_RESPOONSECODE_H_ +#define ROCKETMQ_PROTOCOL_RESPOONSECODE_H_ namespace rocketmq { @@ -71,4 +71,4 @@ enum MQResponseCode { } // namespace rocketmq -#endif // __RESPOONSE_CODE_H__ +#endif // ROCKETMQ_PROTOCOL_RESPOONSECODE_H_ diff --git a/src/protocol/TopicRouteData.h b/src/protocol/TopicRouteData.h deleted file mode 100644 index 446dd7b42..000000000 --- a/src/protocol/TopicRouteData.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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 __TOPIC_ROUTE_DATA_H__ -#define __TOPIC_ROUTE_DATA_H__ - -#include - -#include -#include -#include - -#include "ByteArray.h" -#include "Logging.h" -#include "RemotingSerializable.h" -#include "UtilAll.h" - -namespace rocketmq { - -struct QueueData { - std::string brokerName; - int readQueueNums; - int writeQueueNums; - int perm; - - bool operator<(const QueueData& other) const { return brokerName < other.brokerName; } - - bool operator==(const QueueData& other) const { - return brokerName == other.brokerName && readQueueNums == other.readQueueNums && - writeQueueNums == other.writeQueueNums && perm == other.perm; - } - bool operator!=(const QueueData& other) const { return !operator==(other); } -}; - -struct BrokerData { - std::string brokerName; - std::map brokerAddrs; // master:0; slave:1,2,3,etc. - - bool operator<(const BrokerData& other) const { return brokerName < other.brokerName; } - - bool operator==(const BrokerData& other) const { - return brokerName == other.brokerName && brokerAddrs == other.brokerAddrs; - } - bool operator!=(const BrokerData& other) const { return !operator==(other); } -}; - -class TopicRouteData; -typedef std::shared_ptr TopicRouteDataPtr; - -class TopicRouteData { - public: - static TopicRouteData* Decode(const ByteArray& bodyData) { - Json::Value root = RemotingSerializable::fromJson(bodyData); - - std::unique_ptr trd(new TopicRouteData()); - trd->setOrderTopicConf(root["orderTopicConf"].asString()); - - auto& qds = root["queueDatas"]; - for (auto qd : qds) { - QueueData d; - d.brokerName = qd["brokerName"].asString(); - d.readQueueNums = qd["readQueueNums"].asInt(); - d.writeQueueNums = qd["writeQueueNums"].asInt(); - d.perm = qd["perm"].asInt(); - trd->getQueueDatas().push_back(d); - } - sort(trd->getQueueDatas().begin(), trd->getQueueDatas().end()); - - auto& bds = root["brokerDatas"]; - for (auto bd : bds) { - BrokerData d; - d.brokerName = bd["brokerName"].asString(); - LOG_DEBUG("brokerName:%s", d.brokerName.c_str()); - Json::Value bas = bd["brokerAddrs"]; - Json::Value::Members mbs = bas.getMemberNames(); - for (const auto& key : mbs) { - int id = std::stoi(key); - std::string addr = bas[key].asString(); - d.brokerAddrs[id] = addr; - LOG_DEBUG("brokerId:%d, brokerAddr:%s", id, addr.c_str()); - } - trd->getBrokerDatas().push_back(d); - } - sort(trd->getBrokerDatas().begin(), trd->getBrokerDatas().end()); - - return trd.release(); - } - - /** - * Selects a (preferably master) broker address from the registered list. - * If the master's address cannot be found, a slave broker address is selected in a random manner. - * - * @return Broker address. - */ - std::string selectBrokerAddr() { - auto bdSize = m_brokerDatas.size(); - if (bdSize > 0) { - auto bdIndex = std::rand() % bdSize; - const auto& bd = m_brokerDatas[bdIndex]; - auto it = bd.brokerAddrs.find(MASTER_ID); - if (it == bd.brokerAddrs.end()) { - auto baSize = bd.brokerAddrs.size(); - auto baIndex = std::rand() % baSize; - it = bd.brokerAddrs.begin(); - for (; baIndex > 0; baIndex--) { - it++; - } - } - return it->second; - } - return ""; - } - - std::vector& getQueueDatas() { return m_queueDatas; } - - std::vector& getBrokerDatas() { return m_brokerDatas; } - - const std::string& getOrderTopicConf() const { return m_orderTopicConf; } - - void setOrderTopicConf(const std::string& orderTopicConf) { m_orderTopicConf = orderTopicConf; } - - bool operator==(const TopicRouteData& other) const { - return m_brokerDatas == other.m_brokerDatas && m_orderTopicConf == other.m_orderTopicConf && - m_queueDatas == other.m_queueDatas; - } - bool operator!=(const TopicRouteData& other) const { return !operator==(other); } - - private: - std::string m_orderTopicConf; - std::vector m_queueDatas; - std::vector m_brokerDatas; -}; - -} // namespace rocketmq - -#endif // __TOPIC_ROUTE_DATA_H__ diff --git a/src/protocol/TopicRouteData.hpp b/src/protocol/TopicRouteData.hpp new file mode 100644 index 000000000..6d4b64c5b --- /dev/null +++ b/src/protocol/TopicRouteData.hpp @@ -0,0 +1,189 @@ +/* + * 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_PROTOCOL_TOPICROUTEDATA_HPP_ +#define ROCKETMQ_PROTOCOL_TOPICROUTEDATA_HPP_ + +#include + +#include +#include +#include + +#include "ByteArray.h" +#include "Logging.h" +#include "RemotingSerializable.h" +#include "UtilAll.h" + +namespace rocketmq { + +class QueueData { + public: + QueueData() : read_queue_nums_(16), write_queue_nums_(16), perm_(6) {} + QueueData(const std::string& broker_name, int read_queue_nums, int write_queue_nums, int perm) + : broker_name_(broker_name), + read_queue_nums_(read_queue_nums), + write_queue_nums_(write_queue_nums), + perm_(perm) {} + QueueData(std::string&& broker_name, int read_queue_nums, int write_queue_nums, int perm) + : broker_name_(std::move(broker_name)), + read_queue_nums_(read_queue_nums), + write_queue_nums_(write_queue_nums), + perm_(perm) {} + + bool operator<(const QueueData& other) const { return broker_name_ < other.broker_name_; } + + bool operator==(const QueueData& other) const { + return broker_name_ == other.broker_name_ && read_queue_nums_ == other.read_queue_nums_ && + write_queue_nums_ == other.write_queue_nums_ && perm_ == other.perm_; + } + bool operator!=(const QueueData& other) const { return !operator==(other); } + + public: + inline const std::string& broker_name() const { return broker_name_; } + inline void broker_name(const std::string& broker_name) { broker_name_ = broker_name; } + + inline int read_queue_nums() const { return read_queue_nums_; } + inline void set_read_queue_nums(int read_queue_nums) { read_queue_nums_ = read_queue_nums; } + + inline int write_queue_nums() const { return write_queue_nums_; } + inline void set_write_queue_nums(int write_queue_nums) { write_queue_nums_ = write_queue_nums; } + + inline int perm() const { return perm_; } + inline void set_perm(int perm) { perm_ = perm; } + + private: + std::string broker_name_; + int read_queue_nums_; + int write_queue_nums_; + int perm_; +}; + +class BrokerData { + public: + BrokerData(); + BrokerData(const std::string& broker_name) : broker_name_(broker_name) {} + BrokerData(std::string&& broker_name) : broker_name_(std::move(broker_name)) {} + BrokerData(const std::string& broker_name, const std::map& broker_addrs) + : broker_name_(broker_name), broker_addrs_(broker_addrs) {} + BrokerData(std::string&& broker_name, std::map&& broker_addrs) + : broker_name_(std::move(broker_name)), broker_addrs_(std::move(broker_addrs)) {} + + bool operator<(const BrokerData& other) const { return broker_name_ < other.broker_name_; } + + bool operator==(const BrokerData& other) const { + return broker_name_ == other.broker_name_ && broker_addrs_ == other.broker_addrs_; + } + bool operator!=(const BrokerData& other) const { return !operator==(other); } + + public: + inline const std::string& broker_name() const { return broker_name_; } + inline void broker_name(const std::string& broker_name) { broker_name_ = broker_name; } + + inline const std::map& broker_addrs() const { return broker_addrs_; } + inline std::map& broker_addrs() { return broker_addrs_; } + + private: + std::string broker_name_; + std::map broker_addrs_; // master:0; slave:1,2,3,etc. +}; + +class TopicRouteData; +typedef std::shared_ptr TopicRouteDataPtr; + +class TopicRouteData { + public: + static TopicRouteData* Decode(const ByteArray& bodyData) { + Json::Value root = RemotingSerializable::fromJson(bodyData); + + std::unique_ptr trd(new TopicRouteData()); + trd->set_order_topic_conf(root["orderTopicConf"].asString()); + + auto& qds = root["queueDatas"]; + for (auto qd : qds) { + trd->queue_datas().emplace_back(qd["brokerName"].asString(), qd["readQueueNums"].asInt(), + qd["writeQueueNums"].asInt(), qd["perm"].asInt()); + } + sort(trd->queue_datas().begin(), trd->queue_datas().end()); + + auto& bds = root["brokerDatas"]; + for (auto bd : bds) { + std::string broker_name = bd["brokerName"].asString(); + LOG_DEBUG_NEW("brokerName:{}", broker_name); + std::map broker_addrs; + Json::Value bas = bd["brokerAddrs"]; + Json::Value::Members mbs = bas.getMemberNames(); + for (const auto& key : mbs) { + int id = std::stoi(key); + std::string addr = bas[key].asString(); + broker_addrs.emplace(id, std::move(addr)); + LOG_DEBUG_NEW("brokerId:{}, brokerAddr:{}", id, addr); + } + trd->broker_datas().emplace_back(std::move(broker_name), std::move(broker_addrs)); + } + sort(trd->broker_datas().begin(), trd->broker_datas().end()); + + return trd.release(); + } + + /** + * Selects a (preferably master) broker address from the registered list. + * If the master's address cannot be found, a slave broker address is selected in a random manner. + * + * @return Broker address. + */ + std::string selectBrokerAddr() { + auto bdSize = broker_datas_.size(); + if (bdSize > 0) { + auto bdIndex = std::rand() % bdSize; + const auto& bd = broker_datas_[bdIndex]; + const auto& broker_addrs = bd.broker_addrs(); + auto it = broker_addrs.find(MASTER_ID); + if (it == broker_addrs.end()) { + auto baSize = broker_addrs.size(); + auto baIndex = std::rand() % baSize; + for (it = broker_addrs.begin(); baIndex > 0; baIndex--) { + it++; + } + } + return it->second; + } + return null; + } + + bool operator==(const TopicRouteData& other) const { + return broker_datas_ == other.broker_datas_ && order_topic_conf_ == other.order_topic_conf_ && + queue_datas_ == other.queue_datas_; + } + bool operator!=(const TopicRouteData& other) const { return !operator==(other); } + + public: + inline const std::string& order_topic_conf() const { return order_topic_conf_; } + inline void set_order_topic_conf(const std::string& orderTopicConf) { order_topic_conf_ = orderTopicConf; } + + inline std::vector& queue_datas() { return queue_datas_; } + + inline std::vector& broker_datas() { return broker_datas_; } + + private: + std::string order_topic_conf_; + std::vector queue_datas_; + std::vector broker_datas_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_PROTOCOL_TOPICROUTEDATA_HPP_ diff --git a/src/protocol/header/CommandHeader.cpp b/src/protocol/header/CommandHeader.cpp index 6a6ce8026..4a7e7cac4 100644 --- a/src/protocol/header/CommandHeader.cpp +++ b/src/protocol/header/CommandHeader.cpp @@ -19,7 +19,7 @@ #include #include "Logging.h" -#include "MQClientException.h" +#include "MQException.h" #include "RemotingSerializable.h" #include "UtilAll.h" diff --git a/src/protocol/header/CommandHeader.h b/src/protocol/header/CommandHeader.h index 39998d6a2..31c10eb8f 100644 --- a/src/protocol/header/CommandHeader.h +++ b/src/protocol/header/CommandHeader.h @@ -14,10 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __COMMAND_HEADER_H__ -#define __COMMAND_HEADER_H__ +#ifndef ROCKETMQ_PROTOCOL_COMMANDHEADER_H_ +#define ROCKETMQ_PROTOCOL_COMMANDHEADER_H_ -#include +#include // std::vector #include "ByteArray.h" #include "CommandCustomHeader.h" @@ -463,4 +463,4 @@ class NotifyConsumerIdsChangedRequestHeader : public CommandCustomHeader { } // namespace rocketmq -#endif // __COMMAND_HEADER_H__ +#endif // ROCKETMQ_PROTOCOL_COMMANDHEADER_H_ diff --git a/src/transport/EventLoop.cpp b/src/transport/EventLoop.cpp index 62e535c41..85ea1134b 100644 --- a/src/transport/EventLoop.cpp +++ b/src/transport/EventLoop.cpp @@ -29,7 +29,7 @@ EventLoop* EventLoop::GetDefaultEventLoop() { } EventLoop::EventLoop(const struct event_config* config, bool run_immediately) - : m_eventBase(nullptr), m_loopThread("EventLoop"), _is_running(false) { + : event_base_(nullptr), loop_thread_("EventLoop"), is_running_(false) { // tell libevent support multi-threads #ifdef WIN32 evthread_use_windows_threads(); @@ -38,20 +38,20 @@ EventLoop::EventLoop(const struct event_config* config, bool run_immediately) #endif if (config == nullptr) { - m_eventBase = event_base_new(); + event_base_ = event_base_new(); } else { - m_eventBase = event_base_new_with_config(config); + event_base_ = event_base_new_with_config(config); } - if (m_eventBase == nullptr) { + if (event_base_ == nullptr) { // FIXME: failure... LOG_ERROR_NEW("[CRITICAL] Failed to create event base!"); exit(-1); } - evthread_make_base_notifiable(m_eventBase); + evthread_make_base_notifiable(event_base_); - m_loopThread.set_target(&EventLoop::runLoop, this); + loop_thread_.set_target(&EventLoop::runLoop, this); if (run_immediately) { start(); @@ -61,29 +61,29 @@ EventLoop::EventLoop(const struct event_config* config, bool run_immediately) EventLoop::~EventLoop() { stop(); - if (m_eventBase != nullptr) { - event_base_free(m_eventBase); - m_eventBase = nullptr; + if (event_base_ != nullptr) { + event_base_free(event_base_); + event_base_ = nullptr; } } void EventLoop::start() { - if (!_is_running) { - _is_running = true; - m_loopThread.start(); + if (!is_running_) { + is_running_ = true; + loop_thread_.start(); } } void EventLoop::stop() { - if (_is_running) { - _is_running = false; - m_loopThread.join(); + if (is_running_) { + is_running_ = false; + loop_thread_.join(); } } void EventLoop::runLoop() { - while (_is_running) { - int ret = event_base_dispatch(m_eventBase); + while (is_running_) { + int ret = event_base_dispatch(event_base_); if (ret == 1) { // no event std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -94,7 +94,7 @@ void EventLoop::runLoop() { #define OPT_UNLOCK_CALLBACKS (BEV_OPT_DEFER_CALLBACKS | BEV_OPT_UNLOCK_CALLBACKS) BufferEvent* EventLoop::createBufferEvent(socket_t fd, int options) { - struct bufferevent* event = bufferevent_socket_new(m_eventBase, fd, options); + struct bufferevent* event = bufferevent_socket_new(event_base_, fd, options); if (event == nullptr) { auto ev_errno = EVUTIL_SOCKET_ERROR(); LOG_ERROR_NEW("create bufferevent failed: {}", evutil_socket_error_to_string(ev_errno)); @@ -107,56 +107,56 @@ BufferEvent* EventLoop::createBufferEvent(socket_t fd, int options) { } BufferEvent::BufferEvent(struct bufferevent* event, bool unlockCallbacks, EventLoop* loop) - : m_eventLoop(loop), - m_bufferEvent(event), - m_unlockCallbacks(unlockCallbacks), - m_readCallback(nullptr), - m_writeCallback(nullptr), - m_eventCallback(nullptr) { - if (m_bufferEvent != nullptr) { - bufferevent_incref(m_bufferEvent); + : event_loop_(loop), + buffer_event_(event), + unlock_callbacks_(unlockCallbacks), + read_callback_(nullptr), + write_callback_(nullptr), + event_callback_(nullptr) { + if (buffer_event_ != nullptr) { + bufferevent_incref(buffer_event_); } } BufferEvent::~BufferEvent() { - if (m_bufferEvent != nullptr) { - bufferevent_decref(m_bufferEvent); + if (buffer_event_ != nullptr) { + bufferevent_decref(buffer_event_); } } void BufferEvent::setCallback(DataCallback readCallback, DataCallback writeCallback, EventCallback eventCallback) { - if (m_bufferEvent == nullptr) { + if (buffer_event_ == nullptr) { return; } // use lock in bufferevent - bufferevent_lock(m_bufferEvent); + bufferevent_lock(buffer_event_); // wrap callback - m_readCallback = readCallback; - m_writeCallback = writeCallback; - m_eventCallback = eventCallback; + read_callback_ = readCallback; + write_callback_ = writeCallback; + event_callback_ = eventCallback; bufferevent_data_cb readcb = readCallback != nullptr ? read_callback : nullptr; bufferevent_data_cb writecb = writeCallback != nullptr ? write_callback : nullptr; bufferevent_event_cb eventcb = eventCallback != nullptr ? event_callback : nullptr; - bufferevent_setcb(m_bufferEvent, readcb, writecb, eventcb, this); + bufferevent_setcb(buffer_event_, readcb, writecb, eventcb, this); - bufferevent_unlock(m_bufferEvent); + bufferevent_unlock(buffer_event_); } void BufferEvent::read_callback(struct bufferevent* bev, void* ctx) { auto event = static_cast(ctx); - if (event->m_unlockCallbacks) { - bufferevent_lock(event->m_bufferEvent); + if (event->unlock_callbacks_) { + bufferevent_lock(event->buffer_event_); } - auto callback = event->m_readCallback; + auto callback = event->read_callback_; - if (event->m_unlockCallbacks) { - bufferevent_unlock(event->m_bufferEvent); + if (event->unlock_callbacks_) { + bufferevent_unlock(event->buffer_event_); } if (callback != nullptr) { @@ -167,14 +167,14 @@ void BufferEvent::read_callback(struct bufferevent* bev, void* ctx) { void BufferEvent::write_callback(struct bufferevent* bev, void* ctx) { auto event = static_cast(ctx); - if (event->m_unlockCallbacks) { - bufferevent_lock(event->m_bufferEvent); + if (event->unlock_callbacks_) { + bufferevent_lock(event->buffer_event_); } - auto callback = event->m_writeCallback; + auto callback = event->write_callback_; - if (event->m_unlockCallbacks) { - bufferevent_unlock(event->m_bufferEvent); + if (event->unlock_callbacks_) { + bufferevent_unlock(event->buffer_event_); } if (callback != nullptr) { @@ -185,14 +185,14 @@ void BufferEvent::write_callback(struct bufferevent* bev, void* ctx) { void BufferEvent::event_callback(struct bufferevent* bev, short what, void* ctx) { auto event = static_cast(ctx); - if (event->m_unlockCallbacks) { - bufferevent_lock(event->m_bufferEvent); + if (event->unlock_callbacks_) { + bufferevent_lock(event->buffer_event_); } - auto callback = event->m_eventCallback; + auto callback = event->event_callback_; - if (event->m_unlockCallbacks) { - bufferevent_unlock(event->m_bufferEvent); + if (event->unlock_callbacks_) { + bufferevent_unlock(event->buffer_event_); } if (callback != nullptr) { @@ -201,15 +201,15 @@ void BufferEvent::event_callback(struct bufferevent* bev, short what, void* ctx) } int BufferEvent::connect(const std::string& addr) { - if (m_bufferEvent == nullptr) { + if (buffer_event_ == nullptr) { LOG_WARN_NEW("have not bufferevent object to connect {}", addr); return -1; } try { auto* sa = string2SocketAddress(addr); // resolve domain - m_peerAddrPort = socketAddress2String(sa); - return bufferevent_socket_connect(m_bufferEvent, sa, sockaddr_size(sa)); + peer_addr_port_ = socketAddress2String(sa); + return bufferevent_socket_connect(buffer_event_, sa, sockaddr_size(sa)); } catch (const std::exception& e) { LOG_ERROR_NEW("can not connect to {}, {}", addr, e.what()); return -1; @@ -217,8 +217,8 @@ int BufferEvent::connect(const std::string& addr) { } void BufferEvent::close() { - if (m_bufferEvent != nullptr) { - bufferevent_free(m_bufferEvent); + if (buffer_event_ != nullptr) { + bufferevent_free(buffer_event_); } } diff --git a/src/transport/EventLoop.h b/src/transport/EventLoop.h index 69ca0a010..d07d6b7cc 100644 --- a/src/transport/EventLoop.h +++ b/src/transport/EventLoop.h @@ -14,15 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __EVENTLOOP_H__ -#define __EVENTLOOP_H__ +#ifndef ROCKETMQ_TRANSPORT_EVENTLOOP_H_ +#define ROCKETMQ_TRANSPORT_EVENTLOOP_H_ #include #include #include -#include -#include +#include // std::function #include "concurrent/thread.hpp" #include "noncopyable.h" @@ -44,7 +43,7 @@ class EventLoop : public noncopyable { void start(); void stop(); - bool isRunning() { return _is_running; } + bool isRunning() { return is_running_; } BufferEvent* createBufferEvent(socket_t fd, int options); @@ -52,10 +51,10 @@ class EventLoop : public noncopyable { void runLoop(); private: - struct event_base* m_eventBase; - thread m_loopThread; + struct event_base* event_base_; + thread loop_thread_; - bool _is_running; // aotmic is unnecessary + bool is_running_; // aotmic is unnecessary }; class TcpTransport; @@ -74,27 +73,25 @@ class BufferEvent : public noncopyable { void setCallback(DataCallback readCallback, DataCallback writeCallback, EventCallback eventCallback); - void setWatermark(short events, size_t lowmark, size_t highmark) { - bufferevent_setwatermark(m_bufferEvent, events, lowmark, highmark); + inline void setWatermark(short events, size_t lowmark, size_t highmark) { + bufferevent_setwatermark(buffer_event_, events, lowmark, highmark); } - int enable(short event) { return bufferevent_enable(m_bufferEvent, event); } - int disable(short event) { return bufferevent_disable(m_bufferEvent, event); } + inline int enable(short event) { return bufferevent_enable(buffer_event_, event); } + inline int disable(short event) { return bufferevent_disable(buffer_event_, event); } int connect(const std::string& addr); void close(); - int write(const void* data, size_t size) { return bufferevent_write(m_bufferEvent, data, size); } + inline int write(const void* data, size_t size) { return bufferevent_write(buffer_event_, data, size); } - size_t read(void* data, size_t size) { return bufferevent_read(m_bufferEvent, data, size); } + inline size_t read(void* data, size_t size) { return bufferevent_read(buffer_event_, data, size); } - struct evbuffer* getInput() { - return bufferevent_get_input(m_bufferEvent); - } + inline struct evbuffer* getInput() { return bufferevent_get_input(buffer_event_); } - socket_t getfd() const { return bufferevent_getfd(m_bufferEvent); } + inline socket_t getfd() const { return bufferevent_getfd(buffer_event_); } - const std::string& getPeerAddrPort() const { return m_peerAddrPort; } + inline const std::string& getPeerAddrPort() const { return peer_addr_port_; } private: static void read_callback(struct bufferevent* bev, void* ctx); @@ -102,18 +99,18 @@ class BufferEvent : public noncopyable { static void event_callback(struct bufferevent* bev, short what, void* ctx); private: - EventLoop* m_eventLoop; - struct bufferevent* m_bufferEvent; - const bool m_unlockCallbacks; + EventLoop* event_loop_; + struct bufferevent* buffer_event_; + const bool unlock_callbacks_; - DataCallback m_readCallback; - DataCallback m_writeCallback; - EventCallback m_eventCallback; + DataCallback read_callback_; + DataCallback write_callback_; + EventCallback event_callback_; // cached properties - std::string m_peerAddrPort; + std::string peer_addr_port_; }; } // namespace rocketmq -#endif // __EVENTLOOP_H__ +#endif // ROCKETMQ_TRANSPORT_EVENTLOOP_H_ diff --git a/src/transport/RequestProcessor.h b/src/transport/RequestProcessor.h index 167bd78be..2e6239178 100644 --- a/src/transport/RequestProcessor.h +++ b/src/transport/RequestProcessor.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __REQUEST_PROCESSOR_H__ -#define __REQUEST_PROCESSOR_H__ +#ifndef ROCKETMQ_TRANSPORT_REQUESTPROCESSOR_H_ +#define ROCKETMQ_TRANSPORT_REQUESTPROCESSOR_H_ #include "RemotingCommand.h" #include "TcpTransport.h" @@ -31,4 +31,4 @@ class RequestProcessor { } // namespace rocketmq -#endif // __REQUEST_PROCESSOR_H__ +#endif // ROCKETMQ_TRANSPORT_REQUESTPROCESSOR_H_ diff --git a/src/transport/ResponseFuture.cpp b/src/transport/ResponseFuture.cpp index c3ce78ad4..938413509 100755 --- a/src/transport/ResponseFuture.cpp +++ b/src/transport/ResponseFuture.cpp @@ -21,100 +21,76 @@ namespace rocketmq { ResponseFuture::ResponseFuture(int requestCode, int opaque, int64_t timeoutMillis, InvokeCallback* invokeCallback) - : m_requestCode(requestCode), - m_opaque(opaque), - m_timeoutMillis(timeoutMillis), - m_invokeCallback(invokeCallback), - m_responseCommand(nullptr), - m_beginTimestamp(UtilAll::currentTimeMillis()), - m_sendRequestOK(false), - m_countDownLatch(nullptr) { + : request_code_(requestCode), + opaque_(opaque), + timeout_millis_(timeoutMillis), + invoke_callback_(invokeCallback), + begin_timestamp_(UtilAll::currentTimeMillis()), + send_request_ok_(false), + response_command_(nullptr), + count_down_latch_(nullptr) { if (nullptr == invokeCallback) { - m_countDownLatch.reset(new latch(1)); + count_down_latch_.reset(new latch(1)); } } -ResponseFuture::~ResponseFuture() {} +ResponseFuture::~ResponseFuture() = default; void ResponseFuture::releaseThreadCondition() { - if (m_countDownLatch != nullptr) { - m_countDownLatch->count_down(); + if (count_down_latch_ != nullptr) { + count_down_latch_->count_down(); } } bool ResponseFuture::hasInvokeCallback() { - // if m_invokeCallback is set, this is an async future. - return m_invokeCallback != nullptr; + // if invoke_callback_ is set, this is an async future. + return invoke_callback_ != nullptr; } InvokeCallback* ResponseFuture::releaseInvokeCallback() { - return m_invokeCallback.release(); + return invoke_callback_.release(); } void ResponseFuture::executeInvokeCallback() noexcept { - if (m_invokeCallback != nullptr) { - m_invokeCallback->operationComplete(this); + if (invoke_callback_ != nullptr) { + invoke_callback_->operationComplete(this); } } std::unique_ptr ResponseFuture::waitResponse(int timeoutMillis) { - if (m_countDownLatch != nullptr) { + if (count_down_latch_ != nullptr) { if (timeoutMillis < 0) { timeoutMillis = 0; } - m_countDownLatch->wait(timeoutMillis, time_unit::milliseconds); + count_down_latch_->wait(timeoutMillis, time_unit::milliseconds); } - return std::move(m_responseCommand); + return std::move(response_command_); } void ResponseFuture::putResponse(std::unique_ptr responseCommand) { - m_responseCommand = std::move(responseCommand); - if (m_countDownLatch != nullptr) { - m_countDownLatch->count_down(); + response_command_ = std::move(responseCommand); + if (count_down_latch_ != nullptr) { + count_down_latch_->count_down(); } } std::unique_ptr ResponseFuture::getResponseCommand() { - return std::move(m_responseCommand); + return std::move(response_command_); } void ResponseFuture::setResponseCommand(std::unique_ptr responseCommand) { - m_responseCommand = std::move(responseCommand); -} - -int64_t ResponseFuture::getBeginTimestamp() { - return m_beginTimestamp; -} - -int64_t ResponseFuture::getTimeoutMillis() { - return m_timeoutMillis; + response_command_ = std::move(responseCommand); } bool ResponseFuture::isTimeout() const { - auto diff = UtilAll::currentTimeMillis() - m_beginTimestamp; - return diff > m_timeoutMillis; + auto diff = UtilAll::currentTimeMillis() - begin_timestamp_; + return diff > timeout_millis_; } int64_t ResponseFuture::leftTime() const { - auto diff = UtilAll::currentTimeMillis() - m_beginTimestamp; - auto left = m_timeoutMillis - diff; + auto diff = UtilAll::currentTimeMillis() - begin_timestamp_; + auto left = timeout_millis_ - diff; return left < 0 ? 0 : left; } -bool ResponseFuture::isSendRequestOK() const { - return m_sendRequestOK; -} - -void ResponseFuture::setSendRequestOK(bool sendRequestOK) { - m_sendRequestOK = sendRequestOK; -} - -int ResponseFuture::getOpaque() const { - return m_opaque; -} - -int ResponseFuture::getRequestCode() const { - return m_requestCode; -} - } // namespace rocketmq diff --git a/src/transport/ResponseFuture.h b/src/transport/ResponseFuture.h index 8e8674dec..56ffc67ed 100755 --- a/src/transport/ResponseFuture.h +++ b/src/transport/ResponseFuture.h @@ -14,12 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __RESPONSE_FUTURE_H__ -#define __RESPONSE_FUTURE_H__ +#ifndef ROCKETMQ_TRANSPORT_RESPONSEFUTURE_H_ +#define ROCKETMQ_TRANSPORT_RESPONSEFUTURE_H_ +#include "concurrent/latch.hpp" #include "InvokeCallback.h" #include "RemotingCommand.h" -#include "concurrent/latch.hpp" namespace rocketmq { @@ -46,31 +46,33 @@ class ResponseFuture { std::unique_ptr getResponseCommand(); void setResponseCommand(std::unique_ptr responseCommand); - int64_t getBeginTimestamp(); - int64_t getTimeoutMillis(); bool isTimeout() const; int64_t leftTime() const; - bool isSendRequestOK() const; - void setSendRequestOK(bool sendRequestOK = true); + public: + inline int request_code() const { return request_code_; } + inline int opaque() const { return opaque_; } + inline int64_t timeout_millis() const { return timeout_millis_; } + + inline int64_t begin_timestamp() const { return begin_timestamp_; } - int getRequestCode() const; - int getOpaque() const; + inline bool send_request_ok() const { return send_request_ok_; } + inline void set_send_request_ok(bool sendRequestOK = true) { send_request_ok_ = sendRequestOK; }; private: - int m_requestCode; - int m_opaque; - int64_t m_timeoutMillis; - std::unique_ptr m_invokeCallback; + int request_code_; + int opaque_; + int64_t timeout_millis_; + std::unique_ptr invoke_callback_; - std::unique_ptr m_responseCommand; + int64_t begin_timestamp_; + bool send_request_ok_; - int64_t m_beginTimestamp; - bool m_sendRequestOK; + std::unique_ptr response_command_; - std::unique_ptr m_countDownLatch; // use for synchronization rpc + std::unique_ptr count_down_latch_; // use for synchronization rpc }; } // namespace rocketmq -#endif // __RESPONSE_FUTURE_H__ +#endif // ROCKETMQ_TRANSPORT_RESPONSEFUTURE_H_ diff --git a/src/transport/SocketUtil.cpp b/src/transport/SocketUtil.cpp index 59dff7bee..04700882e 100644 --- a/src/transport/SocketUtil.cpp +++ b/src/transport/SocketUtil.cpp @@ -30,7 +30,7 @@ #endif #include "ByteOrder.h" -#include "MQClientException.h" +#include "MQException.h" #include "UtilAll.h" namespace rocketmq { diff --git a/src/transport/SocketUtil.h b/src/transport/SocketUtil.h index bd2f31cd8..be18a38d7 100644 --- a/src/transport/SocketUtil.h +++ b/src/transport/SocketUtil.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __SOCKET_UTIL_H__ -#define __SOCKET_UTIL_H__ +#ifndef ROCKETMQ_TRANSPORT_SOCKETUTIL_H_ +#define ROCKETMQ_TRANSPORT_SOCKETUTIL_H_ #include @@ -51,4 +51,4 @@ uint64_t n2hll(uint64_t v); } // namespace rocketmq -#endif // __SOCKET_UTIL_H__ +#endif // ROCKETMQ_TRANSPORT_SOCKETUTIL_H_ diff --git a/src/transport/TcpRemotingClient.cpp b/src/transport/TcpRemotingClient.cpp index cf035f280..7c3b5c241 100644 --- a/src/transport/TcpRemotingClient.cpp +++ b/src/transport/TcpRemotingClient.cpp @@ -36,33 +36,33 @@ class ResponseFutureInfo : public TcpTransportInfo { } void putResponseFuture(int opaque, ResponseFuturePtr future) { - std::lock_guard lock(m_futureTableMutex); - const auto it = m_futureTable.find(opaque); - if (it != m_futureTable.end()) { + std::lock_guard lock(future_table_mutex_); + const auto it = future_table_.find(opaque); + if (it != future_table_.end()) { LOG_WARN_NEW("[BUG] response futurn with opaque:{} is exist.", opaque); } - m_futureTable[opaque] = future; + future_table_[opaque] = future; } ResponseFuturePtr popResponseFuture(int opaque) { - std::lock_guard lock(m_futureTableMutex); - const auto& it = m_futureTable.find(opaque); - if (it != m_futureTable.end()) { + std::lock_guard lock(future_table_mutex_); + const auto& it = future_table_.find(opaque); + if (it != future_table_.end()) { auto future = it->second; - m_futureTable.erase(it); + future_table_.erase(it); return future; } return nullptr; } void scanResponseTable(uint64_t now, std::vector& futureList) { - std::lock_guard lock(m_futureTableMutex); - for (auto it = m_futureTable.begin(); it != m_futureTable.end();) { + std::lock_guard lock(future_table_mutex_); + for (auto it = future_table_.begin(); it != future_table_.end();) { auto& future = it->second; // NOTE: future is a reference - if (future->getBeginTimestamp() + future->getTimeoutMillis() + 1000 <= now) { - LOG_WARN_NEW("remove timeout request, code:{}, opaque:{}", future->getRequestCode(), future->getOpaque()); + if (future->begin_timestamp() + future->timeout_millis() + 1000 <= now) { + LOG_WARN_NEW("remove timeout request, code:{}, opaque:{}", future->request_code(), future->opaque()); futureList.push_back(future); - it = m_futureTable.erase(it); + it = future_table_.erase(it); } else { ++it; } @@ -70,8 +70,8 @@ class ResponseFutureInfo : public TcpTransportInfo { } void activeAllResponses() { - std::lock_guard lock(m_futureTableMutex); - for (const auto& it : m_futureTable) { + std::lock_guard lock(future_table_mutex_); + for (const auto& it : future_table_) { auto& future = it.second; if (future->hasInvokeCallback()) { future->executeInvokeCallback(); // callback async request @@ -79,71 +79,71 @@ class ResponseFutureInfo : public TcpTransportInfo { future->putResponse(nullptr); // wake up sync request } } - m_futureTable.clear(); + future_table_.clear(); } private: - FutureMap m_futureTable; // opaque -> future - std::mutex m_futureTableMutex; + FutureMap future_table_; // opaque -> future + std::mutex future_table_mutex_; }; TcpRemotingClient::TcpRemotingClient(int workerThreadNum, uint64_t tcpConnectTimeout, uint64_t tcpTransportTryLockTimeout) - : m_tcpConnectTimeout(tcpConnectTimeout), - m_tcpTransportTryLockTimeout(tcpTransportTryLockTimeout), - m_namesrvIndex(0), - m_dispatchExecutor("MessageDispatchExecutor", 1, false), - m_handleExecutor("MessageHandleExecutor", workerThreadNum, false), - m_timeoutExecutor("TimeoutScanExecutor", false) {} + : tcp_connect_timeout_(tcpConnectTimeout), + tcp_transport_try_lock_timeout_(tcpTransportTryLockTimeout), + namesrv_index_(0), + dispatch_executor_("MessageDispatchExecutor", 1, false), + handle_executor_("MessageHandleExecutor", workerThreadNum, false), + timeout_executor_("TimeoutScanExecutor", false) {} TcpRemotingClient::~TcpRemotingClient() { LOG_DEBUG_NEW("TcpRemotingClient is destructed."); } void TcpRemotingClient::start() { - m_dispatchExecutor.startup(); - m_handleExecutor.startup(); + dispatch_executor_.startup(); + handle_executor_.startup(); - LOG_INFO_NEW("tcpConnectTimeout:{}, tcpTransportTryLockTimeout:{}, pullThreadNum:{}", m_tcpConnectTimeout, - m_tcpTransportTryLockTimeout, m_handleExecutor.num_threads()); + LOG_INFO_NEW("tcpConnectTimeout:{}, tcpTransportTryLockTimeout:{}, pullThreadNums:{}", tcp_connect_timeout_, + tcp_transport_try_lock_timeout_, handle_executor_.thread_nums()); - m_timeoutExecutor.startup(); + timeout_executor_.startup(); // scanResponseTable - m_timeoutExecutor.schedule(std::bind(&TcpRemotingClient::scanResponseTablePeriodically, this), 1000 * 3, + timeout_executor_.schedule(std::bind(&TcpRemotingClient::scanResponseTablePeriodically, this), 1000 * 3, time_unit::milliseconds); } void TcpRemotingClient::shutdown() { LOG_INFO_NEW("TcpRemotingClient::shutdown Begin"); - m_timeoutExecutor.shutdown(); + timeout_executor_.shutdown(); { - std::lock_guard lock(m_transportTableMutex); - for (const auto& trans : m_transportTable) { + std::lock_guard lock(transport_table_mutex_); + for (const auto& trans : transport_table_) { trans.second->disconnect(trans.first); } - m_transportTable.clear(); + transport_table_.clear(); } - m_handleExecutor.shutdown(); + handle_executor_.shutdown(); - m_dispatchExecutor.shutdown(); + dispatch_executor_.shutdown(); - LOG_INFO_NEW("TcpRemotingClient::shutdown End, m_transportTable:{}", m_transportTable.size()); + LOG_INFO_NEW("TcpRemotingClient::shutdown End, transport_table_:{}", transport_table_.size()); } void TcpRemotingClient::registerRPCHook(RPCHookPtr rpcHook) { if (rpcHook != nullptr) { - for (auto& hook : m_rpcHooks) { + for (auto& hook : rpc_hooks_) { if (hook == rpcHook) { return; } } - m_rpcHooks.push_back(rpcHook); + rpc_hooks_.push_back(rpcHook); } } @@ -154,14 +154,14 @@ void TcpRemotingClient::updateNameServerAddressList(const std::string& addrs) { return; } - if (!UtilAll::try_lock_for(m_namesrvLock, 1000 * 10)) { + if (!UtilAll::try_lock_for(namesrv_lock_, 1000 * 10)) { LOG_ERROR_NEW("updateNameServerAddressList get timed_mutex timeout"); return; } - std::lock_guard lock(m_namesrvLock, std::adopt_lock); + std::lock_guard lock(namesrv_lock_, std::adopt_lock); // clear first - m_namesrvAddrList.clear(); + namesrv_addr_list_.clear(); std::vector out; UtilAll::Split(out, addrs, ";"); @@ -172,7 +172,7 @@ void TcpRemotingClient::updateNameServerAddressList(const std::string& addrs) { short portNumber; if (UtilAll::SplitURL(addr, hostName, portNumber)) { LOG_INFO_NEW("update Namesrv:{}", addr); - m_namesrvAddrList.push_back(addr); + namesrv_addr_list_.push_back(addr); } else { LOG_INFO_NEW("This may be invalid namer server: [{}]", addr); } @@ -187,15 +187,15 @@ void TcpRemotingClient::scanResponseTablePeriodically() { } // next round - m_timeoutExecutor.schedule(std::bind(&TcpRemotingClient::scanResponseTablePeriodically, this), 1000, + timeout_executor_.schedule(std::bind(&TcpRemotingClient::scanResponseTablePeriodically, this), 1000, time_unit::milliseconds); } void TcpRemotingClient::scanResponseTable() { std::vector channelList; { - std::lock_guard lock(m_transportTableMutex); - for (const auto& trans : m_transportTable) { + std::lock_guard lock(transport_table_mutex_); + for (const auto& trans : transport_table_) { channelList.push_back(trans.second); } } @@ -208,7 +208,7 @@ void TcpRemotingClient::scanResponseTable() { } for (auto rf : rfList) { if (rf->hasInvokeCallback()) { - m_handleExecutor.submit(std::bind(&ResponseFuture::executeInvokeCallback, rf)); + handle_executor_.submit(std::bind(&ResponseFuture::executeInvokeCallback, rf)); } } } @@ -257,9 +257,9 @@ std::unique_ptr TcpRemotingClient::invokeSyncImpl(TcpTransportP putResponseFuture(channel, opaque, responseFuture); if (SendCommand(channel, request)) { - responseFuture->setSendRequestOK(true); + responseFuture->set_send_request_ok(true); } else { - responseFuture->setSendRequestOK(false); + responseFuture->set_send_request_ok(false); popResponseFuture(channel, opaque); // clean future // wake up potential waitResponse() is unnecessary, so not call putResponse() LOG_WARN_NEW("send a request command to channel <{}> failed.", channel->getPeerAddrAndPort()); @@ -314,14 +314,14 @@ void TcpRemotingClient::invokeAsyncImpl(TcpTransportPtr channel, try { if (SendCommand(channel, request)) { - responseFuture->setSendRequestOK(true); + responseFuture->set_send_request_ok(true); } else { // requestFail responseFuture = popResponseFuture(channel, opaque); if (responseFuture != nullptr) { - responseFuture->setSendRequestOK(false); + responseFuture->set_send_request_ok(false); if (responseFuture->hasInvokeCallback()) { - m_handleExecutor.submit(std::bind(&ResponseFuture::executeInvokeCallback, responseFuture)); + handle_executor_.submit(std::bind(&ResponseFuture::executeInvokeCallback, responseFuture)); } } @@ -364,8 +364,8 @@ void TcpRemotingClient::invokeOnewayImpl(TcpTransportPtr channel, RemotingComman } void TcpRemotingClient::doBeforeRpcHooks(const std::string& addr, RemotingCommand& request, bool toSent) { - if (m_rpcHooks.size() > 0) { - for (auto& rpcHook : m_rpcHooks) { + if (rpc_hooks_.size() > 0) { + for (auto& rpcHook : rpc_hooks_) { rpcHook->doBeforeRequest(addr, request, toSent); } } @@ -375,8 +375,8 @@ void TcpRemotingClient::doAfterRpcHooks(const std::string& addr, RemotingCommand& request, RemotingCommand* response, bool toSent) { - if (m_rpcHooks.size() > 0) { - for (auto& rpcHook : m_rpcHooks) { + if (rpc_hooks_.size() > 0) { + for (auto& rpcHook : rpc_hooks_) { rpcHook->doAfterResponse(addr, request, response, toSent); } } @@ -394,17 +394,17 @@ TcpTransportPtr TcpRemotingClient::CreateTransport(const std::string& addr) { TcpTransportPtr channel; { - // try get m_transportTableMutex until m_tcpTransportTryLockTimeout to avoid blocking long time, - // if could not get m_transportTableMutex, return NULL - if (!UtilAll::try_lock_for(m_transportTableMutex, 1000 * m_tcpTransportTryLockTimeout)) { + // try get transport_table_mutex_ until tcp_transport_try_lock_timeout_ to avoid blocking long time, + // if could not get transport_table_mutex_, return NULL + if (!UtilAll::try_lock_for(transport_table_mutex_, 1000 * tcp_transport_try_lock_timeout_)) { LOG_ERROR_NEW("GetTransport of:{} get timed_mutex timeout", addr); return nullptr; } - std::lock_guard lock(m_transportTableMutex, std::adopt_lock); + std::lock_guard lock(transport_table_mutex_, std::adopt_lock); // check for reuse - const auto& it = m_transportTable.find(addr); - if (it != m_transportTable.end()) { + const auto& it = transport_table_.find(addr); + if (it != transport_table_.end()) { channel = it->second; } @@ -420,11 +420,11 @@ TcpTransportPtr TcpRemotingClient::CreateTransport(const std::string& addr) { case TCP_CONNECT_STATUS_FAILED: LOG_ERROR_NEW("tcpTransport with server disconnected, erase server:{}", addr); channel->disconnect(addr); - m_transportTable.erase(it); + transport_table_.erase(it); break; default: // TCP_CONNECT_STATUS_CLOSED LOG_ERROR_NEW("go to CLOSED state, erase:{} from transportTable, and reconnect it", addr); - m_transportTable.erase(it); + transport_table_.erase(it); break; } } else { @@ -444,13 +444,13 @@ TcpTransportPtr TcpRemotingClient::CreateTransport(const std::string& addr) { return nullptr; } else { // even if connecting failed finally, this server transport will be erased by next CreateTransport - m_transportTable[addr] = channel; + transport_table_[addr] = channel; } } } // waiting... - TcpConnectStatus connectStatus = channel->waitTcpConnectEvent(static_cast(m_tcpConnectTimeout)); + TcpConnectStatus connectStatus = channel->waitTcpConnectEvent(static_cast(tcp_connect_timeout_)); if (connectStatus != TCP_CONNECT_STATUS_CONNECTED) { LOG_WARN_NEW("can not connect to server:{}", addr); // channel->disconnect(addr); @@ -462,33 +462,33 @@ TcpTransportPtr TcpRemotingClient::CreateTransport(const std::string& addr) { } TcpTransportPtr TcpRemotingClient::CreateNameServerTransport() { - // m_namesrvLock was added to avoid operation of NameServer was blocked by + // namesrv_lock_ was added to avoid operation of NameServer was blocked by // m_tcpLock, it was used by single Thread mostly, so no performance impact - // try get m_tcpLock until m_tcpTransportTryLockTimeout to avoid blocking long + // try get m_tcpLock until tcp_transport_try_lock_timeout_ to avoid blocking long // time, if could not get m_namesrvlock, return NULL LOG_DEBUG_NEW("create namesrv transport"); - if (!UtilAll::try_lock_for(m_namesrvLock, 1000 * m_tcpTransportTryLockTimeout)) { + if (!UtilAll::try_lock_for(namesrv_lock_, 1000 * tcp_transport_try_lock_timeout_)) { LOG_ERROR_NEW("CreateNameserverTransport get timed_mutex timeout"); return nullptr; } - std::lock_guard lock(m_namesrvLock, std::adopt_lock); + std::lock_guard lock(namesrv_lock_, std::adopt_lock); - if (!m_namesrvAddrChoosed.empty()) { - auto channel = CreateTransport(m_namesrvAddrChoosed); + if (!namesrv_addr_choosed_.empty()) { + auto channel = CreateTransport(namesrv_addr_choosed_); if (channel != nullptr) { return channel; } else { - m_namesrvAddrChoosed.clear(); + namesrv_addr_choosed_.clear(); } } - for (unsigned i = 0; i < m_namesrvAddrList.size(); i++) { - auto index = m_namesrvIndex++ % m_namesrvAddrList.size(); - LOG_INFO_NEW("namesrvIndex is:{}, index:{}, namesrvaddrlist size:{}", m_namesrvIndex, index, - m_namesrvAddrList.size()); - auto channel = CreateTransport(m_namesrvAddrList[index]); + for (unsigned i = 0; i < namesrv_addr_list_.size(); i++) { + auto index = namesrv_index_++ % namesrv_addr_list_.size(); + LOG_INFO_NEW("namesrvIndex is:{}, index:{}, namesrvaddrlist size:{}", namesrv_index_, index, + namesrv_addr_list_.size()); + auto channel = CreateTransport(namesrv_addr_list_[index]); if (channel != nullptr) { - m_namesrvAddrChoosed = m_namesrvAddrList[index]; + namesrv_addr_choosed_ = namesrv_addr_list_[index]; return channel; } } @@ -501,17 +501,17 @@ bool TcpRemotingClient::CloseTransport(const std::string& addr, TcpTransportPtr return CloseNameServerTransport(channel); } - if (!UtilAll::try_lock_for(m_transportTableMutex, 1000 * m_tcpTransportTryLockTimeout)) { + if (!UtilAll::try_lock_for(transport_table_mutex_, 1000 * tcp_transport_try_lock_timeout_)) { LOG_ERROR_NEW("CloseTransport of:{} get timed_mutex timeout", addr); return false; } - std::lock_guard lock(m_transportTableMutex, std::adopt_lock); + std::lock_guard lock(transport_table_mutex_, std::adopt_lock); LOG_INFO_NEW("CloseTransport of:{}", addr); bool removeItemFromTable = true; - const auto& it = m_transportTable.find(addr); - if (it != m_transportTable.end()) { + const auto& it = transport_table_.find(addr); + if (it != transport_table_.end()) { if (it->second->getStartTime() != channel->getStartTime()) { LOG_INFO_NEW("tcpTransport with addr:{} has been closed before, and has been created again, nothing to do", addr); removeItemFromTable = false; @@ -523,7 +523,7 @@ bool TcpRemotingClient::CloseTransport(const std::string& addr, TcpTransportPtr if (removeItemFromTable) { LOG_WARN_NEW("closeTransport: erase broker: {}", addr); - m_transportTable.erase(addr); + transport_table_.erase(addr); } LOG_WARN_NEW("closeTransport: disconnect:{} with state:{}", addr, channel->getTcpConnectStatus()); @@ -537,17 +537,17 @@ bool TcpRemotingClient::CloseTransport(const std::string& addr, TcpTransportPtr } bool TcpRemotingClient::CloseNameServerTransport(TcpTransportPtr channel) { - if (!UtilAll::try_lock_for(m_namesrvLock, 1000 * m_tcpTransportTryLockTimeout)) { + if (!UtilAll::try_lock_for(namesrv_lock_, 1000 * tcp_transport_try_lock_timeout_)) { LOG_ERROR_NEW("CloseNameServerTransport get timed_mutex timeout"); return false; } - std::lock_guard lock(m_namesrvLock, std::adopt_lock); + std::lock_guard lock(namesrv_lock_, std::adopt_lock); - std::string addr = m_namesrvAddrChoosed; + std::string addr = namesrv_addr_choosed_; bool removeItemFromTable = CloseTransport(addr, channel); if (removeItemFromTable) { - m_namesrvAddrChoosed.clear(); + namesrv_addr_choosed_.clear(); } return removeItemFromTable; @@ -560,11 +560,11 @@ bool TcpRemotingClient::SendCommand(TcpTransportPtr channel, RemotingCommand& ms void TcpRemotingClient::channelClosed(TcpTransportPtr channel) { LOG_DEBUG_NEW("channel of {} is closed.", channel->getPeerAddrAndPort()); - m_handleExecutor.submit([channel] { static_cast(channel->getInfo())->activeAllResponses(); }); + handle_executor_.submit([channel] { static_cast(channel->getInfo())->activeAllResponses(); }); } void TcpRemotingClient::messageReceived(ByteArrayRef msg, TcpTransportPtr channel) { - m_dispatchExecutor.submit(std::bind(&TcpRemotingClient::processMessageReceived, this, std::move(msg), channel)); + dispatch_executor_.submit(std::bind(&TcpRemotingClient::processMessageReceived, this, std::move(msg), channel)); } void TcpRemotingClient::processMessageReceived(ByteArrayRef msg, TcpTransportPtr channel) { @@ -604,7 +604,7 @@ void TcpRemotingClient::processMessageReceived(ByteArrayRef msg, TcpTransportPtr TcpTransportPtr channel_; }; - m_handleExecutor.submit(task_adaptor(this, std::move(cmd), channel)); + handle_executor_.submit(task_adaptor(this, std::move(cmd), channel)); } } @@ -613,14 +613,14 @@ void TcpRemotingClient::processResponseCommand(std::unique_ptr int opaque = responseCommand->opaque(); auto responseFuture = popResponseFuture(channel, opaque); if (responseFuture != nullptr) { - int code = responseFuture->getRequestCode(); + int code = responseFuture->request_code(); LOG_DEBUG_NEW("processResponseCommand, opaque:{}, request code:{}, server:{}", opaque, code, channel->getPeerAddrAndPort()); if (responseFuture->hasInvokeCallback()) { responseFuture->setResponseCommand(std::move(responseCommand)); // bind shared_ptr can save object's life - m_handleExecutor.submit(std::bind(&ResponseFuture::executeInvokeCallback, responseFuture)); + handle_executor_.submit(std::bind(&ResponseFuture::executeInvokeCallback, responseFuture)); } else { responseFuture->putResponse(std::move(responseCommand)); } @@ -635,8 +635,8 @@ void TcpRemotingClient::processRequestCommand(std::unique_ptr r std::unique_ptr response; int requestCode = requestCommand->code(); - const auto& it = m_processorTable.find(requestCode); - if (it != m_processorTable.end()) { + const auto& it = processor_table_.find(requestCode); + if (it != processor_table_.end()) { try { auto* processor = it->second; @@ -674,15 +674,15 @@ void TcpRemotingClient::putResponseFuture(TcpTransportPtr channel, int opaque, R return static_cast(channel->getInfo())->putResponseFuture(opaque, future); } -// NOTE: after call this function, shared_ptr of m_futureTable[opaque] will -// be erased, so caller must ensure the life cycle of returned shared_ptr; +// NOTE: after call this function, shared_ptr of future_table_[opaque] will +// be erased, so caller must ensure the life cycle of returned shared_ptr ResponseFuturePtr TcpRemotingClient::popResponseFuture(TcpTransportPtr channel, int opaque) { return static_cast(channel->getInfo())->popResponseFuture(opaque); } void TcpRemotingClient::registerProcessor(MQRequestCode requestCode, RequestProcessor* requestProcessor) { // replace - m_processorTable[requestCode] = requestProcessor; + processor_table_[requestCode] = requestProcessor; } } // namespace rocketmq diff --git a/src/transport/TcpRemotingClient.h b/src/transport/TcpRemotingClient.h index 6897dee48..3ffbb664c 100755 --- a/src/transport/TcpRemotingClient.h +++ b/src/transport/TcpRemotingClient.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __TCP_REMOTING_CLIENT_H__ -#define __TCP_REMOTING_CLIENT_H__ +#ifndef ROCKETMQ_TRANSPORT_TCPREMOTINGCLIENT_H_ +#define ROCKETMQ_TRANSPORT_TCPREMOTINGCLIENT_H_ #include #include @@ -23,7 +23,7 @@ #include #include -#include "MQClientException.h" +#include "MQException.h" #include "MQProtos.h" #include "RPCHook.h" #include "RemotingCommand.h" @@ -59,7 +59,7 @@ class TcpRemotingClient { void registerProcessor(MQRequestCode requestCode, RequestProcessor* requestProcessor); - std::vector getNameServerAddressList() const { return m_namesrvAddrList; } + std::vector getNameServerAddressList() const { return namesrv_addr_list_; } private: static bool SendCommand(TcpTransportPtr channel, RemotingCommand& msg); @@ -103,28 +103,28 @@ class TcpRemotingClient { using ProcessorMap = std::map; using TransportMap = std::map>; - ProcessorMap m_processorTable; // code -> processor + ProcessorMap processor_table_; // code -> processor - TransportMap m_transportTable; // addr -> transport - std::timed_mutex m_transportTableMutex; + TransportMap transport_table_; // addr -> transport + std::timed_mutex transport_table_mutex_; // FIXME: not strict thread-safe in abnormal scence - std::vector m_rpcHooks; // for Acl / ONS + std::vector rpc_hooks_; // for Acl / ONS - uint64_t m_tcpConnectTimeout; // ms - uint64_t m_tcpTransportTryLockTimeout; // s + uint64_t tcp_connect_timeout_; // ms + uint64_t tcp_transport_try_lock_timeout_; // s // NameServer - std::timed_mutex m_namesrvLock; - std::vector m_namesrvAddrList; - std::string m_namesrvAddrChoosed; - size_t m_namesrvIndex; - - thread_pool_executor m_dispatchExecutor; - thread_pool_executor m_handleExecutor; - scheduled_thread_pool_executor m_timeoutExecutor; + std::timed_mutex namesrv_lock_; + std::vector namesrv_addr_list_; + std::string namesrv_addr_choosed_; + size_t namesrv_index_; + + thread_pool_executor dispatch_executor_; + thread_pool_executor handle_executor_; + scheduled_thread_pool_executor timeout_executor_; }; } // namespace rocketmq -#endif // __TCP_REMOTING_CLIENT_H__ +#endif // ROCKETMQ_TRANSPORT_TCPREMOTINGCLIENT_H_ diff --git a/src/transport/TcpTransport.cpp b/src/transport/TcpTransport.cpp index 15cfa9dd4..431ebd7e1 100644 --- a/src/transport/TcpTransport.cpp +++ b/src/transport/TcpTransport.cpp @@ -34,14 +34,14 @@ namespace rocketmq { TcpTransport::TcpTransport(ReadCallback readCallback, CloseCallback closeCallback, std::unique_ptr info) - : m_event(nullptr), - m_tcpConnectStatus(TCP_CONNECT_STATUS_CREATED), - m_statusMutex(), - m_statusEvent(), - m_readCallback(readCallback), - m_closeCallback(closeCallback), - m_info(std::move(info)) { - m_startTime = UtilAll::currentTimeMillis(); + : event_(nullptr), + tcp_connect_status_(TCP_CONNECT_STATUS_CREATED), + status_mutex_(), + status_event_(), + read_callback_(readCallback), + close_callback_(closeCallback), + info_(std::move(info)) { + start_time_ = UtilAll::currentTimeMillis(); } TcpTransport::~TcpTransport() { @@ -51,53 +51,53 @@ TcpTransport::~TcpTransport() { TcpConnectStatus TcpTransport::closeBufferEvent(bool isDeleted) { // closeBufferEvent is idempotent. if (setTcpConnectEvent(TCP_CONNECT_STATUS_CLOSED) != TCP_CONNECT_STATUS_CLOSED) { - if (m_event != nullptr) { - m_event->close(); + if (event_ != nullptr) { + event_->close(); } - if (!isDeleted && m_closeCallback != nullptr) { - m_closeCallback(shared_from_this()); + if (!isDeleted && close_callback_ != nullptr) { + close_callback_(shared_from_this()); } } return TCP_CONNECT_STATUS_CLOSED; } TcpConnectStatus TcpTransport::getTcpConnectStatus() { - return m_tcpConnectStatus; + return tcp_connect_status_; } TcpConnectStatus TcpTransport::waitTcpConnectEvent(int timeoutMillis) { - if (m_tcpConnectStatus == TCP_CONNECT_STATUS_CONNECTING) { - std::unique_lock lock(m_statusMutex); - if (!m_statusEvent.wait_for(lock, std::chrono::milliseconds(timeoutMillis), - [&] { return m_tcpConnectStatus != TCP_CONNECT_STATUS_CONNECTING; })) { + if (tcp_connect_status_ == TCP_CONNECT_STATUS_CONNECTING) { + std::unique_lock lock(status_mutex_); + if (!status_event_.wait_for(lock, std::chrono::milliseconds(timeoutMillis), + [&] { return tcp_connect_status_ != TCP_CONNECT_STATUS_CONNECTING; })) { LOG_INFO("connect timeout"); } } - return m_tcpConnectStatus; + return tcp_connect_status_; } // internal method TcpConnectStatus TcpTransport::setTcpConnectEvent(TcpConnectStatus connectStatus) { - TcpConnectStatus oldStatus = m_tcpConnectStatus.exchange(connectStatus, std::memory_order_relaxed); + TcpConnectStatus oldStatus = tcp_connect_status_.exchange(connectStatus, std::memory_order_relaxed); if (oldStatus == TCP_CONNECT_STATUS_CONNECTING) { // awake waiting thread - m_statusEvent.notify_all(); + status_event_.notify_all(); } return oldStatus; } bool TcpTransport::setTcpConnectEventIf(TcpConnectStatus& expectedStatus, TcpConnectStatus newStatus) { - bool isSuccessed = m_tcpConnectStatus.compare_exchange_strong(expectedStatus, newStatus); + bool isSuccessed = tcp_connect_status_.compare_exchange_strong(expectedStatus, newStatus); if (expectedStatus == TCP_CONNECT_STATUS_CONNECTING) { // awake waiting thread - m_statusEvent.notify_all(); + status_event_.notify_all(); } return isSuccessed; } void TcpTransport::disconnect(const std::string& addr) { // disconnect is idempotent. - LOG_INFO_NEW("disconnect:{} start. event:{}", addr, (void*)m_event.get()); + LOG_INFO_NEW("disconnect:{} start. event:{}", addr, (void*)event_.get()); closeBufferEvent(); LOG_INFO_NEW("disconnect:{} completely", addr); } @@ -108,8 +108,8 @@ TcpConnectStatus TcpTransport::connect(const std::string& addr, int timeoutMilli TcpConnectStatus curStatus = TCP_CONNECT_STATUS_CREATED; if (setTcpConnectEventIf(curStatus, TCP_CONNECT_STATUS_CONNECTING)) { // create BufferEvent - m_event.reset(EventLoop::GetDefaultEventLoop()->createBufferEvent(-1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE)); - if (nullptr == m_event) { + event_.reset(EventLoop::GetDefaultEventLoop()->createBufferEvent(-1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE)); + if (nullptr == event_) { LOG_ERROR_NEW("create BufferEvent failed"); return closeBufferEvent(); } @@ -132,12 +132,12 @@ TcpConnectStatus TcpTransport::connect(const std::string& addr, int timeoutMilli LOG_WARN_NEW("[BUG] TcpTransport object is released."); } }; - m_event->setCallback(readCallback, nullptr, eventCallback); - m_event->setWatermark(EV_READ, 4, 0); - m_event->enable(EV_READ | EV_WRITE); + event_->setCallback(readCallback, nullptr, eventCallback); + event_->setWatermark(EV_READ, 4, 0); + event_->enable(EV_READ | EV_WRITE); - if (m_event->connect(addr) < 0) { - LOG_WARN_NEW("connect to fd:{} failed", m_event->getfd()); + if (event_->connect(addr) < 0) { + LOG_WARN_NEW("connect to fd:{} failed", event_->getfd()); return closeBufferEvent(); } } else { @@ -145,7 +145,7 @@ TcpConnectStatus TcpTransport::connect(const std::string& addr, int timeoutMilli } if (timeoutMillis <= 0) { - LOG_INFO_NEW("try to connect to fd:{}, addr:{}", m_event->getfd(), addr); + LOG_INFO_NEW("try to connect to fd:{}, addr:{}", event_->getfd(), addr); return TCP_CONNECT_STATUS_CONNECTING; } @@ -250,8 +250,8 @@ void TcpTransport::dataArrived(BufferEvent& event) { } void TcpTransport::messageReceived(ByteArrayRef msg) { - if (m_readCallback != nullptr) { - m_readCallback(std::move(msg), shared_from_this()); + if (read_callback_ != nullptr) { + read_callback_(std::move(msg), shared_from_this()); } } @@ -264,15 +264,15 @@ bool TcpTransport::sendMessage(const char* data, size_t len) { do not need to consider large data which could not send by once, as bufferevent could handle this case; */ - return m_event != nullptr && m_event->write(data, len) == 0; + return event_ != nullptr && event_->write(data, len) == 0; } const std::string& TcpTransport::getPeerAddrAndPort() { - return m_event != nullptr ? m_event->getPeerAddrPort() : null; + return event_ != nullptr ? event_->getPeerAddrPort() : null; } const uint64_t TcpTransport::getStartTime() const { - return m_startTime; + return start_time_; } } // namespace rocketmq diff --git a/src/transport/TcpTransport.h b/src/transport/TcpTransport.h index cffe2e9de..b870f69c2 100755 --- a/src/transport/TcpTransport.h +++ b/src/transport/TcpTransport.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __TCP_TRANSPORT_H__ -#define __TCP_TRANSPORT_H__ +#ifndef ROCKETMQ_TRANSPORT_TCPTRANSPORT_H_ +#define ROCKETMQ_TRANSPORT_TCPTRANSPORT_H_ #include #include @@ -66,7 +66,7 @@ class TcpTransport : public noncopyable, public std::enable_shared_from_this m_event; // NOTE: use m_event in callback is unsafe. + std::unique_ptr event_; // NOTE: use event_ in callback is unsafe. - std::atomic m_tcpConnectStatus; - std::mutex m_statusMutex; - std::condition_variable m_statusEvent; + std::atomic tcp_connect_status_; + std::mutex status_mutex_; + std::condition_variable status_event_; // callback - ReadCallback m_readCallback; - CloseCallback m_closeCallback; + ReadCallback read_callback_; + CloseCallback close_callback_; // info - std::unique_ptr m_info; + std::unique_ptr info_; }; } // namespace rocketmq -#endif // __TCP_TRANSPORT__ +#endif // ROCKETMQ_TRANSPORT_TCPTRANSPORT_H_ diff --git a/test/src/common/NamesrvConfigTest.cpp b/test/src/common/NamesrvConfigTest.cpp deleted file mode 100644 index da2bed182..000000000 --- a/test/src/common/NamesrvConfigTest.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 -#include - -#include - -#include "NamesrvConfig.h" - -using testing::InitGoogleMock; -using testing::InitGoogleTest; -using testing::Return; - -using rocketmq::NamesrvConfig; - -TEST(NamesrvConfigTest, Init) { - NamesrvConfig namesrvConfig; - - const std::string home = "/home/rocketmq"; - namesrvConfig.setRocketmqHome(home); - EXPECT_EQ(namesrvConfig.getRocketmqHome(), "/home/rocketmq"); - - namesrvConfig.setKvConfigPath("/home/rocketmq"); - EXPECT_EQ(namesrvConfig.getKvConfigPath(), "/home/rocketmq"); -} - -int main(int argc, char* argv[]) { - InitGoogleMock(&argc, argv); - testing::GTEST_FLAG(throw_on_failure) = true; - testing::GTEST_FLAG(filter) = "NamesrvConfigTest.*"; - return RUN_ALL_TESTS(); -} diff --git a/test/src/common/TopicConfigTest.cpp b/test/src/common/TopicConfigTest.cpp index a9748a243..42c014c7c 100644 --- a/test/src/common/TopicConfigTest.cpp +++ b/test/src/common/TopicConfigTest.cpp @@ -42,43 +42,43 @@ TEST(TopicConfigTest, EncodeAndDecode) { TEST(TopicConfigTest, GetterAndSetter) { TopicConfig topicConfig; - topicConfig.setTopicName("testTopic"); - EXPECT_EQ(topicConfig.getTopicName(), "testTopic"); + topicConfig.set_topic_name("testTopic"); + EXPECT_EQ(topicConfig.topic_name(), "testTopic"); - topicConfig.setReadQueueNums(4); - EXPECT_EQ(topicConfig.getReadQueueNums(), 4); + topicConfig.set_read_queue_nums(4); + EXPECT_EQ(topicConfig.read_queue_nums(), 4); - topicConfig.setWriteQueueNums(4); - EXPECT_EQ(topicConfig.getWriteQueueNums(), 4); + topicConfig.set_write_queue_nums(4); + EXPECT_EQ(topicConfig.write_queue_nums(), 4); - topicConfig.setPerm(PermName::PERM_READ); - EXPECT_EQ(topicConfig.getPerm(), PermName::PERM_READ); + topicConfig.set_perm(PermName::PERM_READ); + EXPECT_EQ(topicConfig.perm(), PermName::PERM_READ); - topicConfig.setTopicFilterType(TopicFilterType::MULTI_TAG); - EXPECT_EQ(topicConfig.getTopicFilterType(), TopicFilterType::MULTI_TAG); + topicConfig.set_topic_filter_type(TopicFilterType::MULTI_TAG); + EXPECT_EQ(topicConfig.topic_filter_type(), TopicFilterType::MULTI_TAG); } TEST(TopicConfigTest, Init) { TopicConfig topicConfig; - EXPECT_TRUE(topicConfig.getTopicName() == ""); - EXPECT_EQ(topicConfig.getReadQueueNums(), TopicConfig::DefaultReadQueueNums); - EXPECT_EQ(topicConfig.getWriteQueueNums(), TopicConfig::DefaultWriteQueueNums); - EXPECT_EQ(topicConfig.getPerm(), PermName::PERM_READ | PermName::PERM_WRITE); - EXPECT_EQ(topicConfig.getTopicFilterType(), TopicFilterType::SINGLE_TAG); + EXPECT_TRUE(topicConfig.topic_name() == ""); + EXPECT_EQ(topicConfig.read_queue_nums(), TopicConfig::DEFAULT_READ_QUEUE_NUMS); + EXPECT_EQ(topicConfig.write_queue_nums(), TopicConfig::DEFAULT_WRITE_QUEUE_NUMS); + EXPECT_EQ(topicConfig.perm(), PermName::PERM_READ | PermName::PERM_WRITE); + EXPECT_EQ(topicConfig.topic_filter_type(), TopicFilterType::SINGLE_TAG); TopicConfig twoTopicConfig("testTopic"); - EXPECT_EQ(twoTopicConfig.getTopicName(), "testTopic"); - EXPECT_EQ(twoTopicConfig.getReadQueueNums(), TopicConfig::DefaultReadQueueNums); - EXPECT_EQ(twoTopicConfig.getWriteQueueNums(), TopicConfig::DefaultWriteQueueNums); - EXPECT_EQ(twoTopicConfig.getPerm(), PermName::PERM_READ | PermName::PERM_WRITE); - EXPECT_EQ(twoTopicConfig.getTopicFilterType(), TopicFilterType::SINGLE_TAG); + EXPECT_EQ(twoTopicConfig.topic_name(), "testTopic"); + EXPECT_EQ(twoTopicConfig.read_queue_nums(), TopicConfig::DEFAULT_READ_QUEUE_NUMS); + EXPECT_EQ(twoTopicConfig.write_queue_nums(), TopicConfig::DEFAULT_WRITE_QUEUE_NUMS); + EXPECT_EQ(twoTopicConfig.perm(), PermName::PERM_READ | PermName::PERM_WRITE); + EXPECT_EQ(twoTopicConfig.topic_filter_type(), TopicFilterType::SINGLE_TAG); TopicConfig threeTopicConfig("testTopic", 4, 4, PermName::PERM_READ); - EXPECT_EQ(threeTopicConfig.getTopicName(), "testTopic"); - EXPECT_EQ(threeTopicConfig.getReadQueueNums(), 4); - EXPECT_EQ(threeTopicConfig.getWriteQueueNums(), 4); - EXPECT_EQ(threeTopicConfig.getPerm(), PermName::PERM_READ); - EXPECT_EQ(threeTopicConfig.getTopicFilterType(), TopicFilterType::SINGLE_TAG); + EXPECT_EQ(threeTopicConfig.topic_name(), "testTopic"); + EXPECT_EQ(threeTopicConfig.read_queue_nums(), 4); + EXPECT_EQ(threeTopicConfig.write_queue_nums(), 4); + EXPECT_EQ(threeTopicConfig.perm(), PermName::PERM_READ); + EXPECT_EQ(threeTopicConfig.topic_filter_type(), TopicFilterType::SINGLE_TAG); } int main(int argc, char* argv[]) { diff --git a/test/src/common/ValidatorsTest.cpp b/test/src/common/ValidatorsTest.cpp index b56088915..ee26d77b8 100644 --- a/test/src/common/ValidatorsTest.cpp +++ b/test/src/common/ValidatorsTest.cpp @@ -19,7 +19,7 @@ #include -#include "MQClientException.h" +#include "MQException.h" #include "MQMessage.h" #include "Validators.h" @@ -31,11 +31,13 @@ using rocketmq::MQClientException; using rocketmq::MQMessage; using rocketmq::Validators; +const std::string VALID_PATTERN_STR = "^[a-zA-Z0-9_-]+$"; + TEST(ValidatorsTest, RegularExpressionMatcher) { EXPECT_FALSE(Validators::regularExpressionMatcher("", "")); EXPECT_TRUE(Validators::regularExpressionMatcher("123456", "")); - EXPECT_FALSE(Validators::regularExpressionMatcher("123%456", Validators::validPatternStr)); - EXPECT_TRUE(Validators::regularExpressionMatcher("123456", Validators::validPatternStr)); + EXPECT_FALSE(Validators::regularExpressionMatcher("123%456", VALID_PATTERN_STR)); + EXPECT_TRUE(Validators::regularExpressionMatcher("123456", VALID_PATTERN_STR)); } TEST(ValidatorsTest, GetGroupWithRegularExpression) { diff --git a/test/src/extern/CPullConsumerTest.cpp b/test/src/extern/CPullConsumerTest.cpp index 2297779e3..df323648c 100644 --- a/test/src/extern/CPullConsumerTest.cpp +++ b/test/src/extern/CPullConsumerTest.cpp @@ -123,7 +123,7 @@ TEST(CPullConsumerTest, InfoMock) { // EXPECT_CALL(*mqPullConsumer,setLogFileSizeAndNum(_,_)).Times(1); EXPECT_EQ(SetPullConsumerLogFileNumAndSize(pullConsumer, 1, 2), OK); - // EXPECT_CALL(*mqPullConsumer,setLogLevel(_)).Times(1); + // EXPECT_CALL(*mqPullConsumer,set_log_level(_)).Times(1); EXPECT_EQ(SetPullConsumerLogLevel(pullConsumer, E_LOG_LEVEL_INFO), OK); std::vector fullMQ; diff --git a/test/src/message/MQMessageQueueTest.cpp b/test/src/message/MQMessageQueueTest.cpp index 54b8f9180..830f2bd20 100644 --- a/test/src/message/MQMessageQueueTest.cpp +++ b/test/src/message/MQMessageQueueTest.cpp @@ -27,32 +27,32 @@ using rocketmq::MQMessageQueue; TEST(MessageQueueTest, Init) { MQMessageQueue messageQueue; - EXPECT_EQ(messageQueue.getBrokerName(), ""); - EXPECT_EQ(messageQueue.getTopic(), ""); - EXPECT_EQ(messageQueue.getQueueId(), -1); + EXPECT_EQ(messageQueue.broker_name(), ""); + EXPECT_EQ(messageQueue.topic(), ""); + EXPECT_EQ(messageQueue.queue_id(), -1); MQMessageQueue twoMessageQueue("testTopic", "testBroker", 1); - EXPECT_EQ(twoMessageQueue.getBrokerName(), "testBroker"); - EXPECT_EQ(twoMessageQueue.getTopic(), "testTopic"); - EXPECT_EQ(twoMessageQueue.getQueueId(), 1); + EXPECT_EQ(twoMessageQueue.broker_name(), "testBroker"); + EXPECT_EQ(twoMessageQueue.topic(), "testTopic"); + EXPECT_EQ(twoMessageQueue.queue_id(), 1); MQMessageQueue threeMessageQueue("threeTestTopic", "threeTestBroker", 2); MQMessageQueue fourMessageQueue(threeMessageQueue); - EXPECT_EQ(fourMessageQueue.getBrokerName(), "threeTestBroker"); - EXPECT_EQ(fourMessageQueue.getTopic(), "threeTestTopic"); - EXPECT_EQ(fourMessageQueue.getQueueId(), 2); + EXPECT_EQ(fourMessageQueue.broker_name(), "threeTestBroker"); + EXPECT_EQ(fourMessageQueue.topic(), "threeTestTopic"); + EXPECT_EQ(fourMessageQueue.queue_id(), 2); fourMessageQueue = twoMessageQueue; - EXPECT_EQ(fourMessageQueue.getBrokerName(), "testBroker"); - EXPECT_EQ(fourMessageQueue.getTopic(), "testTopic"); - EXPECT_EQ(fourMessageQueue.getQueueId(), 1); - - fourMessageQueue.setBrokerName("fourTestBroker"); - fourMessageQueue.setTopic("fourTestTopic"); - fourMessageQueue.setQueueId(4); - EXPECT_EQ(fourMessageQueue.getBrokerName(), "fourTestBroker"); - EXPECT_EQ(fourMessageQueue.getTopic(), "fourTestTopic"); - EXPECT_EQ(fourMessageQueue.getQueueId(), 4); + EXPECT_EQ(fourMessageQueue.broker_name(), "testBroker"); + EXPECT_EQ(fourMessageQueue.topic(), "testTopic"); + EXPECT_EQ(fourMessageQueue.queue_id(), 1); + + fourMessageQueue.set_broker_name("fourTestBroker"); + fourMessageQueue.set_topic("fourTestTopic"); + fourMessageQueue.set_queue_id(4); + EXPECT_EQ(fourMessageQueue.broker_name(), "fourTestBroker"); + EXPECT_EQ(fourMessageQueue.topic(), "fourTestTopic"); + EXPECT_EQ(fourMessageQueue.queue_id(), 4); } TEST(MessageQueueTest, Operators) { @@ -64,21 +64,21 @@ TEST(MessageQueueTest, Operators) { EXPECT_EQ(messageQueue, twoMessageQueue); EXPECT_EQ(messageQueue.compareTo(twoMessageQueue), 0); - twoMessageQueue.setTopic("testTopic"); + twoMessageQueue.set_topic("testTopic"); EXPECT_FALSE(messageQueue == twoMessageQueue); EXPECT_NE(messageQueue.compareTo(twoMessageQueue), 0); twoMessageQueue = messageQueue; EXPECT_TRUE(messageQueue == twoMessageQueue); - twoMessageQueue.setQueueId(1); + twoMessageQueue.set_queue_id(1); EXPECT_FALSE(messageQueue == twoMessageQueue); EXPECT_NE(messageQueue.compareTo(twoMessageQueue), 0); twoMessageQueue = messageQueue; EXPECT_TRUE(messageQueue == twoMessageQueue); - twoMessageQueue.setBrokerName("testBroker"); + twoMessageQueue.set_broker_name("testBroker"); EXPECT_FALSE(messageQueue == twoMessageQueue); EXPECT_FALSE(messageQueue.compareTo(twoMessageQueue) == 0); } diff --git a/test/src/protocol/CommandHeaderTest.cpp b/test/src/protocol/CommandHeaderTest.cpp index 502ab29ba..d98fffb70 100644 --- a/test/src/protocol/CommandHeaderTest.cpp +++ b/test/src/protocol/CommandHeaderTest.cpp @@ -25,7 +25,7 @@ #include #include "ByteArray.h" -#include "MQClientException.h" +#include "MQException.h" #include "MessageSysFlag.h" #include "UtilAll.h" #include "protocol/header/CommandHeader.h" diff --git a/test/src/protocol/MessageQueueTest.cpp b/test/src/protocol/MessageQueueTest.cpp index fa6afa48d..0f6f5fcf8 100644 --- a/test/src/protocol/MessageQueueTest.cpp +++ b/test/src/protocol/MessageQueueTest.cpp @@ -28,9 +28,9 @@ using rocketmq::toJson; TEST(MessageQueueTest, Json) { MQMessageQueue messageQueue("testTopic", "testBroker", 1); - EXPECT_EQ(messageQueue.getQueueId(), 1); - EXPECT_EQ(messageQueue.getTopic(), "testTopic"); - EXPECT_EQ(messageQueue.getBrokerName(), "testBroker"); + EXPECT_EQ(messageQueue.queue_id(), 1); + EXPECT_EQ(messageQueue.topic(), "testTopic"); + EXPECT_EQ(messageQueue.broker_name(), "testBroker"); Json::Value outJson = toJson(messageQueue); EXPECT_EQ(outJson["queueId"], 1); diff --git a/test/src/protocol/RemotingCommandTest.cpp b/test/src/protocol/RemotingCommandTest.cpp index 7729d9377..42ee77168 100644 --- a/test/src/protocol/RemotingCommandTest.cpp +++ b/test/src/protocol/RemotingCommandTest.cpp @@ -54,7 +54,7 @@ TEST(RemotingCommandTest, Init) { EXPECT_EQ(twoRemotingCommand.code(), 13); EXPECT_EQ(twoRemotingCommand.opaque(), 0); EXPECT_EQ(twoRemotingCommand.remark(), ""); - EXPECT_EQ(twoRemotingCommand.version(), MQVersion::s_CurrentVersion); + EXPECT_EQ(twoRemotingCommand.version(), MQVersion::CURRENT_VERSION); EXPECT_EQ(twoRemotingCommand.flag(), 0); EXPECT_TRUE(twoRemotingCommand.body() == nullptr); EXPECT_TRUE(twoRemotingCommand.readCustomHeader() == nullptr); @@ -62,12 +62,12 @@ TEST(RemotingCommandTest, Init) { RemotingCommand threeRemotingCommand(13, new GetRouteInfoRequestHeader("topic")); EXPECT_FALSE(threeRemotingCommand.readCustomHeader() == nullptr); - RemotingCommand frouRemotingCommand(13, "CPP", MQVersion::s_CurrentVersion, 12, 3, "remark", + RemotingCommand frouRemotingCommand(13, MQVersion::CURRENT_LANGUAGE, MQVersion::CURRENT_VERSION, 12, 3, "remark", new GetRouteInfoRequestHeader("topic")); EXPECT_EQ(frouRemotingCommand.code(), 13); EXPECT_EQ(frouRemotingCommand.opaque(), 12); EXPECT_EQ(frouRemotingCommand.remark(), "remark"); - EXPECT_EQ(frouRemotingCommand.version(), MQVersion::s_CurrentVersion); + EXPECT_EQ(frouRemotingCommand.version(), MQVersion::CURRENT_VERSION); EXPECT_EQ(frouRemotingCommand.flag(), 3); EXPECT_TRUE(frouRemotingCommand.body() == nullptr); EXPECT_FALSE(frouRemotingCommand.readCustomHeader() == nullptr); @@ -76,7 +76,7 @@ TEST(RemotingCommandTest, Init) { EXPECT_EQ(sixRemotingCommand.code(), 13); EXPECT_EQ(sixRemotingCommand.opaque(), 12); EXPECT_EQ(sixRemotingCommand.remark(), "remark"); - EXPECT_EQ(sixRemotingCommand.version(), MQVersion::s_CurrentVersion); + EXPECT_EQ(sixRemotingCommand.version(), MQVersion::CURRENT_VERSION); EXPECT_EQ(sixRemotingCommand.flag(), 3); EXPECT_TRUE(sixRemotingCommand.body() == nullptr); EXPECT_FALSE(sixRemotingCommand.readCustomHeader() == nullptr); @@ -85,7 +85,7 @@ TEST(RemotingCommandTest, Init) { EXPECT_EQ(sevenRemotingCommand->code(), 13); EXPECT_EQ(sevenRemotingCommand->opaque(), 12); EXPECT_EQ(sevenRemotingCommand->remark(), "remark"); - EXPECT_EQ(sevenRemotingCommand->version(), MQVersion::s_CurrentVersion); + EXPECT_EQ(sevenRemotingCommand->version(), MQVersion::CURRENT_VERSION); EXPECT_EQ(sevenRemotingCommand->flag(), 3); EXPECT_TRUE(sevenRemotingCommand->body() == nullptr); EXPECT_FALSE(sevenRemotingCommand->readCustomHeader() == nullptr); @@ -110,7 +110,7 @@ TEST(RemotingCommandTest, Info) { } TEST(RemotingCommandTest, Flag) { - RemotingCommand remotingCommand(13, "CPP", MQVersion::s_CurrentVersion, 12, 0, "remark", + RemotingCommand remotingCommand(13, MQVersion::CURRENT_LANGUAGE, MQVersion::CURRENT_VERSION, 12, 0, "remark", new GetRouteInfoRequestHeader("topic")); ; EXPECT_EQ(remotingCommand.flag(), 0); @@ -130,8 +130,8 @@ TEST(RemotingCommandTest, Flag) { } TEST(RemotingCommandTest, EncodeAndDecode) { - RemotingCommand remotingCommand(MQRequestCode::QUERY_BROKER_OFFSET, "CPP", MQVersion::s_CurrentVersion, 12, 3, - "remark", nullptr); + RemotingCommand remotingCommand(MQRequestCode::QUERY_BROKER_OFFSET, MQVersion::CURRENT_LANGUAGE, + MQVersion::CURRENT_VERSION, 12, 3, "remark", nullptr); remotingCommand.set_body("123123"); auto package = remotingCommand.encode(); @@ -151,8 +151,8 @@ TEST(RemotingCommandTest, EncodeAndDecode) { requestHeader->setConsumerGroup("consumerGroup"); requestHeader->setJstackEnable(false); - RemotingCommand remotingCommand2(MQRequestCode::GET_CONSUMER_RUNNING_INFO, "CPP", MQVersion::s_CurrentVersion, 12, 3, - "remark", requestHeader); + RemotingCommand remotingCommand2(MQRequestCode::GET_CONSUMER_RUNNING_INFO, MQVersion::CURRENT_LANGUAGE, + MQVersion::CURRENT_VERSION, 12, 3, "remark", requestHeader); remotingCommand2.set_body("123123"); package = remotingCommand2.encode(); diff --git a/test/src/protocol/TopicRouteDataTest.cpp b/test/src/protocol/TopicRouteDataTest.cpp index 3b518b9f1..cb70c100c 100644 --- a/test/src/protocol/TopicRouteDataTest.cpp +++ b/test/src/protocol/TopicRouteDataTest.cpp @@ -20,7 +20,7 @@ #include #include "ByteArray.h" -#include "TopicRouteData.h" +#include "TopicRouteData.hpp" using testing::InitGoogleMock; using testing::InitGoogleTest; @@ -64,22 +64,17 @@ TEST(TopicRouteDataTest, TopicRouteData) { const ByteArray bodyData((char*)data.data(), data.size()); std::unique_ptr topicRouteData(TopicRouteData::Decode(bodyData)); - EXPECT_EQ(root["orderTopicConf"], topicRouteData->getOrderTopicConf()); + EXPECT_EQ(root["orderTopicConf"], topicRouteData->order_topic_conf()); - BrokerData broker; - broker.brokerName = "testBroker"; - broker.brokerAddrs[0] = "127.0.0.1:10091"; - broker.brokerAddrs[1] = "127.0.0.2:10092"; + BrokerData broker("testBroker"); + broker.broker_addrs()[0] = "127.0.0.1:10091"; + broker.broker_addrs()[1] = "127.0.0.2:10092"; - std::vector brokerDataSt = topicRouteData->getBrokerDatas(); + std::vector brokerDataSt = topicRouteData->broker_datas(); EXPECT_EQ(broker, brokerDataSt[0]); - QueueData queue; - queue.brokerName = "brokerTest"; - queue.readQueueNums = 8; - queue.writeQueueNums = 8; - queue.perm = 7; - std::vector queueDataSt = topicRouteData->getQueueDatas(); + QueueData queue("brokerTest", 8, 8, 7); + std::vector queueDataSt = topicRouteData->queue_datas(); EXPECT_EQ(queue, queueDataSt[0]); EXPECT_EQ(topicRouteData->selectBrokerAddr(), "127.0.0.1:10091"); diff --git a/test/src/transport/ClientRemotingProcessorTest.cpp b/test/src/transport/ClientRemotingProcessorTest.cpp index 843fa49a5..34f7c6acb 100644 --- a/test/src/transport/ClientRemotingProcessorTest.cpp +++ b/test/src/transport/ClientRemotingProcessorTest.cpp @@ -26,7 +26,7 @@ #include "ClientRPCHook.h" #include "ClientRemotingProcessor.h" #include "ConsumerRunningInfo.h" -#include "MQClientConfigImpl.h" +#include "MQClientConfigImpl.hpp" #include "MQClientInstance.h" #include "MQMessageQueue.h" #include "MQProtos.h" diff --git a/test/src/transport/ResponseFutureTest.cpp b/test/src/transport/ResponseFutureTest.cpp index e199fe07b..9826c82c1 100644 --- a/test/src/transport/ResponseFutureTest.cpp +++ b/test/src/transport/ResponseFutureTest.cpp @@ -41,10 +41,10 @@ class MockInvokeCallback : public InvokeCallback { TEST(ResponseFutureTest, Init) { ResponseFuture responseFuture(MQRequestCode::QUERY_BROKER_OFFSET, 4, 1000); - EXPECT_EQ(responseFuture.getRequestCode(), MQRequestCode::QUERY_BROKER_OFFSET); - EXPECT_EQ(responseFuture.getOpaque(), 4); - EXPECT_EQ(responseFuture.getTimeoutMillis(), 1000); - EXPECT_FALSE(responseFuture.isSendRequestOK()); + EXPECT_EQ(responseFuture.request_code(), MQRequestCode::QUERY_BROKER_OFFSET); + EXPECT_EQ(responseFuture.opaque(), 4); + EXPECT_EQ(responseFuture.timeout_millis(), 1000); + EXPECT_FALSE(responseFuture.send_request_ok()); EXPECT_FALSE(responseFuture.hasInvokeCallback()); // ~ResponseFuture delete callback @@ -56,8 +56,8 @@ TEST(ResponseFutureTest, Init) { TEST(ResponseFutureTest, Info) { ResponseFuture responseFuture(MQRequestCode::QUERY_BROKER_OFFSET, 4, 1000); - responseFuture.setSendRequestOK(true); - EXPECT_TRUE(responseFuture.isSendRequestOK()); + responseFuture.set_send_request_ok(true); + EXPECT_TRUE(responseFuture.send_request_ok()); } TEST(ResponseFutureTest, Response) { From 793d13ae2b9266e2c413edd0540637f89dee8ba2 Mon Sep 17 00:00:00 2001 From: James Yin Date: Wed, 29 Jul 2020 19:46:12 +0800 Subject: [PATCH 17/62] style: rename accessors and mutators --- example/AsyncProducer.cpp | 16 +-- example/BatchProducer.cpp | 19 ++- example/OrderlyProducer.cpp | 19 ++- example/OrderlyPushConsumer.cpp | 16 +-- example/PullConsumer.cpp | 4 +- example/PushConsumer.cpp | 16 +-- example/RequestReply.cpp | 26 ++-- example/SendDelayMsg.cpp | 12 +- example/SyncProducer.cpp | 19 ++- example/TransactionProducer.cpp | 21 ++- example/common.h | 2 +- include/DefaultMQProducer.h | 4 +- include/DefaultMQProducerConfig.h | 32 ++--- include/DefaultMQProducerConfigProxy.h | 64 ++++----- include/DefaultMQPushConsumerConfig.h | 40 +++--- include/DefaultMQPushConsumerConfigProxy.h | 80 +++++------ include/MQClientConfig.h | 31 ++-- include/MQClientConfigProxy.h | 53 +++---- include/MQMessage.h | 44 +++--- include/MQMessageExt.h | 56 ++++---- include/Message.h | 55 +++---- include/MessageExt.h | 56 ++++---- include/QueryResult.h | 12 +- include/SendResult.h | 19 ++- include/SessionCredentials.h | 22 +-- include/TransactionSendResult.h | 4 +- src/ClientRemotingProcessor.cpp | 24 ++-- src/MQClientAPIImpl.cpp | 18 +-- src/MQClientConfigImpl.hpp | 47 +++--- src/MQClientInstance.cpp | 2 +- src/common/ClientRPCHook.cpp | 10 +- src/common/SendCallbackWrap.cpp | 2 +- src/common/Validators.cpp | 4 +- .../ConsumeMessageConcurrentlyService.cpp | 8 +- src/consumer/ConsumeMessageOrderlyService.cpp | 4 +- src/consumer/DefaultMQPullConsumer.cpp | 4 +- src/consumer/DefaultMQPushConsumer.cpp | 4 +- .../DefaultMQPushConsumerConfigImpl.hpp | 46 +++--- src/consumer/DefaultMQPushConsumerImpl.cpp | 112 +++++++-------- src/consumer/ProcessQueue.cpp | 10 +- src/consumer/PullAPIWrapper.cpp | 4 +- src/consumer/RebalancePushImpl.cpp | 4 +- src/extern/CMessage.cpp | 24 ++-- src/extern/CMessageExt.cpp | 28 ++-- src/extern/CProducer.cpp | 56 ++++---- src/extern/CPullConsumer.cpp | 6 +- src/extern/CPushConsumer.cpp | 18 +-- src/message/MQMessage.cpp | 88 ++++++------ src/message/MQMessageExt.cpp | 112 +++++++-------- src/message/MessageAccessor.hpp | 2 +- src/message/MessageBatch.cpp | 14 +- src/message/MessageDecoder.cpp | 44 +++--- src/message/MessageExtImpl.cpp | 74 +++++----- src/message/MessageExtImpl.h | 70 ++++----- src/message/MessageImpl.cpp | 88 ++++++------ src/message/MessageImpl.h | 44 +++--- src/producer/DefaultMQProducer.cpp | 10 +- src/producer/DefaultMQProducerConfigImpl.hpp | 28 ++-- src/producer/DefaultMQProducerImpl.cpp | 135 +++++++++--------- test/src/common/ClientRPCHookTest.cpp | 6 +- test/src/extern/CMessageExtTest.cpp | 56 ++++---- test/src/extern/CMessageTest.cpp | 16 +-- test/src/extern/CProducerTest.cpp | 14 +- test/src/extern/CPullConsumerTest.cpp | 8 +- test/src/extern/CPushConsumerTest.cpp | 10 +- test/src/message/MQMessageExtTest.cpp | 108 +++++++------- test/src/message/MQMessageTest.cpp | 124 ++++++++-------- test/src/message/MessageDecoderTest.cpp | 46 +++--- 68 files changed, 1133 insertions(+), 1141 deletions(-) diff --git a/example/AsyncProducer.cpp b/example/AsyncProducer.cpp index 9a5ea4521..cee48edae 100644 --- a/example/AsyncProducer.cpp +++ b/example/AsyncProducer.cpp @@ -71,14 +71,14 @@ int main(int argc, char* argv[]) { PrintRocketmqSendAndConsumerArgs(info); auto* producer = new DefaultMQProducer(info.groupname); - producer->setNamesrvAddr(info.namesrv); - producer->setGroupName(info.groupname); - producer->setSendMsgTimeout(3000); - producer->setRetryTimes(info.retrytimes); - producer->setRetryTimesForAsync(info.retrytimes); - producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker); - producer->setTcpTransportTryLockTimeout(1000); - producer->setTcpTransportConnectTimeout(400); + producer->set_namesrv_addr(info.namesrv); + producer->set_group_name(info.groupname); + producer->set_send_msg_timeout(3000); + producer->set_retry_times(info.retrytimes); + producer->set_retry_times_for_async(info.retrytimes); + producer->set_send_latency_fault_enable(!info.selectUnactiveBroker); + producer->set_tcp_transport_try_lock_timeout(1000); + producer->set_tcp_transport_connect_timeout(400); producer->start(); std::vector> work_pool; diff --git a/example/BatchProducer.cpp b/example/BatchProducer.cpp index 68883e3e3..c417ded4a 100644 --- a/example/BatchProducer.cpp +++ b/example/BatchProducer.cpp @@ -46,8 +46,7 @@ void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* pr auto duration = std::chrono::duration_cast(end - start); if (duration.count() >= 500) { - std::cout << "send RT more than: " << duration.count() << "ms with msgid: " << sendResult.getMsgId() - << std::endl; + std::cout << "send RT more than: " << duration.count() << "ms with msgid: " << sendResult.msg_id() << std::endl; } } catch (const MQException& e) { std::cout << "send failed: " << e.what() << std::endl; @@ -63,14 +62,14 @@ int main(int argc, char* argv[]) { PrintRocketmqSendAndConsumerArgs(info); auto* producer = new DefaultMQProducer(info.groupname); - producer->setNamesrvAddr(info.namesrv); - producer->setGroupName(info.groupname); - producer->setSendMsgTimeout(3000); - producer->setRetryTimes(info.retrytimes); - producer->setRetryTimesForAsync(info.retrytimes); - producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker); - producer->setTcpTransportTryLockTimeout(1000); - producer->setTcpTransportConnectTimeout(400); + producer->set_namesrv_addr(info.namesrv); + producer->set_group_name(info.groupname); + producer->set_send_msg_timeout(3000); + producer->set_retry_times(info.retrytimes); + producer->set_retry_times_for_async(info.retrytimes); + producer->set_send_latency_fault_enable(!info.selectUnactiveBroker); + producer->set_tcp_transport_try_lock_timeout(1000); + producer->set_tcp_transport_connect_timeout(400); producer->start(); std::vector> work_pool; diff --git a/example/OrderlyProducer.cpp b/example/OrderlyProducer.cpp index 45538ba40..5c555ee2f 100644 --- a/example/OrderlyProducer.cpp +++ b/example/OrderlyProducer.cpp @@ -47,8 +47,7 @@ void ProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* produc auto duration = std::chrono::duration_cast(end - start); if (duration.count() >= 500) { - std::cout << "send RT more than: " << duration.count() << "ms with msgid: " << sendResult.getMsgId() - << std::endl; + std::cout << "send RT more than: " << duration.count() << "ms with msgid: " << sendResult.msg_id() << std::endl; } } catch (const MQException& e) { std::cout << "send failed: " << e.what() << std::endl; @@ -64,14 +63,14 @@ int main(int argc, char* argv[]) { PrintRocketmqSendAndConsumerArgs(info); auto* producer = new DefaultMQProducer(info.groupname); - producer->setNamesrvAddr(info.namesrv); - producer->setGroupName(info.groupname); - producer->setSendMsgTimeout(3000); - producer->setRetryTimes(info.retrytimes); - producer->setRetryTimesForAsync(info.retrytimes); - producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker); - producer->setTcpTransportTryLockTimeout(1000); - producer->setTcpTransportConnectTimeout(400); + producer->set_namesrv_addr(info.namesrv); + producer->set_group_name(info.groupname); + producer->set_send_msg_timeout(3000); + producer->set_retry_times(info.retrytimes); + producer->set_retry_times_for_async(info.retrytimes); + producer->set_send_latency_fault_enable(!info.selectUnactiveBroker); + producer->set_tcp_transport_try_lock_timeout(1000); + producer->set_tcp_transport_connect_timeout(400); producer->start(); std::vector> work_pool; diff --git a/example/OrderlyPushConsumer.cpp b/example/OrderlyPushConsumer.cpp index 02887c6e9..5f2454ff1 100644 --- a/example/OrderlyPushConsumer.cpp +++ b/example/OrderlyPushConsumer.cpp @@ -33,7 +33,7 @@ class MyMsgListener : public MessageListenerOrderly { if (old > 0) { for (size_t i = 0; i < msgs.size(); ++i) { g_tps.Increment(); - std::cout << msgs[i].getMsgId() << ", body: " << msgs[i].getBody() << std::endl; + std::cout << msgs[i].msg_id() << ", body: " << msgs[i].body() << std::endl; } if (old <= msgs.size()) { g_finished.count_down(); @@ -53,13 +53,13 @@ int main(int argc, char* argv[]) { PrintRocketmqSendAndConsumerArgs(info); auto* consumer = new DefaultMQPushConsumer(info.groupname); - consumer->setNamesrvAddr(info.namesrv); - consumer->setGroupName(info.groupname); - consumer->setTcpTransportTryLockTimeout(1000); - consumer->setTcpTransportConnectTimeout(400); - consumer->setConsumeThreadNum(info.thread_count); - consumer->setConsumeMessageBatchMaxSize(31); - consumer->setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET); + consumer->set_namesrv_addr(info.namesrv); + consumer->set_group_name(info.groupname); + consumer->set_tcp_transport_try_lock_timeout(1000); + consumer->set_tcp_transport_connect_timeout(400); + consumer->set_consume_thread_nums(info.thread_count); + consumer->set_consume_message_batch_max_size(31); + consumer->set_consume_from_where(CONSUME_FROM_LAST_OFFSET); consumer->subscribe(info.topic, "*"); MyMsgListener msglistener; diff --git a/example/PullConsumer.cpp b/example/PullConsumer.cpp index f37620177..a05b38310 100644 --- a/example/PullConsumer.cpp +++ b/example/PullConsumer.cpp @@ -49,8 +49,8 @@ int main(int argc, char* argv[]) { } PrintRocketmqSendAndConsumerArgs(info); DefaultMQPullConsumer consumer("please_rename_unique_group_name"); - consumer.setNamesrvAddr(info.namesrv); - consumer.setGroupName(info.groupname); + consumer.set_namesrv_addr(info.namesrv); + consumer.set_group_name(info.groupname); consumer.registerMessageQueueListener(info.topic, NULL); consumer.start(); std::vector mqs; diff --git a/example/PushConsumer.cpp b/example/PushConsumer.cpp index ff9c055b5..f44ac95d7 100644 --- a/example/PushConsumer.cpp +++ b/example/PushConsumer.cpp @@ -36,7 +36,7 @@ class MyMsgListener : public MessageListenerConcurrently { if (msgs[i] == nullptr) { std::cout << "error!!!" << std::endl; } else { - std::cout << msgs[i].getMsgId() << ", body: " << msgs[i].getBody() << std::endl; + std::cout << msgs[i].msg_id() << ", body: " << msgs[i].body() << std::endl; } } if (old <= msgs.size()) { @@ -57,15 +57,15 @@ int main(int argc, char* argv[]) { PrintRocketmqSendAndConsumerArgs(info); auto* consumer = new DefaultMQPushConsumer(info.groupname); - consumer->setNamesrvAddr(info.namesrv); - consumer->setGroupName(info.groupname); - consumer->setTcpTransportTryLockTimeout(1000); - consumer->setTcpTransportConnectTimeout(400); - consumer->setConsumeThreadNum(info.thread_count); - consumer->setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET); + consumer->set_namesrv_addr(info.namesrv); + consumer->set_group_name(info.groupname); + consumer->set_tcp_transport_try_lock_timeout(1000); + consumer->set_tcp_transport_connect_timeout(400); + consumer->set_consume_thread_nums(info.thread_count); + consumer->set_consume_from_where(CONSUME_FROM_LAST_OFFSET); if (info.broadcasting) { - consumer->setMessageModel(BROADCASTING); + consumer->set_message_model(BROADCASTING); } consumer->subscribe(info.topic, "*"); diff --git a/example/RequestReply.cpp b/example/RequestReply.cpp index 656418382..79b4212e9 100644 --- a/example/RequestReply.cpp +++ b/example/RequestReply.cpp @@ -60,24 +60,24 @@ int main(int argc, char* argv[]) { PrintRocketmqSendAndConsumerArgs(info); DefaultMQProducer producer(""); - producer.setNamesrvAddr(info.namesrv); - producer.setSendMsgTimeout(3000); - producer.setRetryTimes(info.retrytimes); - producer.setRetryTimesForAsync(info.retrytimes); - producer.setSendLatencyFaultEnable(!info.selectUnactiveBroker); - producer.setTcpTransportTryLockTimeout(1000); - producer.setTcpTransportConnectTimeout(400); + producer.set_namesrv_addr(info.namesrv); + producer.set_send_msg_timeout(3000); + producer.set_retry_times(info.retrytimes); + producer.set_retry_times_for_async(info.retrytimes); + producer.set_send_latency_fault_enable(!info.selectUnactiveBroker); + producer.set_tcp_transport_try_lock_timeout(1000); + producer.set_tcp_transport_connect_timeout(400); producer.start(); DefaultMQPushConsumer consumer(info.groupname); - consumer.setNamesrvAddr(info.namesrv); - consumer.setTcpTransportTryLockTimeout(1000); - consumer.setTcpTransportConnectTimeout(400); - consumer.setConsumeThreadNum(info.thread_count); - consumer.setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET); + consumer.set_namesrv_addr(info.namesrv); + consumer.set_tcp_transport_try_lock_timeout(1000); + consumer.set_tcp_transport_connect_timeout(400); + consumer.set_consume_thread_nums(info.thread_count); + consumer.set_consume_from_where(CONSUME_FROM_LAST_OFFSET); // recommend client configs - consumer.setPullTimeDelayMillsWhenException(0L); + consumer.set_pull_time_delay_mills_when_exception(0L); consumer.subscribe(info.topic, "*"); diff --git a/example/SendDelayMsg.cpp b/example/SendDelayMsg.cpp index dd0ba7281..34742b45d 100644 --- a/example/SendDelayMsg.cpp +++ b/example/SendDelayMsg.cpp @@ -27,11 +27,11 @@ int main(int argc, char* argv[]) { PrintRocketmqSendAndConsumerArgs(info); auto* producer = new DefaultMQProducer(info.groupname); - producer->setNamesrvAddr(info.namesrv); - producer->setGroupName(info.groupname); - producer->setSendMsgTimeout(3000); - producer->setTcpTransportTryLockTimeout(1000); - producer->setTcpTransportConnectTimeout(400); + producer->set_namesrv_addr(info.namesrv); + producer->set_group_name(info.groupname); + producer->set_send_msg_timeout(3000); + producer->set_tcp_transport_try_lock_timeout(1000); + producer->set_tcp_transport_connect_timeout(400); producer->start(); MQMessage msg(info.topic, // topic @@ -39,7 +39,7 @@ int main(int argc, char* argv[]) { info.body); // body // messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h - msg.setDelayTimeLevel(5); // 1m + msg.set_delay_time_level(5); // 1m try { SendResult sendResult = producer->send(msg); } catch (const MQException& e) { diff --git a/example/SyncProducer.cpp b/example/SyncProducer.cpp index 69461ee99..1668ea51a 100644 --- a/example/SyncProducer.cpp +++ b/example/SyncProducer.cpp @@ -35,8 +35,7 @@ void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* pr auto duration = std::chrono::duration_cast(end - start); if (duration.count() >= 500) { - std::cout << "send RT more than: " << duration.count() << "ms with msgid: " << sendResult.getMsgId() - << std::endl; + std::cout << "send RT more than: " << duration.count() << "ms with msgid: " << sendResult.msg_id() << std::endl; } } catch (const MQException& e) { std::cout << "send failed: " << e.what() << std::endl; @@ -52,14 +51,14 @@ int main(int argc, char* argv[]) { PrintRocketmqSendAndConsumerArgs(info); auto* producer = new DefaultMQProducer(info.groupname); - producer->setNamesrvAddr(info.namesrv); - producer->setGroupName(info.groupname); - producer->setSendMsgTimeout(3000); - producer->setRetryTimes(info.retrytimes); - producer->setRetryTimesForAsync(info.retrytimes); - producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker); - producer->setTcpTransportTryLockTimeout(1000); - producer->setTcpTransportConnectTimeout(400); + producer->set_namesrv_addr(info.namesrv); + producer->set_group_name(info.groupname); + producer->set_send_msg_timeout(3000); + producer->set_retry_times(info.retrytimes); + producer->set_retry_times_for_async(info.retrytimes); + producer->set_send_latency_fault_enable(!info.selectUnactiveBroker); + producer->set_tcp_transport_try_lock_timeout(1000); + producer->set_tcp_transport_connect_timeout(400); producer->start(); std::vector> work_pool; diff --git a/example/TransactionProducer.cpp b/example/TransactionProducer.cpp index ac2e2864a..30b948254 100644 --- a/example/TransactionProducer.cpp +++ b/example/TransactionProducer.cpp @@ -24,7 +24,7 @@ TpsReportService g_tps; class MyTransactionListener : public TransactionListener { virtual LocalTransactionState executeLocalTransaction(const MQMessage& msg, void* arg) { LocalTransactionState state = (LocalTransactionState)(((intptr_t)arg) % 3); - std::cout << "executeLocalTransaction transactionId:" << msg.getTransactionId() << ", return state: " << state + std::cout << "executeLocalTransaction transactionId:" << msg.transaction_id() << ", return state: " << state << std::endl; return state; } @@ -51,8 +51,7 @@ void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, TransactionMQProducer auto duration = std::chrono::duration_cast(end - start); if (duration.count() >= 500) { - std::cout << "send RT more than: " << duration.count() << "ms with msgid: " << sendResult.getMsgId() - << std::endl; + std::cout << "send RT more than: " << duration.count() << "ms with msgid: " << sendResult.msg_id() << std::endl; } } catch (const MQException& e) { std::cout << "send failed: " << e.what() << std::endl; @@ -69,14 +68,14 @@ int main(int argc, char* argv[]) { PrintRocketmqSendAndConsumerArgs(info); auto* producer = new TransactionMQProducer(info.groupname); - producer->setNamesrvAddr(info.namesrv); - producer->setGroupName(info.groupname); - producer->setSendMsgTimeout(3000); - producer->setRetryTimes(info.retrytimes); - producer->setRetryTimesForAsync(info.retrytimes); - producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker); - producer->setTcpTransportTryLockTimeout(1000); - producer->setTcpTransportConnectTimeout(400); + producer->set_namesrv_addr(info.namesrv); + producer->set_group_name(info.groupname); + producer->set_send_msg_timeout(3000); + producer->set_retry_times(info.retrytimes); + producer->set_retry_times_for_async(info.retrytimes); + producer->set_send_latency_fault_enable(!info.selectUnactiveBroker); + producer->set_tcp_transport_try_lock_timeout(1000); + producer->set_tcp_transport_connect_timeout(400); MyTransactionListener myListener; producer->setTransactionListener(&myListener); diff --git a/example/common.h b/example/common.h index e3435add6..4834987a8 100644 --- a/example/common.h +++ b/example/common.h @@ -103,7 +103,7 @@ class TpsReportService { /* static void PrintResult(rocketmq::SendResult* result) { - std::cout << "sendresult = " << result->getSendStatus() + std::cout << "sendresult = " << result->send_status() << ", msgid = " << result->getMsgId() << ", queueOffset = " << result->getQueueOffset() << "," << result->getMessageQueue().toString() << endl; diff --git a/include/DefaultMQProducer.h b/include/DefaultMQProducer.h index 6405d6475..ec5e5dfca 100644 --- a/include/DefaultMQProducer.h +++ b/include/DefaultMQProducer.h @@ -88,8 +88,8 @@ class ROCKETMQCLIENT_API DefaultMQProducer : public DefaultMQProducerConfigProxy long timeout) override; public: // DefaultMQProducerConfig - bool isSendLatencyFaultEnable() const override; - void setSendLatencyFaultEnable(bool sendLatencyFaultEnable) override; + bool send_latency_fault_enable() const override; + void set_send_latency_fault_enable(bool sendLatencyFaultEnable) override; public: void setRPCHook(RPCHookPtr rpcHook); diff --git a/include/DefaultMQProducerConfig.h b/include/DefaultMQProducerConfig.h index dcee17af8..46f9c2f86 100644 --- a/include/DefaultMQProducerConfig.h +++ b/include/DefaultMQProducerConfig.h @@ -33,35 +33,35 @@ class ROCKETMQCLIENT_API DefaultMQProducerConfig : virtual public MQClientConfig virtual ~DefaultMQProducerConfig() = default; // if msgbody size larger than maxMsgBodySize, exception will be throwed - virtual int getMaxMessageSize() const = 0; - virtual void setMaxMessageSize(int maxMessageSize) = 0; + virtual int max_message_size() const = 0; + virtual void set_max_message_size(int maxMessageSize) = 0; /* * if msgBody size is large than m_compressMsgBodyOverHowmuch * rocketmq cpp will compress msgBody according to compressLevel */ - virtual int getCompressMsgBodyOverHowmuch() const = 0; - virtual void setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch) = 0; + virtual int compress_msg_body_over_howmuch() const = 0; + virtual void set_compress_msg_body_over_howmuch(int compressMsgBodyOverHowmuch) = 0; - virtual int getCompressLevel() const = 0; - virtual void setCompressLevel(int compressLevel) = 0; + virtual int compress_level() const = 0; + virtual void set_compress_level(int compressLevel) = 0; // set and get timeout of per msg - virtual int getSendMsgTimeout() const = 0; - virtual void setSendMsgTimeout(int sendMsgTimeout) = 0; + virtual int send_msg_timeout() const = 0; + virtual void set_send_msg_timeout(int sendMsgTimeout) = 0; // set msg max retry times, default retry times is 5 - virtual int getRetryTimes() const = 0; - virtual void setRetryTimes(int times) = 0; + virtual int retry_times() const = 0; + virtual void set_retry_times(int times) = 0; - virtual int getRetryTimesForAsync() const = 0; - virtual void setRetryTimesForAsync(int times) = 0; + virtual int retry_times_for_async() const = 0; + virtual void set_retry_times_for_async(int times) = 0; - virtual bool isRetryAnotherBrokerWhenNotStoreOK() const = 0; - virtual void setRetryAnotherBrokerWhenNotStoreOK(bool retryAnotherBrokerWhenNotStoreOK) = 0; + virtual bool retry_another_broker_when_not_store_ok() const = 0; + virtual void set_retry_another_broker_when_not_store_ok(bool retryAnotherBrokerWhenNotStoreOK) = 0; - virtual bool isSendLatencyFaultEnable() const { return false; }; - virtual void setSendLatencyFaultEnable(bool sendLatencyFaultEnable){}; + virtual bool send_latency_fault_enable() const { return false; }; + virtual void set_send_latency_fault_enable(bool sendLatencyFaultEnable){}; }; } // namespace rocketmq diff --git a/include/DefaultMQProducerConfigProxy.h b/include/DefaultMQProducerConfigProxy.h index deeb87945..b879b43f6 100644 --- a/include/DefaultMQProducerConfigProxy.h +++ b/include/DefaultMQProducerConfigProxy.h @@ -32,70 +32,70 @@ class ROCKETMQCLIENT_API DefaultMQProducerConfigProxy : public MQClientConfigPro DefaultMQProducerConfigProxy(DefaultMQProducerConfigPtr producerConfig) : MQClientConfigProxy(producerConfig) {} virtual ~DefaultMQProducerConfigProxy() = default; - inline int getMaxMessageSize() const override { - return dynamic_cast(client_config_.get())->getMaxMessageSize(); + int max_message_size() const override { + return dynamic_cast(client_config_.get())->max_message_size(); } - inline void setMaxMessageSize(int maxMessageSize) override { - dynamic_cast(client_config_.get())->setMaxMessageSize(maxMessageSize); + void set_max_message_size(int maxMessageSize) override { + dynamic_cast(client_config_.get())->set_max_message_size(maxMessageSize); } - inline int getCompressMsgBodyOverHowmuch() const override { - return dynamic_cast(client_config_.get())->getCompressMsgBodyOverHowmuch(); + int compress_msg_body_over_howmuch() const override { + return dynamic_cast(client_config_.get())->compress_msg_body_over_howmuch(); } - inline void setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch) override { + void set_compress_msg_body_over_howmuch(int compressMsgBodyOverHowmuch) override { dynamic_cast(client_config_.get()) - ->setCompressMsgBodyOverHowmuch(compressMsgBodyOverHowmuch); + ->set_compress_msg_body_over_howmuch(compressMsgBodyOverHowmuch); } - inline int getCompressLevel() const override { - return dynamic_cast(client_config_.get())->getCompressLevel(); + int compress_level() const override { + return dynamic_cast(client_config_.get())->compress_level(); } - inline void setCompressLevel(int compressLevel) override { - dynamic_cast(client_config_.get())->setCompressLevel(compressLevel); + void set_compress_level(int compressLevel) override { + dynamic_cast(client_config_.get())->set_compress_level(compressLevel); } - inline int getSendMsgTimeout() const override { - return dynamic_cast(client_config_.get())->getSendMsgTimeout(); + int send_msg_timeout() const override { + return dynamic_cast(client_config_.get())->send_msg_timeout(); } - inline void setSendMsgTimeout(int sendMsgTimeout) override { - dynamic_cast(client_config_.get())->setSendMsgTimeout(sendMsgTimeout); + void set_send_msg_timeout(int sendMsgTimeout) override { + dynamic_cast(client_config_.get())->set_send_msg_timeout(sendMsgTimeout); } - inline int getRetryTimes() const override { - return dynamic_cast(client_config_.get())->getRetryTimes(); + int retry_times() const override { + return dynamic_cast(client_config_.get())->retry_times(); } - inline void setRetryTimes(int times) override { - dynamic_cast(client_config_.get())->setRetryTimes(times); + void set_retry_times(int times) override { + dynamic_cast(client_config_.get())->set_retry_times(times); } - inline int getRetryTimesForAsync() const override { - return dynamic_cast(client_config_.get())->getRetryTimesForAsync(); + int retry_times_for_async() const override { + return dynamic_cast(client_config_.get())->retry_times_for_async(); } - inline void setRetryTimesForAsync(int times) override { - dynamic_cast(client_config_.get())->setRetryTimesForAsync(times); + void set_retry_times_for_async(int times) override { + dynamic_cast(client_config_.get())->set_retry_times_for_async(times); } - inline bool isRetryAnotherBrokerWhenNotStoreOK() const override { - return dynamic_cast(client_config_.get())->isRetryAnotherBrokerWhenNotStoreOK(); + bool retry_another_broker_when_not_store_ok() const override { + return dynamic_cast(client_config_.get())->retry_another_broker_when_not_store_ok(); } - inline void setRetryAnotherBrokerWhenNotStoreOK(bool retryAnotherBrokerWhenNotStoreOK) override { + void set_retry_another_broker_when_not_store_ok(bool retryAnotherBrokerWhenNotStoreOK) override { dynamic_cast(client_config_.get()) - ->setRetryAnotherBrokerWhenNotStoreOK(retryAnotherBrokerWhenNotStoreOK); + ->set_retry_another_broker_when_not_store_ok(retryAnotherBrokerWhenNotStoreOK); } - inline bool isSendLatencyFaultEnable() const override { - return dynamic_cast(client_config_.get())->isSendLatencyFaultEnable(); + bool send_latency_fault_enable() const override { + return dynamic_cast(client_config_.get())->send_latency_fault_enable(); } - inline void setSendLatencyFaultEnable(bool sendLatencyFaultEnable) override { - dynamic_cast(client_config_.get())->setSendLatencyFaultEnable(sendLatencyFaultEnable); + void set_send_latency_fault_enable(bool sendLatencyFaultEnable) override { + dynamic_cast(client_config_.get())->set_send_latency_fault_enable(sendLatencyFaultEnable); } inline DefaultMQProducerConfigPtr real_config() const { diff --git a/include/DefaultMQPushConsumerConfig.h b/include/DefaultMQPushConsumerConfig.h index c15400744..ee3988e97 100644 --- a/include/DefaultMQPushConsumerConfig.h +++ b/include/DefaultMQPushConsumerConfig.h @@ -34,45 +34,45 @@ class ROCKETMQCLIENT_API DefaultMQPushConsumerConfig : virtual public MQClientCo public: virtual ~DefaultMQPushConsumerConfig() = default; - virtual MessageModel getMessageModel() const = 0; - virtual void setMessageModel(MessageModel messageModel) = 0; + virtual MessageModel message_model() const = 0; + virtual void set_message_model(MessageModel messageModel) = 0; - virtual ConsumeFromWhere getConsumeFromWhere() const = 0; - virtual void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) = 0; + virtual ConsumeFromWhere consume_from_where() const = 0; + virtual void set_consume_from_where(ConsumeFromWhere consumeFromWhere) = 0; - virtual const std::string& getConsumeTimestamp() const = 0; - virtual void setConsumeTimestamp(const std::string& consumeTimestamp) = 0; + virtual const std::string& consume_timestamp() const = 0; + virtual void set_consume_timestamp(const std::string& consumeTimestamp) = 0; /** * consuming thread count, default value is cpu cores */ - virtual int getConsumeThreadNum() const = 0; - virtual void setConsumeThreadNum(int threadNum) = 0; + virtual int consume_thread_nums() const = 0; + virtual void set_consume_thread_nums(int threadNum) = 0; /** * the pull number of message size by each pullMsg for orderly consume, default value is 1 */ - virtual int getConsumeMessageBatchMaxSize() const = 0; - virtual void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) = 0; + virtual int consume_message_batch_max_size() const = 0; + virtual void set_consume_message_batch_max_size(int consumeMessageBatchMaxSize) = 0; /** * max cache msg size per Queue in memory if consumer could not consume msgs immediately, * default maxCacheMsgSize per Queue is 1000, set range is:1~65535 */ - virtual int getMaxCacheMsgSizePerQueue() const = 0; - virtual void setMaxCacheMsgSizePerQueue(int maxCacheSize) = 0; + virtual int max_cache_msg_size_per_queue() const = 0; + virtual void set_max_cache_msg_size_per_queue(int maxCacheSize) = 0; - virtual int getAsyncPullTimeout() const = 0; - virtual void setAsyncPullTimeout(int asyncPullTimeout) = 0; + virtual int async_pull_timeout() const = 0; + virtual void set_async_pull_timeout(int asyncPullTimeout) = 0; - virtual int getMaxReconsumeTimes() const = 0; - virtual void setMaxReconsumeTimes(int maxReconsumeTimes) = 0; + virtual int max_reconsume_times() const = 0; + virtual void set_max_reconsume_times(int maxReconsumeTimes) = 0; - virtual long getPullTimeDelayMillsWhenException() const = 0; - virtual void setPullTimeDelayMillsWhenException(long pullTimeDelayMillsWhenException) = 0; + virtual long pull_time_delay_mills_when_exception() const = 0; + virtual void set_pull_time_delay_mills_when_exception(long pullTimeDelayMillsWhenException) = 0; - virtual AllocateMQStrategy* getAllocateMQStrategy() const = 0; - virtual void setAllocateMQStrategy(AllocateMQStrategy* strategy) = 0; + virtual AllocateMQStrategy* allocate_mq_strategy() const = 0; + virtual void set_allocate_mq_strategy(AllocateMQStrategy* strategy) = 0; }; } // namespace rocketmq diff --git a/include/DefaultMQPushConsumerConfigProxy.h b/include/DefaultMQPushConsumerConfigProxy.h index 3ff22b311..4a0c22fcc 100644 --- a/include/DefaultMQPushConsumerConfigProxy.h +++ b/include/DefaultMQPushConsumerConfigProxy.h @@ -30,86 +30,86 @@ class ROCKETMQCLIENT_API DefaultMQPushConsumerConfigProxy : public MQClientConfi : MQClientConfigProxy(consumerConfig) {} virtual ~DefaultMQPushConsumerConfigProxy() = default; - inline MessageModel getMessageModel() const override { - return dynamic_cast(client_config_.get())->getMessageModel(); + MessageModel message_model() const override { + return dynamic_cast(client_config_.get())->message_model(); } - inline void setMessageModel(MessageModel messageModel) override { - dynamic_cast(client_config_.get())->setMessageModel(messageModel); + void set_message_model(MessageModel messageModel) override { + dynamic_cast(client_config_.get())->set_message_model(messageModel); } - inline ConsumeFromWhere getConsumeFromWhere() const override { - return dynamic_cast(client_config_.get())->getConsumeFromWhere(); + ConsumeFromWhere consume_from_where() const override { + return dynamic_cast(client_config_.get())->consume_from_where(); } - inline void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) override { - dynamic_cast(client_config_.get())->setConsumeFromWhere(consumeFromWhere); + void set_consume_from_where(ConsumeFromWhere consumeFromWhere) override { + dynamic_cast(client_config_.get())->set_consume_from_where(consumeFromWhere); } - inline const std::string& getConsumeTimestamp() const override { - return dynamic_cast(client_config_.get())->getConsumeTimestamp(); + const std::string& consume_timestamp() const override { + return dynamic_cast(client_config_.get())->consume_timestamp(); } - inline void setConsumeTimestamp(const std::string& consumeTimestamp) override { - dynamic_cast(client_config_.get())->setConsumeTimestamp(consumeTimestamp); + void set_consume_timestamp(const std::string& consumeTimestamp) override { + dynamic_cast(client_config_.get())->set_consume_timestamp(consumeTimestamp); } - inline int getConsumeThreadNum() const override { - return dynamic_cast(client_config_.get())->getConsumeThreadNum(); + int consume_thread_nums() const override { + return dynamic_cast(client_config_.get())->consume_thread_nums(); } - inline void setConsumeThreadNum(int threadNum) override { - dynamic_cast(client_config_.get())->setConsumeThreadNum(threadNum); + void set_consume_thread_nums(int threadNum) override { + dynamic_cast(client_config_.get())->set_consume_thread_nums(threadNum); } - inline int getConsumeMessageBatchMaxSize() const override { - return dynamic_cast(client_config_.get())->getConsumeMessageBatchMaxSize(); + int consume_message_batch_max_size() const override { + return dynamic_cast(client_config_.get())->consume_message_batch_max_size(); } - inline void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) override { + void set_consume_message_batch_max_size(int consumeMessageBatchMaxSize) override { dynamic_cast(client_config_.get()) - ->setConsumeMessageBatchMaxSize(consumeMessageBatchMaxSize); + ->set_consume_message_batch_max_size(consumeMessageBatchMaxSize); } - inline int getMaxCacheMsgSizePerQueue() const override { - return dynamic_cast(client_config_.get())->getMaxCacheMsgSizePerQueue(); + int max_cache_msg_size_per_queue() const override { + return dynamic_cast(client_config_.get())->max_cache_msg_size_per_queue(); } - inline void setMaxCacheMsgSizePerQueue(int maxCacheSize) override { - dynamic_cast(client_config_.get())->setMaxCacheMsgSizePerQueue(maxCacheSize); + void set_max_cache_msg_size_per_queue(int maxCacheSize) override { + dynamic_cast(client_config_.get())->set_max_cache_msg_size_per_queue(maxCacheSize); } - inline int getAsyncPullTimeout() const override { - return dynamic_cast(client_config_.get())->getAsyncPullTimeout(); + int async_pull_timeout() const override { + return dynamic_cast(client_config_.get())->async_pull_timeout(); } - inline void setAsyncPullTimeout(int asyncPullTimeout) override { - dynamic_cast(client_config_.get())->setAsyncPullTimeout(asyncPullTimeout); + void set_async_pull_timeout(int asyncPullTimeout) override { + dynamic_cast(client_config_.get())->set_async_pull_timeout(asyncPullTimeout); } - inline int getMaxReconsumeTimes() const override { - return dynamic_cast(client_config_.get())->getMaxReconsumeTimes(); + int max_reconsume_times() const override { + return dynamic_cast(client_config_.get())->max_reconsume_times(); } - inline void setMaxReconsumeTimes(int maxReconsumeTimes) override { - dynamic_cast(client_config_.get())->setMaxReconsumeTimes(maxReconsumeTimes); + void set_max_reconsume_times(int maxReconsumeTimes) override { + dynamic_cast(client_config_.get())->set_max_reconsume_times(maxReconsumeTimes); } - inline long getPullTimeDelayMillsWhenException() const override { - return dynamic_cast(client_config_.get())->getPullTimeDelayMillsWhenException(); + long pull_time_delay_mills_when_exception() const override { + return dynamic_cast(client_config_.get())->pull_time_delay_mills_when_exception(); } - inline void setPullTimeDelayMillsWhenException(long pullTimeDelayMillsWhenException) override { + void set_pull_time_delay_mills_when_exception(long pullTimeDelayMillsWhenException) override { dynamic_cast(client_config_.get()) - ->setPullTimeDelayMillsWhenException(pullTimeDelayMillsWhenException); + ->set_pull_time_delay_mills_when_exception(pullTimeDelayMillsWhenException); } - inline AllocateMQStrategy* getAllocateMQStrategy() const override { - return dynamic_cast(client_config_.get())->getAllocateMQStrategy(); + AllocateMQStrategy* allocate_mq_strategy() const override { + return dynamic_cast(client_config_.get())->allocate_mq_strategy(); } - inline void setAllocateMQStrategy(AllocateMQStrategy* strategy) override { - dynamic_cast(client_config_.get())->setAllocateMQStrategy(strategy); + void set_allocate_mq_strategy(AllocateMQStrategy* strategy) override { + dynamic_cast(client_config_.get())->set_allocate_mq_strategy(strategy); } inline DefaultMQPushConsumerConfigPtr real_config() const { diff --git a/include/MQClientConfig.h b/include/MQClientConfig.h index c93dd2b18..ade13f01f 100644 --- a/include/MQClientConfig.h +++ b/include/MQClientConfig.h @@ -37,37 +37,38 @@ class ROCKETMQCLIENT_API MQClientConfig { // clientId = clientIP @ processId [ @ unitName ] virtual std::string buildMQClientId() const = 0; - virtual const std::string& getGroupName() const = 0; - virtual void setGroupName(const std::string& groupname) = 0; + virtual void changeInstanceNameToPID() = 0; - virtual const std::string& getNamesrvAddr() const = 0; - virtual void setNamesrvAddr(const std::string& namesrvAddr) = 0; + public: + virtual const std::string& group_name() const = 0; + virtual void set_group_name(const std::string& groupname) = 0; - virtual const std::string& getInstanceName() const = 0; - virtual void setInstanceName(const std::string& instanceName) = 0; + virtual const std::string& namesrv_addr() const = 0; + virtual void set_namesrv_addr(const std::string& namesrvAddr) = 0; - virtual void changeInstanceNameToPID() = 0; + virtual const std::string& instance_name() const = 0; + virtual void set_instance_name(const std::string& instanceName) = 0; - virtual const std::string& getUnitName() const = 0; - virtual void setUnitName(std::string unitName) = 0; + virtual const std::string& unit_name() const = 0; + virtual void set_unit_name(std::string unitName) = 0; /** * the num of threads to distribute network data **/ - virtual int getTcpTransportWorkerThreadNum() const = 0; - virtual void setTcpTransportWorkerThreadNum(int num) = 0; + virtual int tcp_transport_worker_thread_nums() const = 0; + virtual void set_tcp_transport_worker_thread_nums(int num) = 0; /** * timeout of tcp connect **/ - virtual uint64_t getTcpTransportConnectTimeout() const = 0; - virtual void setTcpTransportConnectTimeout(uint64_t timeout) = 0; // ms + virtual uint64_t tcp_transport_connect_timeout() const = 0; + virtual void set_tcp_transport_connect_timeout(uint64_t timeout) = 0; // ms /** * timeout of tryLock tcpTransport, the minimun value is 1000ms **/ - virtual uint64_t getTcpTransportTryLockTimeout() const = 0; - virtual void setTcpTransportTryLockTimeout(uint64_t timeout) = 0; // ms + virtual uint64_t tcp_transport_try_lock_timeout() const = 0; + virtual void set_tcp_transport_try_lock_timeout(uint64_t timeout) = 0; // ms }; } // namespace rocketmq diff --git a/include/MQClientConfigProxy.h b/include/MQClientConfigProxy.h index 2e3b33235..8cea1bbc8 100644 --- a/include/MQClientConfigProxy.h +++ b/include/MQClientConfigProxy.h @@ -30,48 +30,35 @@ class ROCKETMQCLIENT_API MQClientConfigProxy : virtual public MQClientConfig // MQClientConfigProxy(MQClientConfigPtr clientConfig) : client_config_(clientConfig) {} virtual ~MQClientConfigProxy() = default; - inline std::string buildMQClientId() const override { return client_config_->buildMQClientId(); } + std::string buildMQClientId() const override { return client_config_->buildMQClientId(); } + void changeInstanceNameToPID() override { client_config_->changeInstanceNameToPID(); } - inline const std::string& getGroupName() const override { return client_config_->getGroupName(); } - - inline void setGroupName(const std::string& groupname) override { client_config_->setGroupName(groupname); } - - inline const std::string& getNamesrvAddr() const override { return client_config_->getNamesrvAddr(); } - - inline void setNamesrvAddr(const std::string& namesrvAddr) override { client_config_->setNamesrvAddr(namesrvAddr); } - - inline const std::string& getInstanceName() const override { return client_config_->getInstanceName(); } - - inline void setInstanceName(const std::string& instanceName) override { - client_config_->setInstanceName(instanceName); - } - - inline void changeInstanceNameToPID() override { client_config_->changeInstanceNameToPID(); } - - inline const std::string& getUnitName() const override { return client_config_->getUnitName(); } - - inline void setUnitName(std::string unitName) override { client_config_->setUnitName(unitName); } + public: + const std::string& group_name() const override { return client_config_->group_name(); } + void set_group_name(const std::string& groupname) override { client_config_->set_group_name(groupname); } - inline int getTcpTransportWorkerThreadNum() const override { - return client_config_->getTcpTransportWorkerThreadNum(); - } + const std::string& namesrv_addr() const override { return client_config_->namesrv_addr(); } + void set_namesrv_addr(const std::string& namesrvAddr) override { client_config_->set_namesrv_addr(namesrvAddr); } - inline void setTcpTransportWorkerThreadNum(int num) override { client_config_->setTcpTransportWorkerThreadNum(num); } + const std::string& instance_name() const override { return client_config_->instance_name(); } + void set_instance_name(const std::string& instanceName) override { client_config_->set_instance_name(instanceName); } - inline uint64_t getTcpTransportConnectTimeout() const override { - return client_config_->getTcpTransportConnectTimeout(); - } + const std::string& unit_name() const override { return client_config_->unit_name(); } + void set_unit_name(std::string unitName) override { client_config_->set_unit_name(unitName); } - inline void setTcpTransportConnectTimeout(uint64_t timeout) override { - client_config_->setTcpTransportConnectTimeout(timeout); + int tcp_transport_worker_thread_nums() const override { return client_config_->tcp_transport_worker_thread_nums(); } + void set_tcp_transport_worker_thread_nums(int num) override { + client_config_->set_tcp_transport_worker_thread_nums(num); } - inline uint64_t getTcpTransportTryLockTimeout() const override { - return client_config_->getTcpTransportTryLockTimeout(); + uint64_t tcp_transport_connect_timeout() const override { return client_config_->tcp_transport_connect_timeout(); } + void set_tcp_transport_connect_timeout(uint64_t timeout) override { + client_config_->set_tcp_transport_connect_timeout(timeout); } - inline void setTcpTransportTryLockTimeout(uint64_t timeout) override { - client_config_->setTcpTransportTryLockTimeout(timeout); + uint64_t tcp_transport_try_lock_timeout() const override { return client_config_->tcp_transport_try_lock_timeout(); } + void set_tcp_transport_try_lock_timeout(uint64_t timeout) override { + client_config_->set_tcp_transport_try_lock_timeout(timeout); } inline MQClientConfigPtr real_config() const { return client_config_; } diff --git a/include/MQMessage.h b/include/MQMessage.h index c0786a726..84c4cbd2b 100644 --- a/include/MQMessage.h +++ b/include/MQMessage.h @@ -71,36 +71,36 @@ class ROCKETMQCLIENT_API MQMessage : virtual public Message // interface void putProperty(const std::string& name, const std::string& value) override; void clearProperty(const std::string& name) override; - const std::string& getTopic() const override; - void setTopic(const std::string& topic) override; - void setTopic(const char* body, int len) override; + const std::string& topic() const override; + void set_topic(const std::string& topic) override; + void set_topic(const char* body, int len) override; - const std::string& getTags() const override; - void setTags(const std::string& tags) override; + const std::string& tags() const override; + void set_tags(const std::string& tags) override; - const std::string& getKeys() const override; - void setKeys(const std::string& keys) override; - void setKeys(const std::vector& keys) override; + const std::string& keys() const override; + void set_keys(const std::string& keys) override; + void set_keys(const std::vector& keys) override; - int getDelayTimeLevel() const override; - void setDelayTimeLevel(int level) override; + int delay_time_level() const override; + void set_delay_time_level(int level) override; - bool isWaitStoreMsgOK() const override; - void setWaitStoreMsgOK(bool waitStoreMsgOK) override; + bool wait_store_msg_ok() const override; + void set_wait_store_msg_ok(bool waitStoreMsgOK) override; - int32_t getFlag() const override; - void setFlag(int32_t flag) override; + int32_t flag() const override; + void set_flag(int32_t flag) override; - const std::string& getBody() const override; - void setBody(const std::string& body) override; - void setBody(std::string&& body) override; + const std::string& body() const override; + void set_body(const std::string& body) override; + void set_body(std::string&& body) override; - const std::string& getTransactionId() const override; - void setTransactionId(const std::string& transactionId) override; + const std::string& transaction_id() const override; + void set_transaction_id(const std::string& transactionId) override; - const std::map& getProperties() const override; - void setProperties(const std::map& properties) override; - void setProperties(std::map&& properties) override; + const std::map& properties() const override; + void set_properties(const std::map& properties) override; + void set_properties(std::map&& properties) override; bool isBatch() const override; diff --git a/include/MQMessageExt.h b/include/MQMessageExt.h index 8d499179e..d00ea94b1 100644 --- a/include/MQMessageExt.h +++ b/include/MQMessageExt.h @@ -57,46 +57,46 @@ class ROCKETMQCLIENT_API MQMessageExt : public MQMessage, // base virtual ~MQMessageExt(); public: // MessageExt - int32_t getStoreSize() const override; - void setStoreSize(int32_t storeSize) override; + int32_t store_size() const override; + void set_store_size(int32_t storeSize) override; - int32_t getBodyCRC() const override; - void setBodyCRC(int32_t bodyCRC) override; + int32_t body_crc() const override; + void set_body_crc(int32_t bodyCRC) override; - int32_t getQueueId() const override; - void setQueueId(int32_t queueId) override; + int32_t queue_id() const override; + void set_queue_id(int32_t queueId) override; - int64_t getQueueOffset() const override; - void setQueueOffset(int64_t queueOffset) override; + int64_t queue_offset() const override; + void set_queue_offset(int64_t queueOffset) override; - int64_t getCommitLogOffset() const override; - void setCommitLogOffset(int64_t physicOffset) override; + int64_t commit_log_offset() const override; + void set_commit_log_offset(int64_t physicOffset) override; - int32_t getSysFlag() const override; - void setSysFlag(int32_t sysFlag) override; + int32_t sys_flag() const override; + void set_sys_flag(int32_t sysFlag) override; - int64_t getBornTimestamp() const override; - void setBornTimestamp(int64_t bornTimestamp) override; + int64_t born_timestamp() const override; + void set_born_timestamp(int64_t bornTimestamp) override; - std::string getBornHostString() const override; - const struct sockaddr* getBornHost() const override; - void setBornHost(const struct sockaddr* bornHost) override; + std::string born_host_string() const override; + const struct sockaddr* born_host() const override; + void set_born_host(const struct sockaddr* bornHost) override; - int64_t getStoreTimestamp() const override; - void setStoreTimestamp(int64_t storeTimestamp) override; + int64_t store_timestamp() const override; + void set_store_timestamp(int64_t storeTimestamp) override; - std::string getStoreHostString() const override; - const struct sockaddr* getStoreHost() const override; - void setStoreHost(const struct sockaddr* storeHost) override; + std::string store_host_string() const override; + const struct sockaddr* store_host() const override; + void set_store_host(const struct sockaddr* storeHost) override; - int32_t getReconsumeTimes() const override; - void setReconsumeTimes(int32_t reconsumeTimes) override; + int32_t reconsume_times() const override; + void set_reconsume_times(int32_t reconsumeTimes) override; - int64_t getPreparedTransactionOffset() const override; - void setPreparedTransactionOffset(int64_t preparedTransactionOffset) override; + int64_t prepared_transaction_offset() const override; + void set_prepared_transaction_offset(int64_t preparedTransactionOffset) override; - const std::string& getMsgId() const override; - void setMsgId(const std::string& msgId) override; + const std::string& msg_id() const override; + void set_msg_id(const std::string& msgId) override; }; } // namespace rocketmq diff --git a/include/Message.h b/include/Message.h index fe6bd3cef..9a778ac17 100644 --- a/include/Message.h +++ b/include/Message.h @@ -37,50 +37,51 @@ class ROCKETMQCLIENT_API Message { virtual ~Message() = default; public: - // property - virtual const std::string& getProperty(const std::string& name) const = 0; - virtual void putProperty(const std::string& name, const std::string& value) = 0; - virtual void clearProperty(const std::string& name) = 0; - // topic - virtual const std::string& getTopic() const = 0; - virtual void setTopic(const std::string& topic) = 0; - virtual void setTopic(const char* body, int len) = 0; + virtual const std::string& topic() const = 0; + virtual void set_topic(const std::string& topic) = 0; + virtual void set_topic(const char* topic, int len) = 0; // tags - virtual const std::string& getTags() const = 0; - virtual void setTags(const std::string& tags) = 0; + virtual const std::string& tags() const = 0; + virtual void set_tags(const std::string& tags) = 0; // keys - virtual const std::string& getKeys() const = 0; - virtual void setKeys(const std::string& keys) = 0; - virtual void setKeys(const std::vector& keys) = 0; + virtual const std::string& keys() const = 0; + virtual void set_keys(const std::string& keys) = 0; + virtual void set_keys(const std::vector& keys) = 0; // delay time level - virtual int getDelayTimeLevel() const = 0; - virtual void setDelayTimeLevel(int level) = 0; + virtual int delay_time_level() const = 0; + virtual void set_delay_time_level(int level) = 0; // wait store message ok - virtual bool isWaitStoreMsgOK() const = 0; - virtual void setWaitStoreMsgOK(bool waitStoreMsgOK) = 0; + virtual bool wait_store_msg_ok() const = 0; + virtual void set_wait_store_msg_ok(bool waitStoreMsgOK) = 0; // flag - virtual int32_t getFlag() const = 0; - virtual void setFlag(int32_t flag) = 0; + virtual int32_t flag() const = 0; + virtual void set_flag(int32_t flag) = 0; // body - virtual const std::string& getBody() const = 0; - virtual void setBody(const std::string& body) = 0; - virtual void setBody(std::string&& body) = 0; + virtual const std::string& body() const = 0; + virtual void set_body(const std::string& body) = 0; + virtual void set_body(std::string&& body) = 0; // transaction id - virtual const std::string& getTransactionId() const = 0; - virtual void setTransactionId(const std::string& transactionId) = 0; + virtual const std::string& transaction_id() const = 0; + virtual void set_transaction_id(const std::string& transactionId) = 0; // properties - virtual const std::map& getProperties() const = 0; - virtual void setProperties(const std::map& properties) = 0; - virtual void setProperties(std::map&& properties) = 0; + virtual const std::map& properties() const = 0; + virtual void set_properties(const std::map& properties) = 0; + virtual void set_properties(std::map&& properties) = 0; + + public: + // property + virtual const std::string& getProperty(const std::string& name) const = 0; + virtual void putProperty(const std::string& name, const std::string& value) = 0; + virtual void clearProperty(const std::string& name) = 0; // batch flag virtual bool isBatch() const { return false; } diff --git a/include/MessageExt.h b/include/MessageExt.h index 44b37a854..61ae1476a 100644 --- a/include/MessageExt.h +++ b/include/MessageExt.h @@ -41,46 +41,46 @@ class ROCKETMQCLIENT_API MessageExt : virtual public Message // base interface public: virtual ~MessageExt() = default; - virtual int32_t getStoreSize() const = 0; - virtual void setStoreSize(int32_t storeSize) = 0; + virtual int32_t store_size() const = 0; + virtual void set_store_size(int32_t storeSize) = 0; - virtual int32_t getBodyCRC() const = 0; - virtual void setBodyCRC(int32_t bodyCRC) = 0; + virtual int32_t body_crc() const = 0; + virtual void set_body_crc(int32_t bodyCRC) = 0; - virtual int32_t getQueueId() const = 0; - virtual void setQueueId(int32_t queueId) = 0; + virtual int32_t queue_id() const = 0; + virtual void set_queue_id(int32_t queueId) = 0; - virtual int64_t getQueueOffset() const = 0; - virtual void setQueueOffset(int64_t queueOffset) = 0; + virtual int64_t queue_offset() const = 0; + virtual void set_queue_offset(int64_t queueOffset) = 0; - virtual int64_t getCommitLogOffset() const = 0; - virtual void setCommitLogOffset(int64_t physicOffset) = 0; + virtual int64_t commit_log_offset() const = 0; + virtual void set_commit_log_offset(int64_t physicOffset) = 0; - virtual int32_t getSysFlag() const = 0; - virtual void setSysFlag(int32_t sysFlag) = 0; + virtual int32_t sys_flag() const = 0; + virtual void set_sys_flag(int32_t sysFlag) = 0; - virtual int64_t getBornTimestamp() const = 0; - virtual void setBornTimestamp(int64_t bornTimestamp) = 0; + virtual int64_t born_timestamp() const = 0; + virtual void set_born_timestamp(int64_t bornTimestamp) = 0; - virtual std::string getBornHostString() const = 0; - virtual const struct sockaddr* getBornHost() const = 0; - virtual void setBornHost(const struct sockaddr* bornHost) = 0; + virtual std::string born_host_string() const = 0; + virtual const struct sockaddr* born_host() const = 0; + virtual void set_born_host(const struct sockaddr* bornHost) = 0; - virtual int64_t getStoreTimestamp() const = 0; - virtual void setStoreTimestamp(int64_t storeTimestamp) = 0; + virtual int64_t store_timestamp() const = 0; + virtual void set_store_timestamp(int64_t storeTimestamp) = 0; - virtual std::string getStoreHostString() const = 0; - virtual const struct sockaddr* getStoreHost() const = 0; - virtual void setStoreHost(const struct sockaddr* storeHost) = 0; + virtual std::string store_host_string() const = 0; + virtual const struct sockaddr* store_host() const = 0; + virtual void set_store_host(const struct sockaddr* storeHost) = 0; - virtual int32_t getReconsumeTimes() const = 0; - virtual void setReconsumeTimes(int32_t reconsumeTimes) = 0; + virtual int32_t reconsume_times() const = 0; + virtual void set_reconsume_times(int32_t reconsumeTimes) = 0; - virtual int64_t getPreparedTransactionOffset() const = 0; - virtual void setPreparedTransactionOffset(int64_t preparedTransactionOffset) = 0; + virtual int64_t prepared_transaction_offset() const = 0; + virtual void set_prepared_transaction_offset(int64_t preparedTransactionOffset) = 0; - virtual const std::string& getMsgId() const = 0; - virtual void setMsgId(const std::string& msgId) = 0; + virtual const std::string& msg_id() const = 0; + virtual void set_msg_id(const std::string& msgId) = 0; }; } // namespace rocketmq diff --git a/include/QueryResult.h b/include/QueryResult.h index b24d9e0d1..0482f3e1a 100644 --- a/include/QueryResult.h +++ b/include/QueryResult.h @@ -24,17 +24,17 @@ namespace rocketmq { class ROCKETMQCLIENT_API QueryResult { public: QueryResult(uint64_t indexLastUpdateTimestamp, const std::vector& messageList) { - m_indexLastUpdateTimestamp = indexLastUpdateTimestamp; - m_messageList = messageList; + index_last_update_timestamp_ = indexLastUpdateTimestamp; + message_list_ = messageList; } - uint64_t getIndexLastUpdateTimestamp() { return m_indexLastUpdateTimestamp; } + uint64_t index_last_update_timestamp() { return index_last_update_timestamp_; } - std::vector& getMessageList() { return m_messageList; } + std::vector& message_list() { return message_list_; } private: - uint64_t m_indexLastUpdateTimestamp; - std::vector m_messageList; + uint64_t index_last_update_timestamp_; + std::vector message_list_; }; } // namespace rocketmq diff --git a/include/SendResult.h b/include/SendResult.h index 918822224..f7ec17120 100644 --- a/include/SendResult.h +++ b/include/SendResult.h @@ -60,18 +60,23 @@ class ROCKETMQCLIENT_API SendResult { virtual ~SendResult() = default; - inline SendStatus getSendStatus() const { return send_status_; } + inline SendStatus send_status() const { return send_status_; } + inline void send_status(SendStatus send_status) { send_status_ = send_status; } - inline const std::string& getMsgId() const { return msg_id_; } + inline const std::string& msg_id() const { return msg_id_; } + inline void msg_id(const std::string& msg_id) { msg_id_ = msg_id; } - inline const std::string& getOffsetMsgId() const { return offset_msg_id_; } + inline const std::string& offset_msg_id() const { return offset_msg_id_; } + inline void offset_msg_id(std::string& offset_msg_id) { offset_msg_id_ = offset_msg_id; } - inline const MQMessageQueue& getMessageQueue() const { return message_queue_; } + inline const MQMessageQueue& message_queue() const { return message_queue_; } + inline void message_queue(const MQMessageQueue& message_queue) { message_queue_ = message_queue; } - inline int64_t getQueueOffset() const { return queue_offset_; } + inline int64_t queue_offset() const { return queue_offset_; } + inline void set_queue_offset(int64_t queue_offset) { queue_offset_ = queue_offset; } - inline const std::string& getTransactionId() const { return transaction_id_; } - inline void setTransactionId(const std::string& id) { transaction_id_ = id; } + inline const std::string& transaction_id() const { return transaction_id_; } + inline void set_transaction_id(const std::string& id) { transaction_id_ = id; } std::string toString() const; diff --git a/include/SessionCredentials.h b/include/SessionCredentials.h index 2d03f2a9f..3146bf098 100644 --- a/include/SessionCredentials.h +++ b/include/SessionCredentials.h @@ -37,22 +37,22 @@ class ROCKETMQCLIENT_API SessionCredentials { ~SessionCredentials() = default; - inline const std::string& getAccessKey() const { return access_key_; } - inline void setAccessKey(const std::string& accessKey) { access_key_ = accessKey; } + bool isValid() const { return !access_key_.empty() && !secret_key_.empty() && !auth_channel_.empty(); } - inline const std::string& getSecretKey() const { return secret_key_; } - inline void setSecretKey(const std::string& secretKey) { secret_key_ = secretKey; } + inline const std::string& access_key() const { return access_key_; } + inline void set_access_key(const std::string& accessKey) { access_key_ = accessKey; } - inline const std::string& getSignature() const { return signature_; } - inline void setSignature(const std::string& signature) { signature_ = signature; } + inline const std::string& secret_key() const { return secret_key_; } + inline void set_secret_key(const std::string& secretKey) { secret_key_ = secretKey; } - inline const std::string& getSignatureMethod() const { return signature_method_; } - inline void setSignatureMethod(const std::string& signatureMethod) { signature_method_ = signatureMethod; } + inline const std::string& signature() const { return signature_; } + inline void set_signature(const std::string& signature) { signature_ = signature; } - inline const std::string& getAuthChannel() const { return auth_channel_; } - inline void setAuthChannel(const std::string& channel) { auth_channel_ = channel; } + inline const std::string& signature_method() const { return signature_method_; } + inline void set_signature_method(const std::string& signatureMethod) { signature_method_ = signatureMethod; } - bool isValid() const { return !access_key_.empty() && !secret_key_.empty() && !auth_channel_.empty(); } + inline const std::string& auth_channel() const { return auth_channel_; } + inline void set_auth_channel(const std::string& channel) { auth_channel_ = channel; } private: std::string access_key_; diff --git a/include/TransactionSendResult.h b/include/TransactionSendResult.h index 7219d16ba..b036cf335 100644 --- a/include/TransactionSendResult.h +++ b/include/TransactionSendResult.h @@ -27,9 +27,9 @@ class ROCKETMQCLIENT_API TransactionSendResult : public SendResult { public: TransactionSendResult(const SendResult& sendResult) : SendResult(sendResult), local_transaction_state_(UNKNOWN) {} - inline LocalTransactionState getLocalTransactionState() const { return local_transaction_state_; } + inline LocalTransactionState local_transaction_state() const { return local_transaction_state_; } - inline void setLocalTransactionState(LocalTransactionState localTransactionState) { + inline void set_local_transaction_state(LocalTransactionState localTransactionState) { local_transaction_state_ = localTransactionState; } diff --git a/src/ClientRemotingProcessor.cpp b/src/ClientRemotingProcessor.cpp index aa742ba85..518e4649b 100644 --- a/src/ClientRemotingProcessor.cpp +++ b/src/ClientRemotingProcessor.cpp @@ -70,7 +70,7 @@ RemotingCommand* ClientRemotingProcessor::checkTransactionState(const std::strin if (messageExt != nullptr) { const auto& transactionId = messageExt->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX); if (!transactionId.empty()) { - messageExt->setTransactionId(transactionId); + messageExt->set_transaction_id(transactionId); } const auto& group = messageExt->getProperty(MQMessageConst::PROPERTY_PRODUCER_GROUP); if (!group.empty()) { @@ -148,36 +148,36 @@ RemotingCommand* ClientRemotingProcessor::receiveReplyMessage(RemotingCommand* r try { std::unique_ptr msg(new MQMessageExt); - msg->setTopic(requestHeader->getTopic()); - msg->setQueueId(requestHeader->getQueueId()); - msg->setStoreTimestamp(requestHeader->getStoreTimestamp()); + msg->set_topic(requestHeader->getTopic()); + msg->set_queue_id(requestHeader->getQueueId()); + msg->set_store_timestamp(requestHeader->getStoreTimestamp()); if (!requestHeader->getBornHost().empty()) { - msg->setBornHost(string2SocketAddress(requestHeader->getBornHost())); + msg->set_born_host(string2SocketAddress(requestHeader->getBornHost())); } if (!requestHeader->getStoreHost().empty()) { - msg->setStoreHost(string2SocketAddress(requestHeader->getStoreHost())); + msg->set_store_host(string2SocketAddress(requestHeader->getStoreHost())); } auto body = request->body(); if ((requestHeader->getSysFlag() & MessageSysFlag::COMPRESSED_FLAG) == MessageSysFlag::COMPRESSED_FLAG) { std::string origin_body; if (UtilAll::inflate(*body, origin_body)) { - msg->setBody(std::move(origin_body)); + msg->set_body(std::move(origin_body)); } else { LOG_WARN_NEW("err when uncompress constant"); } } else { - msg->setBody(std::string(body->array(), body->size())); + msg->set_body(std::string(body->array(), body->size())); } - msg->setFlag(requestHeader->getFlag()); + msg->set_flag(requestHeader->getFlag()); MessageAccessor::setProperties(*msg, MessageDecoder::string2messageProperties(requestHeader->getProperties())); MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_REPLY_MESSAGE_ARRIVE_TIME, UtilAll::to_string(receiveTime)); - msg->setBornTimestamp(requestHeader->getBornTimestamp()); - msg->setReconsumeTimes(requestHeader->getReconsumeTimes()); + msg->set_born_timestamp(requestHeader->getBornTimestamp()); + msg->set_reconsume_times(requestHeader->getReconsumeTimes()); LOG_DEBUG_NEW("receive reply message:{}", msg->toString()); processReplyMessage(std::move(msg)); @@ -200,7 +200,7 @@ void ClientRemotingProcessor::processReplyMessage(std::unique_ptr requestResponseFuture->putResponseMessage(std::move(replyMsg)); requestResponseFuture->executeRequestCallback(); } else { - auto bornHost = replyMsg->getBornHostString(); + auto bornHost = replyMsg->born_host_string(); LOG_WARN_NEW("receive reply message, but not matched any request, CorrelationId: {} , reply from host: {}", correlationId, bornHost); } diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index 429ff1745..cb17dfdf3 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -34,9 +34,9 @@ namespace rocketmq { MQClientAPIImpl::MQClientAPIImpl(ClientRemotingProcessor* clientRemotingProcessor, RPCHookPtr rpcHook, const MQClientConfig& clientConfig) - : remoting_client_(new TcpRemotingClient(clientConfig.getTcpTransportWorkerThreadNum(), - clientConfig.getTcpTransportConnectTimeout(), - clientConfig.getTcpTransportTryLockTimeout())) { + : remoting_client_(new TcpRemotingClient(clientConfig.tcp_transport_worker_thread_nums(), + clientConfig.tcp_transport_connect_timeout(), + clientConfig.tcp_transport_try_lock_timeout())) { remoting_client_->registerRPCHook(rpcHook); remoting_client_->registerProcessor(CHECK_TRANSACTION_STATE, clientRemotingProcessor); remoting_client_->registerProcessor(NOTIFY_CONSUMER_IDS_CHANGED, clientRemotingProcessor); @@ -128,7 +128,7 @@ SendResult* MQClientAPIImpl::sendMessage(const std::string& addr, } RemotingCommand request(code, header.release()); - request.set_body(msg->getBody()); + request.set_body(msg->body()); switch (communicationMode) { case CommunicationMode::ONEWAY: @@ -212,7 +212,7 @@ SendResult* MQClientAPIImpl::processSendResponse(const std::string& brokerName, auto* responseHeader = response->decodeCommandCustomHeader(); assert(responseHeader != nullptr); - MQMessageQueue messageQueue(msg->getTopic(), brokerName, responseHeader->queueId); + MQMessageQueue messageQueue(msg->topic(), brokerName, responseHeader->queueId); std::string uniqMsgId = MessageClientIDSetter::getUniqID(*msg); @@ -232,7 +232,7 @@ SendResult* MQClientAPIImpl::processSendResponse(const std::string& brokerName, SendResult* sendResult = new SendResult(sendStatus, uniqMsgId, responseHeader->msgId, messageQueue, responseHeader->queueOffset); - sendResult->setTransactionId(responseHeader->transactionId); + sendResult->set_transaction_id(responseHeader->transactionId); return sendResult; } @@ -560,10 +560,10 @@ void MQClientAPIImpl::consumerSendMessageBack(const std::string& addr, int maxConsumeRetryTimes) { auto* requestHeader = new ConsumerSendMsgBackRequestHeader(); requestHeader->group = consumerGroup; - requestHeader->originTopic = msg->getTopic(); - requestHeader->offset = msg->getCommitLogOffset(); + requestHeader->originTopic = msg->topic(); + requestHeader->offset = msg->commit_log_offset(); requestHeader->delayLevel = delayLevel; - requestHeader->originMsgId = msg->getMsgId(); + requestHeader->originMsgId = msg->msg_id(); requestHeader->maxReconsumeTimes = maxConsumeRetryTimes; RemotingCommand request(CONSUMER_SEND_MSG_BACK, requestHeader); diff --git a/src/MQClientConfigImpl.hpp b/src/MQClientConfigImpl.hpp index 9eec2393e..c0aa341f0 100644 --- a/src/MQClientConfigImpl.hpp +++ b/src/MQClientConfigImpl.hpp @@ -33,7 +33,7 @@ class MQClientConfigImpl : virtual public MQClientConfig { public: MQClientConfigImpl() : instance_name_("DEFAULT"), - tcp_worker_thread_num_(std::min(4, (int)std::thread::hardware_concurrency())), + tcp_worker_thread_nums_(std::min(4, (int)std::thread::hardware_concurrency())), tcp_connect_timeout(3000), tcp_transport_try_lock_timeout_(3) { const char* addr = std::getenv(ROCKETMQ_NAMESRV_ADDR_ENV.c_str()); @@ -55,38 +55,39 @@ class MQClientConfigImpl : virtual public MQClientConfig { return clientId; } - const std::string& getGroupName() const override { return group_name_; } - void setGroupName(const std::string& groupname) override { group_name_ = groupname; } - - const std::string& getNamesrvAddr() const override { return namesrv_addr_; } - void setNamesrvAddr(const std::string& namesrvAddr) override { - namesrv_addr_ = NameSpaceUtil::formatNameServerURL(namesrvAddr); - } - - const std::string& getInstanceName() const override { return instance_name_; } - void setInstanceName(const std::string& instanceName) override { instance_name_ = instanceName; } - void changeInstanceNameToPID() override { if (instance_name_ == "DEFAULT") { instance_name_ = UtilAll::to_string(UtilAll::getProcessId()); } } - const std::string& getUnitName() const override { return unit_name_; } - void setUnitName(std::string unitName) override { unit_name_ = unitName; } + public: + const std::string& group_name() const override { return group_name_; } + void set_group_name(const std::string& groupname) override { group_name_ = groupname; } + + const std::string& namesrv_addr() const override { return namesrv_addr_; } + void set_namesrv_addr(const std::string& namesrvAddr) override { + namesrv_addr_ = NameSpaceUtil::formatNameServerURL(namesrvAddr); + } + + const std::string& instance_name() const override { return instance_name_; } + void set_instance_name(const std::string& instanceName) override { instance_name_ = instanceName; } + + const std::string& unit_name() const override { return unit_name_; } + void set_unit_name(std::string unitName) override { unit_name_ = unitName; } - int getTcpTransportWorkerThreadNum() const override { return tcp_worker_thread_num_; } - void setTcpTransportWorkerThreadNum(int num) override { - if (num > tcp_worker_thread_num_) { - tcp_worker_thread_num_ = num; + int tcp_transport_worker_thread_nums() const override { return tcp_worker_thread_nums_; } + void set_tcp_transport_worker_thread_nums(int num) override { + if (num > tcp_worker_thread_nums_) { + tcp_worker_thread_nums_ = num; } } - uint64_t getTcpTransportConnectTimeout() const override { return tcp_connect_timeout; } - void setTcpTransportConnectTimeout(uint64_t millisec) override { tcp_connect_timeout = millisec; } + uint64_t tcp_transport_connect_timeout() const override { return tcp_connect_timeout; } + void set_tcp_transport_connect_timeout(uint64_t millisec) override { tcp_connect_timeout = millisec; } - uint64_t getTcpTransportTryLockTimeout() const override { return tcp_transport_try_lock_timeout_; } - void setTcpTransportTryLockTimeout(uint64_t millisec) override { + uint64_t tcp_transport_try_lock_timeout() const override { return tcp_transport_try_lock_timeout_; } + void set_tcp_transport_try_lock_timeout(uint64_t millisec) override { tcp_transport_try_lock_timeout_ = std::max(1000, millisec) / 1000; } @@ -96,7 +97,7 @@ class MQClientConfigImpl : virtual public MQClientConfig { std::string group_name_; std::string unit_name_; - int tcp_worker_thread_num_; + int tcp_worker_thread_nums_; uint64_t tcp_connect_timeout; // ms uint64_t tcp_transport_try_lock_timeout_; // s }; diff --git a/src/MQClientInstance.cpp b/src/MQClientInstance.cpp index fa58bde71..f10f18891 100644 --- a/src/MQClientInstance.cpp +++ b/src/MQClientInstance.cpp @@ -53,7 +53,7 @@ MQClientInstance::MQClientInstance(const MQClientConfig& clientConfig, const std client_remoting_processor_.reset(new ClientRemotingProcessor(this)); mq_client_api_impl_.reset(new MQClientAPIImpl(client_remoting_processor_.get(), rpcHook, clientConfig)); - std::string namesrvAddr = clientConfig.getNamesrvAddr(); + std::string namesrvAddr = clientConfig.namesrv_addr(); if (!namesrvAddr.empty()) { mq_client_api_impl_->updateNameServerAddressList(namesrvAddr); LOG_INFO_NEW("user specified name server address: {}", namesrvAddr); diff --git a/src/common/ClientRPCHook.cpp b/src/common/ClientRPCHook.cpp index 5fcb47b7f..26f56bdfc 100644 --- a/src/common/ClientRPCHook.cpp +++ b/src/common/ClientRPCHook.cpp @@ -48,8 +48,8 @@ void ClientRPCHook::doAfterResponse(const std::string& remoteAddr, void ClientRPCHook::signCommand(RemotingCommand& command) { std::map headerMap; - headerMap.insert(std::make_pair(ACCESS_KEY, session_credentials_.getAccessKey())); - headerMap.insert(std::make_pair(ONS_CHANNEL_KEY, session_credentials_.getAuthChannel())); + headerMap.insert(std::make_pair(ACCESS_KEY, session_credentials_.access_key())); + headerMap.insert(std::make_pair(ONS_CHANNEL_KEY, session_credentials_.auth_channel())); LOG_DEBUG_NEW("before insert declared filed, MAP SIZE is:{}", headerMap.size()); auto* header = command.readCustomHeader(); @@ -70,12 +70,12 @@ void ClientRPCHook::signCommand(RemotingCommand& command) { LOG_DEBUG_NEW("total msg info are:{}, size is:{}", totalMsg, totalMsg.size()); char* sign = - rocketmqSignature::spas_sign(totalMsg.c_str(), totalMsg.size(), session_credentials_.getSecretKey().c_str()); + rocketmqSignature::spas_sign(totalMsg.c_str(), totalMsg.size(), session_credentials_.secret_key().c_str()); if (sign != nullptr) { std::string signature(static_cast(sign)); command.set_ext_field(SIGNATURE_KEY, signature); - command.set_ext_field(ACCESS_KEY, session_credentials_.getAccessKey()); - command.set_ext_field(ONS_CHANNEL_KEY, session_credentials_.getAuthChannel()); + command.set_ext_field(ACCESS_KEY, session_credentials_.access_key()); + command.set_ext_field(ONS_CHANNEL_KEY, session_credentials_.auth_channel()); rocketmqSignature::spas_mem_free(sign); } else { LOG_ERROR_NEW("signature for request failed"); diff --git a/src/common/SendCallbackWrap.cpp b/src/common/SendCallbackWrap.cpp index d7514c08f..8763be157 100755 --- a/src/common/SendCallbackWrap.cpp +++ b/src/common/SendCallbackWrap.cpp @@ -162,7 +162,7 @@ void SendCallbackWrap::onExceptionImpl(ResponseFuture* responseFuture, } } std::string addr = instance_->findBrokerAddressInPublish(retryBrokerName); - LOG_INFO_NEW("async send msg by retry {} times. topic={}, brokerAddr={}, brokerName={}", times_, msg_->getTopic(), + LOG_INFO_NEW("async send msg by retry {} times. topic={}, brokerAddr={}, brokerName={}", times_, msg_->topic(), addr, retryBrokerName); try { // new request diff --git a/src/common/Validators.cpp b/src/common/Validators.cpp index 22084eecd..d014f0e4d 100644 --- a/src/common/Validators.cpp +++ b/src/common/Validators.cpp @@ -97,9 +97,9 @@ void Validators::checkGroup(const std::string& group) { } void Validators::checkMessage(const Message& msg, int maxMessageSize) { - checkTopic(msg.getTopic()); + checkTopic(msg.topic()); - const auto& body = msg.getBody(); + const auto& body = msg.body(); if (body.empty()) { THROW_MQEXCEPTION(MQClientException, "the message body is empty", MESSAGE_ILLEGAL); } diff --git a/src/consumer/ConsumeMessageConcurrentlyService.cpp b/src/consumer/ConsumeMessageConcurrentlyService.cpp index 5c3c2f9d9..16d725bfb 100755 --- a/src/consumer/ConsumeMessageConcurrentlyService.cpp +++ b/src/consumer/ConsumeMessageConcurrentlyService.cpp @@ -65,7 +65,7 @@ void ConsumeMessageConcurrentlyService::ConsumeRequest(std::vectordropped()) { LOG_WARN_NEW("the message queue not be able to consume, because it's dropped. group={} {}", - consumer_->getDefaultMQPushConsumerConfig()->getGroupName(), messageQueue.toString()); + consumer_->getDefaultMQPushConsumerConfig()->group_name(), messageQueue.toString()); return; } @@ -76,7 +76,7 @@ void ConsumeMessageConcurrentlyService::ConsumeRequest(std::vectorresetRetryTopic( - msgs, consumer_->getDefaultMQPushConsumerConfig()->getGroupName()); // set where to sendMessageBack + msgs, consumer_->getDefaultMQPushConsumerConfig()->group_name()); // set where to sendMessageBack ConsumeStatus status = RECONSUME_LATER; try { @@ -132,11 +132,11 @@ void ConsumeMessageConcurrentlyService::ConsumeRequest(std::vectorgetMsgId(), idx, (*iter)->getReconsumeTimes()); + messageQueue.toString(), (*iter)->msg_id(), idx, (*iter)->reconsume_times()); auto& msg = (*iter); bool result = consumer_->sendMessageBack(msg, 0, messageQueue.broker_name()); if (!result) { - msg->setReconsumeTimes(msg->getReconsumeTimes() + 1); + msg->set_reconsume_times(msg->reconsume_times() + 1); msgBackFailed.push_back(msg); iter = msgs.erase(iter); } else { diff --git a/src/consumer/ConsumeMessageOrderlyService.cpp b/src/consumer/ConsumeMessageOrderlyService.cpp index 1a3698cd7..0dd2c16c6 100755 --- a/src/consumer/ConsumeMessageOrderlyService.cpp +++ b/src/consumer/ConsumeMessageOrderlyService.cpp @@ -144,11 +144,11 @@ void ConsumeMessageOrderlyService::ConsumeRequest(ProcessQueuePtr processQueue, break; } - const int consumeBatchSize = consumer_->getDefaultMQPushConsumerConfig()->getConsumeMessageBatchMaxSize(); + const int consumeBatchSize = consumer_->getDefaultMQPushConsumerConfig()->consume_message_batch_max_size(); std::vector msgs; processQueue->takeMessages(msgs, consumeBatchSize); - consumer_->resetRetryTopic(msgs, consumer_->getDefaultMQPushConsumerConfig()->getGroupName()); + consumer_->resetRetryTopic(msgs, consumer_->getDefaultMQPushConsumerConfig()->group_name()); if (!msgs.empty()) { ConsumeStatus status = RECONSUME_LATER; try { diff --git a/src/consumer/DefaultMQPullConsumer.cpp b/src/consumer/DefaultMQPullConsumer.cpp index 66d324e9e..166ed6913 100644 --- a/src/consumer/DefaultMQPullConsumer.cpp +++ b/src/consumer/DefaultMQPullConsumer.cpp @@ -27,9 +27,9 @@ DefaultMQPullConsumer::DefaultMQPullConsumer(const std::string& groupname, RPCHo : DefaultMQPullConsumerConfigProxy(nullptr), m_pullConsumerDelegate(nullptr) { // set default group name if (groupname.empty()) { - setGroupName(DEFAULT_CONSUMER_GROUP); + set_group_name(DEFAULT_CONSUMER_GROUP); } else { - setGroupName(groupname); + set_group_name(groupname); } // TODO: DefaultMQPullConsumerImpl diff --git a/src/consumer/DefaultMQPushConsumer.cpp b/src/consumer/DefaultMQPushConsumer.cpp index f5a80d9cf..894e9656a 100644 --- a/src/consumer/DefaultMQPushConsumer.cpp +++ b/src/consumer/DefaultMQPushConsumer.cpp @@ -30,9 +30,9 @@ DefaultMQPushConsumer::DefaultMQPushConsumer(const std::string& groupname, RPCHo push_consumer_impl_(nullptr) { // set default group name if (groupname.empty()) { - setGroupName(DEFAULT_CONSUMER_GROUP); + set_group_name(DEFAULT_CONSUMER_GROUP); } else { - setGroupName(groupname); + set_group_name(groupname); } // create DefaultMQPushConsumerImpl diff --git a/src/consumer/DefaultMQPushConsumerConfigImpl.hpp b/src/consumer/DefaultMQPushConsumerConfigImpl.hpp index 1b1f1eb07..e2ba06d13 100644 --- a/src/consumer/DefaultMQPushConsumerConfigImpl.hpp +++ b/src/consumer/DefaultMQPushConsumerConfigImpl.hpp @@ -36,7 +36,7 @@ class DefaultMQPushConsumerConfigImpl : virtual public DefaultMQPushConsumerConf : message_model_(MessageModel::CLUSTERING), consume_from_where_(ConsumeFromWhere::CONSUME_FROM_LAST_OFFSET), consume_timestamp_("0"), - consume_thread_num_(std::min(8, (int)std::thread::hardware_concurrency())), + consume_thread_nums_(std::min(8, (int)std::thread::hardware_concurrency())), consume_message_batch_max_size_(1), max_msg_cache_size_(1000), async_pull_timeout_(30 * 1000), @@ -45,49 +45,49 @@ class DefaultMQPushConsumerConfigImpl : virtual public DefaultMQPushConsumerConf allocate_mq_strategy_(new AllocateMQAveragely()) {} virtual ~DefaultMQPushConsumerConfigImpl() = default; - MessageModel getMessageModel() const override { return message_model_; } - void setMessageModel(MessageModel messageModel) override { message_model_ = messageModel; } + MessageModel message_model() const override { return message_model_; } + void set_message_model(MessageModel messageModel) override { message_model_ = messageModel; } - ConsumeFromWhere getConsumeFromWhere() const override { return consume_from_where_; } - void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) override { consume_from_where_ = consumeFromWhere; } + ConsumeFromWhere consume_from_where() const override { return consume_from_where_; } + void set_consume_from_where(ConsumeFromWhere consumeFromWhere) override { consume_from_where_ = consumeFromWhere; } - const std::string& getConsumeTimestamp() const override { return consume_timestamp_; } - void setConsumeTimestamp(const std::string& consumeTimestamp) override { consume_timestamp_ = consumeTimestamp; } + const std::string& consume_timestamp() const override { return consume_timestamp_; } + void set_consume_timestamp(const std::string& consumeTimestamp) override { consume_timestamp_ = consumeTimestamp; } - int getConsumeThreadNum() const override { return consume_thread_num_; } - void setConsumeThreadNum(int threadNum) override { + int consume_thread_nums() const override { return consume_thread_nums_; } + void set_consume_thread_nums(int threadNum) override { if (threadNum > 0) { - consume_thread_num_ = threadNum; + consume_thread_nums_ = threadNum; } } - int getConsumeMessageBatchMaxSize() const override { return consume_message_batch_max_size_; } - void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) override { + int consume_message_batch_max_size() const override { return consume_message_batch_max_size_; } + void set_consume_message_batch_max_size(int consumeMessageBatchMaxSize) override { if (consumeMessageBatchMaxSize >= 1) { consume_message_batch_max_size_ = consumeMessageBatchMaxSize; } } - int getMaxCacheMsgSizePerQueue() const override { return max_msg_cache_size_; } - void setMaxCacheMsgSizePerQueue(int maxCacheSize) override { + int max_cache_msg_size_per_queue() const override { return max_msg_cache_size_; } + void set_max_cache_msg_size_per_queue(int maxCacheSize) override { if (maxCacheSize > 0 && maxCacheSize < 65535) { max_msg_cache_size_ = maxCacheSize; } } - int getAsyncPullTimeout() const override { return async_pull_timeout_; } - void setAsyncPullTimeout(int asyncPullTimeout) override { async_pull_timeout_ = asyncPullTimeout; } + int async_pull_timeout() const override { return async_pull_timeout_; } + void set_async_pull_timeout(int asyncPullTimeout) override { async_pull_timeout_ = asyncPullTimeout; } - int getMaxReconsumeTimes() const override { return max_reconsume_times_; } - void setMaxReconsumeTimes(int maxReconsumeTimes) override { max_reconsume_times_ = maxReconsumeTimes; } + int max_reconsume_times() const override { return max_reconsume_times_; } + void set_max_reconsume_times(int maxReconsumeTimes) override { max_reconsume_times_ = maxReconsumeTimes; } - long getPullTimeDelayMillsWhenException() const override { return pull_time_delay_mills_when_exception_; } - void setPullTimeDelayMillsWhenException(long pullTimeDelayMillsWhenException) override { + long pull_time_delay_mills_when_exception() const override { return pull_time_delay_mills_when_exception_; } + void set_pull_time_delay_mills_when_exception(long pullTimeDelayMillsWhenException) override { pull_time_delay_mills_when_exception_ = pullTimeDelayMillsWhenException; } - AllocateMQStrategy* getAllocateMQStrategy() const override { return allocate_mq_strategy_.get(); } - void setAllocateMQStrategy(AllocateMQStrategy* strategy) override { allocate_mq_strategy_.reset(strategy); } + AllocateMQStrategy* allocate_mq_strategy() const override { return allocate_mq_strategy_.get(); } + void set_allocate_mq_strategy(AllocateMQStrategy* strategy) override { allocate_mq_strategy_.reset(strategy); } protected: MessageModel message_model_; @@ -95,7 +95,7 @@ class DefaultMQPushConsumerConfigImpl : virtual public DefaultMQPushConsumerConf ConsumeFromWhere consume_from_where_; std::string consume_timestamp_; - int consume_thread_num_; + int consume_thread_nums_; int consume_message_batch_max_size_; int max_msg_cache_size_; diff --git a/src/consumer/DefaultMQPushConsumerImpl.cpp b/src/consumer/DefaultMQPushConsumerImpl.cpp index 71097b2e1..de90889e5 100644 --- a/src/consumer/DefaultMQPushConsumerImpl.cpp +++ b/src/consumer/DefaultMQPushConsumerImpl.cpp @@ -69,7 +69,7 @@ class AsyncPullCallback : public AutoDeletePullCallback { if (result.msg_found_list().empty()) { defaultMQPushConsumer->executePullRequestImmediately(pull_request_); } else { - firstMsgOffset = result.msg_found_list()[0]->getQueueOffset(); + firstMsgOffset = result.msg_found_list()[0]->queue_offset(); pull_request_->process_queue()->putMessage(result.msg_found_list()); defaultMQPushConsumer->getConsumerMsgService()->submitConsumeRequest( @@ -96,7 +96,7 @@ class AsyncPullCallback : public AutoDeletePullCallback { defaultMQPushConsumer->correctTagsOffset(pull_request_); defaultMQPushConsumer->executePullRequestLater( pull_request_, - defaultMQPushConsumer->getDefaultMQPushConsumerConfig()->getPullTimeDelayMillsWhenException()); + defaultMQPushConsumer->getDefaultMQPushConsumerConfig()->pull_time_delay_mills_when_exception()); break; case OFFSET_ILLEGAL: { LOG_WARN_NEW("the pull request offset illegal, {} {}", pull_request_->toString(), result.toString()); @@ -139,7 +139,7 @@ class AsyncPullCallback : public AutoDeletePullCallback { // TODO defaultMQPushConsumer->executePullRequestLater( - pull_request_, defaultMQPushConsumer->getDefaultMQPushConsumerConfig()->getPullTimeDelayMillsWhenException()); + pull_request_, defaultMQPushConsumer->getDefaultMQPushConsumerConfig()->pull_time_delay_mills_when_exception()); } private: @@ -176,7 +176,7 @@ void DefaultMQPushConsumerImpl::start() { switch (service_state_) { case CREATE_JUST: { - LOG_INFO_NEW("the consumer [{}] start beginning.", client_config_->getGroupName()); + LOG_INFO_NEW("the consumer [{}] start beginning.", client_config_->group_name()); service_state_ = START_FAILED; @@ -192,59 +192,59 @@ void DefaultMQPushConsumerImpl::start() { MQClientImpl::start(); // init rebalance_impl_ - rebalance_impl_->set_consumer_group(client_config_->getGroupName()); + rebalance_impl_->set_consumer_group(client_config_->group_name()); rebalance_impl_->set_message_model( - dynamic_cast(client_config_.get())->getMessageModel()); + dynamic_cast(client_config_.get())->message_model()); rebalance_impl_->set_allocate_mq_strategy( - dynamic_cast(client_config_.get())->getAllocateMQStrategy()); + dynamic_cast(client_config_.get())->allocate_mq_strategy()); rebalance_impl_->set_client_instance(client_instance_.get()); // init pull_api_wrapper_ - pull_api_wrapper_.reset(new PullAPIWrapper(client_instance_.get(), client_config_->getGroupName())); + pull_api_wrapper_.reset(new PullAPIWrapper(client_instance_.get(), client_config_->group_name())); // TODO: registerFilterMessageHook // init offset_store_ - switch (dynamic_cast(client_config_.get())->getMessageModel()) { + switch (dynamic_cast(client_config_.get())->message_model()) { case MessageModel::BROADCASTING: - offset_store_.reset(new LocalFileOffsetStore(client_instance_.get(), client_config_->getGroupName())); + offset_store_.reset(new LocalFileOffsetStore(client_instance_.get(), client_config_->group_name())); break; case MessageModel::CLUSTERING: - offset_store_.reset(new RemoteBrokerOffsetStore(client_instance_.get(), client_config_->getGroupName())); + offset_store_.reset(new RemoteBrokerOffsetStore(client_instance_.get(), client_config_->group_name())); break; } offset_store_->load(); // checkConfig() guarantee message_listener_ is not nullptr if (message_listener_->getMessageListenerType() == messageListenerOrderly) { - LOG_INFO_NEW("start orderly consume service: {}", client_config_->getGroupName()); + LOG_INFO_NEW("start orderly consume service: {}", client_config_->group_name()); consume_orderly_ = true; consume_service_.reset(new ConsumeMessageOrderlyService( - this, dynamic_cast(client_config_.get())->getConsumeThreadNum(), + this, dynamic_cast(client_config_.get())->consume_thread_nums(), message_listener_)); } else { // for backward compatible, defaultly and concurrently listeners are allocating // ConsumeMessageConcurrentlyService - LOG_INFO_NEW("start concurrently consume service: {}", client_config_->getGroupName()); + LOG_INFO_NEW("start concurrently consume service: {}", client_config_->group_name()); consume_orderly_ = false; consume_service_.reset(new ConsumeMessageConcurrentlyService( - this, dynamic_cast(client_config_.get())->getConsumeThreadNum(), + this, dynamic_cast(client_config_.get())->consume_thread_nums(), message_listener_)); } consume_service_->start(); // register consumer - bool registerOK = client_instance_->registerConsumer(client_config_->getGroupName(), this); + bool registerOK = client_instance_->registerConsumer(client_config_->group_name(), this); if (!registerOK) { service_state_ = CREATE_JUST; consume_service_->shutdown(); - THROW_MQEXCEPTION(MQClientException, "The cousumer group[" + client_config_->getGroupName() + + THROW_MQEXCEPTION(MQClientException, "The cousumer group[" + client_config_->group_name() + "] has been created before, specify another name please.", -1); } client_instance_->start(); - LOG_INFO_NEW("the consumer [{}] start OK", client_config_->getGroupName()); + LOG_INFO_NEW("the consumer [{}] start OK", client_config_->group_name()); service_state_ = RUNNING; break; } @@ -263,7 +263,7 @@ void DefaultMQPushConsumerImpl::start() { } void DefaultMQPushConsumerImpl::checkConfig() { - std::string groupname = client_config_->getGroupName(); + std::string groupname = client_config_->group_name(); // check consumerGroup Validators::checkGroup(groupname); @@ -274,13 +274,13 @@ void DefaultMQPushConsumerImpl::checkConfig() { "consumerGroup can not equal " + DEFAULT_CONSUMER_GROUP + ", please specify another one.", -1); } - if (dynamic_cast(client_config_.get())->getMessageModel() != BROADCASTING && - dynamic_cast(client_config_.get())->getMessageModel() != CLUSTERING) { + if (dynamic_cast(client_config_.get())->message_model() != BROADCASTING && + dynamic_cast(client_config_.get())->message_model() != CLUSTERING) { THROW_MQEXCEPTION(MQClientException, "messageModel is valid", -1); } // allocateMessageQueueStrategy - if (nullptr == dynamic_cast(client_config_.get())->getAllocateMQStrategy()) { + if (nullptr == dynamic_cast(client_config_.get())->allocate_mq_strategy()) { THROW_MQEXCEPTION(MQClientException, "allocateMessageQueueStrategy is null", -1); } @@ -302,12 +302,12 @@ void DefaultMQPushConsumerImpl::copySubscription() { rebalance_impl_->setSubscriptionData(it.first, subscriptionData); } - switch (dynamic_cast(client_config_.get())->getMessageModel()) { + switch (dynamic_cast(client_config_.get())->message_model()) { case BROADCASTING: break; case CLUSTERING: { // auto subscript retry topic - std::string retryTopic = UtilAll::getRetryTopic(client_config_->getGroupName()); + std::string retryTopic = UtilAll::getRetryTopic(client_config_->group_name()); SubscriptionData* subscriptionData = FilterAPI::buildSubscriptionData(retryTopic, SUB_ALL); rebalance_impl_->setSubscriptionData(retryTopic, subscriptionData); break; @@ -333,9 +333,9 @@ void DefaultMQPushConsumerImpl::shutdown() { case RUNNING: { consume_service_->shutdown(); persistConsumerOffset(); - client_instance_->unregisterConsumer(client_config_->getGroupName()); + client_instance_->unregisterConsumer(client_config_->group_name()); client_instance_->shutdown(); - LOG_INFO_NEW("the consumer [{}] shutdown OK", client_config_->getGroupName()); + LOG_INFO_NEW("the consumer [{}] shutdown OK", client_config_->group_name()); rebalance_impl_->destroy(); service_state_ = SHUTDOWN_ALREADY; break; @@ -354,16 +354,16 @@ bool DefaultMQPushConsumerImpl::sendMessageBack(MessageExtPtr msg, int delayLeve bool DefaultMQPushConsumerImpl::sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) { try { - std::string brokerAddr = brokerName.empty() ? socketAddress2String(msg->getStoreHost()) + std::string brokerAddr = brokerName.empty() ? socketAddress2String(msg->store_host()) : client_instance_->findBrokerAddressInPublish(brokerName); client_instance_->getMQClientAPIImpl()->consumerSendMessageBack( - brokerAddr, msg, dynamic_cast(client_config_.get())->getGroupName(), delayLevel, + brokerAddr, msg, dynamic_cast(client_config_.get())->group_name(), delayLevel, 5000, getMaxReconsumeTimes()); return true; } catch (const std::exception& e) { LOG_ERROR_NEW("sendMessageBack exception, group: {}, msg: {}. {}", - dynamic_cast(client_config_.get())->getGroupName(), msg->toString(), + dynamic_cast(client_config_.get())->group_name(), msg->toString(), e.what()); } return false; @@ -404,13 +404,13 @@ void DefaultMQPushConsumerImpl::subscribe(const std::string& topic, const std::s void DefaultMQPushConsumerImpl::suspend() { pause_ = true; - LOG_INFO_NEW("suspend this consumer, {}", client_config_->getGroupName()); + LOG_INFO_NEW("suspend this consumer, {}", client_config_->group_name()); } void DefaultMQPushConsumerImpl::resume() { pause_ = false; doRebalance(); - LOG_INFO_NEW("resume this consumer, {}", client_config_->getGroupName()); + LOG_INFO_NEW("resume this consumer, {}", client_config_->group_name()); } void DefaultMQPushConsumerImpl::doRebalance() { @@ -422,7 +422,7 @@ void DefaultMQPushConsumerImpl::doRebalance() { void DefaultMQPushConsumerImpl::persistConsumerOffset() { if (isServiceStateOk()) { std::vector mqs = rebalance_impl_->getAllocatedMQ(); - if (dynamic_cast(client_config_.get())->getMessageModel() == BROADCASTING) { + if (dynamic_cast(client_config_.get())->message_model() == BROADCASTING) { offset_store_->persistAll(mqs); } else { for (const auto& mq : mqs) { @@ -478,7 +478,7 @@ void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pullRequest) { int cachedMessageCount = processQueue->getCacheMsgCount(); if (cachedMessageCount > - dynamic_cast(client_config_.get())->getMaxCacheMsgSizePerQueue()) { + dynamic_cast(client_config_.get())->max_cache_msg_size_per_queue()) { // too many message in cache, wait to process executePullRequestLater(pullRequest, 1000); return; @@ -505,7 +505,7 @@ void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pullRequest) { } else { executePullRequestLater( pullRequest, - dynamic_cast(client_config_.get())->getPullTimeDelayMillsWhenException()); + dynamic_cast(client_config_.get())->pull_time_delay_mills_when_exception()); LOG_INFO_NEW("pull message later because not locked in broker, {}", pullRequest->toString()); return; } @@ -516,14 +516,14 @@ void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pullRequest) { if (nullptr == subscriptionData) { executePullRequestLater( pullRequest, - dynamic_cast(client_config_.get())->getPullTimeDelayMillsWhenException()); + dynamic_cast(client_config_.get())->pull_time_delay_mills_when_exception()); LOG_WARN_NEW("find the consumer's subscription failed, {}", pullRequest->toString()); return; } bool commitOffsetEnable = false; int64_t commitOffsetValue = 0; - if (CLUSTERING == dynamic_cast(client_config_.get())->getMessageModel()) { + if (CLUSTERING == dynamic_cast(client_config_.get())->message_model()) { commitOffsetValue = offset_store_->readOffset(messageQueue, READ_FROM_MEMORY); if (commitOffsetValue > 0) { commitOffsetEnable = true; @@ -540,22 +540,22 @@ void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pullRequest) { try { auto* callback = new AsyncPullCallback(shared_from_this(), pullRequest, subscriptionData); pull_api_wrapper_->pullKernelImpl( - messageQueue, // 1 - subExpression, // 2 - subscriptionData->sub_version(), // 3 - pullRequest->next_offset(), // 4 - 32, // 5 - sysFlag, // 6 - commitOffsetValue, // 7 - 1000 * 15, // 8 - dynamic_cast(client_config_.get())->getAsyncPullTimeout(), // 9 - CommunicationMode::ASYNC, // 10 - callback); // 11 + messageQueue, // 1 + subExpression, // 2 + subscriptionData->sub_version(), // 3 + pullRequest->next_offset(), // 4 + 32, // 5 + sysFlag, // 6 + commitOffsetValue, // 7 + 1000 * 15, // 8 + dynamic_cast(client_config_.get())->async_pull_timeout(), // 9 + CommunicationMode::ASYNC, // 10 + callback); // 11 } catch (MQException& e) { LOG_ERROR_NEW("pullKernelImpl exception: {}", e.what()); executePullRequestLater( pullRequest, - dynamic_cast(client_config_.get())->getPullTimeDelayMillsWhenException()); + dynamic_cast(client_config_.get())->pull_time_delay_mills_when_exception()); } } @@ -564,27 +564,27 @@ void DefaultMQPushConsumerImpl::resetRetryTopic(const std::vector std::string groupTopic = UtilAll::getRetryTopic(consumerGroup); for (auto& msg : msgs) { std::string retryTopic = msg->getProperty(MQMessageConst::PROPERTY_RETRY_TOPIC); - if (!retryTopic.empty() && groupTopic == msg->getTopic()) { - msg->setTopic(retryTopic); + if (!retryTopic.empty() && groupTopic == msg->topic()) { + msg->set_topic(retryTopic); } } } int DefaultMQPushConsumerImpl::getMaxReconsumeTimes() { // default reconsume times: 16 - if (dynamic_cast(client_config_.get())->getMaxReconsumeTimes() == -1) { + if (dynamic_cast(client_config_.get())->max_reconsume_times() == -1) { return 16; } else { - return dynamic_cast(client_config_.get())->getMaxReconsumeTimes(); + return dynamic_cast(client_config_.get())->max_reconsume_times(); } } std::string DefaultMQPushConsumerImpl::groupName() const { - return client_config_->getGroupName(); + return client_config_->group_name(); } MessageModel DefaultMQPushConsumerImpl::messageModel() const { - return dynamic_cast(client_config_.get())->getMessageModel(); + return dynamic_cast(client_config_.get())->message_model(); }; ConsumeType DefaultMQPushConsumerImpl::consumeType() const { @@ -592,7 +592,7 @@ ConsumeType DefaultMQPushConsumerImpl::consumeType() const { } ConsumeFromWhere DefaultMQPushConsumerImpl::consumeFromWhere() const { - return dynamic_cast(client_config_.get())->getConsumeFromWhere(); + return dynamic_cast(client_config_.get())->consume_from_where(); } std::vector DefaultMQPushConsumerImpl::subscriptions() const { @@ -610,7 +610,7 @@ ConsumerRunningInfo* DefaultMQPushConsumerImpl::consumerRunningInfo() { info->setProperty(ConsumerRunningInfo::PROP_CONSUME_ORDERLY, UtilAll::to_string(consume_orderly_)); info->setProperty( ConsumerRunningInfo::PROP_THREADPOOL_CORE_SIZE, - UtilAll::to_string(dynamic_cast(client_config_.get())->getConsumeThreadNum())); + UtilAll::to_string(dynamic_cast(client_config_.get())->consume_thread_nums())); info->setProperty(ConsumerRunningInfo::PROP_CONSUMER_START_TIMESTAMP, UtilAll::to_string(start_time_)); auto subSet = subscriptions(); diff --git a/src/consumer/ProcessQueue.cpp b/src/consumer/ProcessQueue.cpp index dee12f325..bc6f29d89 100644 --- a/src/consumer/ProcessQueue.cpp +++ b/src/consumer/ProcessQueue.cpp @@ -52,7 +52,7 @@ void ProcessQueue::putMessage(const std::vector& msgs) { std::lock_guard lock(lock_tree_map_); for (const auto& msg : msgs) { - int64_t offset = msg->getQueueOffset(); + int64_t offset = msg->queue_offset(); msg_tree_map_[offset] = msg; if (offset > queue_offset_max_) { queue_offset_max_ = offset; @@ -74,8 +74,8 @@ int64_t ProcessQueue::removeMessage(const std::vector& msgs) { LOG_DEBUG_NEW("offset result is:{}, queue_offset_max is:{}, msgs size:{}", result, queue_offset_max_, msgs.size()); for (auto& msg : msgs) { - LOG_DEBUG_NEW("remove these msg from msg_tree_map, its offset:{}", msg->getQueueOffset()); - msg_tree_map_.erase(msg->getQueueOffset()); + LOG_DEBUG_NEW("remove these msg from msg_tree_map, its offset:{}", msg->queue_offset()); + msg_tree_map_.erase(msg->queue_offset()); } if (!msg_tree_map_.empty()) { @@ -121,8 +121,8 @@ int64_t ProcessQueue::commit() { void ProcessQueue::makeMessageToCosumeAgain(std::vector& msgs) { std::lock_guard lock(lock_tree_map_); for (const auto& msg : msgs) { - msg_tree_map_[msg->getQueueOffset()] = msg; - consuming_msg_orderly_tree_map_.erase(msg->getQueueOffset()); + msg_tree_map_[msg->queue_offset()] = msg; + consuming_msg_orderly_tree_map_.erase(msg->queue_offset()); } } diff --git a/src/consumer/PullAPIWrapper.cpp b/src/consumer/PullAPIWrapper.cpp index 96a9a8fb8..54a551214 100644 --- a/src/consumer/PullAPIWrapper.cpp +++ b/src/consumer/PullAPIWrapper.cpp @@ -69,7 +69,7 @@ PullResult PullAPIWrapper::processPullResult(const MQMessageQueue& mq, if (subscriptionData != nullptr && !subscriptionData->tags_set().empty()) { msgListFilterAgain.reserve(msgList.size()); for (const auto& msg : msgList) { - const auto& msgTag = msg->getTags(); + const auto& msgTag = msg->tags(); if (subscriptionData->contain_tag(msgTag)) { msgListFilterAgain.push_back(msg); } @@ -81,7 +81,7 @@ PullResult PullAPIWrapper::processPullResult(const MQMessageQueue& mq, for (auto& msg : msgListFilterAgain) { const auto& tranMsg = msg->getProperty(MQMessageConst::PROPERTY_TRANSACTION_PREPARED); if (UtilAll::stob(tranMsg)) { - msg->setTransactionId(msg->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX)); + msg->set_transaction_id(msg->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX)); } MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_MIN_OFFSET, UtilAll::to_string(pullResult.min_offset())); diff --git a/src/consumer/RebalancePushImpl.cpp b/src/consumer/RebalancePushImpl.cpp index ecffc955a..7c2cf46f3 100644 --- a/src/consumer/RebalancePushImpl.cpp +++ b/src/consumer/RebalancePushImpl.cpp @@ -61,7 +61,7 @@ void RebalancePushImpl::removeDirtyOffset(const MQMessageQueue& mq) { int64_t RebalancePushImpl::computePullFromWhere(const MQMessageQueue& mq) { int64_t result = -1; ConsumeFromWhere consumeFromWhere = - default_mq_push_consumer_impl_->getDefaultMQPushConsumerConfig()->getConsumeFromWhere(); + default_mq_push_consumer_impl_->getDefaultMQPushConsumerConfig()->consume_from_where(); OffsetStore* offsetStore = default_mq_push_consumer_impl_->getOffsetStore(); switch (consumeFromWhere) { case CONSUME_FROM_LAST_OFFSET: { @@ -119,7 +119,7 @@ int64_t RebalancePushImpl::computePullFromWhere(const MQMessageQueue& mq) { try { // FIXME: parseDate by YYYYMMDDHHMMSS auto timestamp = - std::stoull(default_mq_push_consumer_impl_->getDefaultMQPushConsumerConfig()->getConsumeTimestamp()); + std::stoull(default_mq_push_consumer_impl_->getDefaultMQPushConsumerConfig()->consume_timestamp()); result = default_mq_push_consumer_impl_->searchOffset(mq, timestamp); } catch (MQClientException& e) { LOG_ERROR_NEW("CONSUME_FROM_TIMESTAMP error, searchOffset of mq:{}, return 0", mq.toString()); diff --git a/src/extern/CMessage.cpp b/src/extern/CMessage.cpp index b7db24536..2a3014739 100644 --- a/src/extern/CMessage.cpp +++ b/src/extern/CMessage.cpp @@ -23,7 +23,7 @@ using namespace rocketmq; CMessage* CreateMessage(const char* topic) { auto* msg = new MQMessage(); if (topic != NULL) { - msg->setTopic(topic); + msg->set_topic(topic); } return reinterpret_cast(msg); } @@ -40,7 +40,7 @@ int SetMessageTopic(CMessage* msg, const char* topic) { if (msg == NULL) { return NULL_POINTER; } - reinterpret_cast(msg)->setTopic(topic); + reinterpret_cast(msg)->set_topic(topic); return OK; } @@ -48,7 +48,7 @@ int SetMessageTags(CMessage* msg, const char* tags) { if (msg == NULL) { return NULL_POINTER; } - reinterpret_cast(msg)->setTags(tags); + reinterpret_cast(msg)->set_tags(tags); return OK; } @@ -56,7 +56,7 @@ int SetMessageKeys(CMessage* msg, const char* keys) { if (msg == NULL) { return NULL_POINTER; } - reinterpret_cast(msg)->setKeys(keys); + reinterpret_cast(msg)->set_keys(keys); return OK; } @@ -64,7 +64,7 @@ int SetMessageBody(CMessage* msg, const char* body) { if (msg == NULL) { return NULL_POINTER; } - reinterpret_cast(msg)->setBody(std::string(body)); + reinterpret_cast(msg)->set_body(std::string(body)); return OK; } @@ -73,7 +73,7 @@ int SetByteMessageBody(CMessage* msg, const char* body, int len) { return NULL_POINTER; } - reinterpret_cast(msg)->setBody(std::string(body, len)); + reinterpret_cast(msg)->set_body(std::string(body, len)); return OK; } @@ -89,7 +89,7 @@ int SetDelayTimeLevel(CMessage* msg, int level) { if (msg == NULL) { return NULL_POINTER; } - reinterpret_cast(msg)->setDelayTimeLevel(level); + reinterpret_cast(msg)->set_delay_time_level(level); return OK; } @@ -97,28 +97,28 @@ const char* GetOriginMessageTopic(CMessage* msg) { if (msg == NULL) { return NULL; } - return reinterpret_cast(msg)->getTopic().c_str(); + return reinterpret_cast(msg)->topic().c_str(); } const char* GetOriginMessageTags(CMessage* msg) { if (msg == NULL) { return NULL; } - return reinterpret_cast(msg)->getTags().c_str(); + return reinterpret_cast(msg)->tags().c_str(); } const char* GetOriginMessageKeys(CMessage* msg) { if (msg == NULL) { return NULL; } - return reinterpret_cast(msg)->getKeys().c_str(); + return reinterpret_cast(msg)->keys().c_str(); } const char* GetOriginMessageBody(CMessage* msg) { if (msg == NULL) { return NULL; } - return reinterpret_cast(msg)->getBody().c_str(); + return reinterpret_cast(msg)->body().c_str(); } const char* GetOriginMessageProperty(CMessage* msg, const char* key) { @@ -132,5 +132,5 @@ int GetOriginDelayTimeLevel(CMessage* msg) { if (msg == NULL) { return -1; } - return reinterpret_cast(msg)->getDelayTimeLevel(); + return reinterpret_cast(msg)->delay_time_level(); } diff --git a/src/extern/CMessageExt.cpp b/src/extern/CMessageExt.cpp index 247ba5b85..1ddde9384 100644 --- a/src/extern/CMessageExt.cpp +++ b/src/extern/CMessageExt.cpp @@ -24,28 +24,28 @@ const char* GetMessageTopic(CMessageExt* msg) { if (msg == NULL) { return NULL; } - return reinterpret_cast(msg)->getTopic().c_str(); + return reinterpret_cast(msg)->topic().c_str(); } const char* GetMessageTags(CMessageExt* msg) { if (msg == NULL) { return NULL; } - return reinterpret_cast(msg)->getTags().c_str(); + return reinterpret_cast(msg)->tags().c_str(); } const char* GetMessageKeys(CMessageExt* msg) { if (msg == NULL) { return NULL; } - return reinterpret_cast(msg)->getKeys().c_str(); + return reinterpret_cast(msg)->keys().c_str(); } const char* GetMessageBody(CMessageExt* msg) { if (msg == NULL) { return NULL; } - return reinterpret_cast(msg)->getBody().c_str(); + return reinterpret_cast(msg)->body().c_str(); } const char* GetMessageProperty(CMessageExt* msg, const char* key) { @@ -59,68 +59,68 @@ const char* GetMessageId(CMessageExt* msg) { if (msg == NULL) { return NULL; } - return reinterpret_cast(msg)->getMsgId().c_str(); + return reinterpret_cast(msg)->msg_id().c_str(); } int GetMessageDelayTimeLevel(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return reinterpret_cast(msg)->getDelayTimeLevel(); + return reinterpret_cast(msg)->delay_time_level(); } int GetMessageQueueId(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return reinterpret_cast(msg)->getQueueId(); + return reinterpret_cast(msg)->queue_id(); } int GetMessageReconsumeTimes(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return reinterpret_cast(msg)->getReconsumeTimes(); + return reinterpret_cast(msg)->reconsume_times(); } int GetMessageStoreSize(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return reinterpret_cast(msg)->getStoreSize(); + return reinterpret_cast(msg)->store_size(); } long long GetMessageBornTimestamp(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return reinterpret_cast(msg)->getBornTimestamp(); + return reinterpret_cast(msg)->born_timestamp(); } long long GetMessageStoreTimestamp(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return reinterpret_cast(msg)->getStoreTimestamp(); + return reinterpret_cast(msg)->store_timestamp(); } long long GetMessageQueueOffset(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return reinterpret_cast(msg)->getQueueOffset(); + return reinterpret_cast(msg)->queue_offset(); } long long GetMessageCommitLogOffset(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return reinterpret_cast(msg)->getCommitLogOffset(); + return reinterpret_cast(msg)->commit_log_offset(); } long long GetMessagePreparedTransactionOffset(CMessageExt* msg) { if (msg == NULL) { return NULL_POINTER; } - return reinterpret_cast(msg)->getPreparedTransactionOffset(); + return reinterpret_cast(msg)->prepared_transaction_offset(); } diff --git a/src/extern/CProducer.cpp b/src/extern/CProducer.cpp index 33dd4da45..edf607287 100644 --- a/src/extern/CProducer.cpp +++ b/src/extern/CProducer.cpp @@ -127,9 +127,9 @@ class COnSendCallback : public AutoDeleteSendCallback { void onSuccess(SendResult& sendResult) override { 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.sendStatus = CSendStatus((int)sendResult.send_status()); + result.offset = sendResult.queue_offset(); + strncpy(result.msgId, sendResult.msg_id().c_str(), MAX_MESSAGE_ID_LENGTH - 1); result.msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0; send_success_callback_(result, message_, user_data_); } @@ -159,9 +159,9 @@ class CSendCallback : public AutoDeleteSendCallback { void onSuccess(SendResult& sendResult) override { 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.sendStatus = CSendStatus((int)sendResult.send_status()); + result.offset = sendResult.queue_offset(); + strncpy(result.msgId, sendResult.msg_id().c_str(), MAX_MESSAGE_ID_LENGTH - 1); result.msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0; send_success_callback_(result); } @@ -236,7 +236,7 @@ int SetProducerNameServerAddress(CProducer* producer, const char* namesrv) { if (producer == NULL) { return NULL_POINTER; } - reinterpret_cast(producer)->setNamesrvAddr(namesrv); + reinterpret_cast(producer)->set_namesrv_addr(namesrv); return OK; } @@ -257,7 +257,7 @@ int SendMessageSync(CProducer* producer, CMessage* msg, CSendResult* result) { auto* defaultMQProducer = reinterpret_cast(producer); auto* message = reinterpret_cast(msg); auto sendResult = defaultMQProducer->send(*message); - switch (sendResult.getSendStatus()) { + switch (sendResult.send_status()) { case SEND_OK: result->sendStatus = E_SEND_OK; break; @@ -274,8 +274,8 @@ int SendMessageSync(CProducer* producer, CMessage* msg, CSendResult* result) { result->sendStatus = E_SEND_OK; break; } - result->offset = sendResult.getQueueOffset(); - strncpy(result->msgId, sendResult.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1); + result->offset = sendResult.queue_offset(); + strncpy(result->msgId, sendResult.msg_id().c_str(), MAX_MESSAGE_ID_LENGTH - 1); result->msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0; } catch (std::exception& e) { CErrorContainer::setErrorMessage(e.what()); @@ -292,7 +292,7 @@ int SendBatchMessage(CProducer* producer, CBatchMessage* batcMsg, CSendResult* r auto* defaultMQProducer = reinterpret_cast(producer); auto* message = reinterpret_cast*>(batcMsg); auto sendResult = defaultMQProducer->send(*message); - switch (sendResult.getSendStatus()) { + switch (sendResult.send_status()) { case SEND_OK: result->sendStatus = E_SEND_OK; break; @@ -309,8 +309,8 @@ int SendBatchMessage(CProducer* producer, CBatchMessage* batcMsg, CSendResult* r result->sendStatus = E_SEND_OK; break; } - result->offset = sendResult.getQueueOffset(); - strncpy(result->msgId, sendResult.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1); + result->offset = sendResult.queue_offset(); + strncpy(result->msgId, sendResult.msg_id().c_str(), MAX_MESSAGE_ID_LENGTH - 1); result->msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0; } catch (std::exception& e) { return PRODUCER_SEND_SYNC_FAILED; @@ -412,9 +412,9 @@ int SendMessageOrderly(CProducer* producer, SelectMessageQueue selectMessageQueue(selectorCallback); SendResult send_result = defaultMQProducer->send(*message, &selectMessageQueue, arg); // Convert SendStatus to CSendStatus - result->sendStatus = CSendStatus((int)send_result.getSendStatus()); - result->offset = send_result.getQueueOffset(); - strncpy(result->msgId, send_result.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1); + result->sendStatus = CSendStatus((int)send_result.send_status()); + result->offset = send_result.queue_offset(); + strncpy(result->msgId, send_result.msg_id().c_str(), MAX_MESSAGE_ID_LENGTH - 1); result->msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0; } catch (std::exception& e) { CErrorContainer::setErrorMessage(e.what()); @@ -435,9 +435,9 @@ int SendMessageOrderlyByShardingKey(CProducer* producer, CMessage* msg, const ch SelectMessageQueueInner selectMessageQueue; SendResult send_esult = defaultMQProducer->send(*message, &selectMessageQueue, (void*)shardingKey, retryTimes); // Convert SendStatus to CSendStatus - result->sendStatus = CSendStatus((int)send_esult.getSendStatus()); - result->offset = send_esult.getQueueOffset(); - strncpy(result->msgId, send_esult.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1); + result->sendStatus = CSendStatus((int)send_esult.send_status()); + result->offset = send_esult.queue_offset(); + strncpy(result->msgId, send_esult.msg_id().c_str(), MAX_MESSAGE_ID_LENGTH - 1); result->msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0; } catch (std::exception& e) { CErrorContainer::setErrorMessage(e.what()); @@ -459,9 +459,9 @@ int SendMessageTransaction(CProducer* producer, auto* message = reinterpret_cast(msg); LocalTransactionExecutorInner executorInner(callback, msg, userData); auto send_result = transactionMQProducer->sendMessageInTransaction(*message, &executorInner); - result->sendStatus = CSendStatus((int)send_result.getSendStatus()); - result->offset = send_result.getQueueOffset(); - strncpy(result->msgId, send_result.getMsgId().c_str(), MAX_MESSAGE_ID_LENGTH - 1); + result->sendStatus = CSendStatus((int)send_result.send_status()); + result->offset = send_result.queue_offset(); + strncpy(result->msgId, send_result.msg_id().c_str(), MAX_MESSAGE_ID_LENGTH - 1); result->msgId[MAX_MESSAGE_ID_LENGTH - 1] = 0; } catch (std::exception& e) { CErrorContainer::setErrorMessage(e.what()); @@ -474,7 +474,7 @@ int SetProducerGroupName(CProducer* producer, const char* groupName) { if (producer == NULL) { return NULL_POINTER; } - reinterpret_cast(producer)->setGroupName(groupName); + reinterpret_cast(producer)->set_group_name(groupName); return OK; } @@ -482,7 +482,7 @@ int SetProducerInstanceName(CProducer* producer, const char* instanceName) { if (producer == NULL) { return NULL_POINTER; } - reinterpret_cast(producer)->setInstanceName(instanceName); + reinterpret_cast(producer)->set_instance_name(instanceName); return OK; } @@ -527,7 +527,7 @@ int SetProducerSendMsgTimeout(CProducer* producer, int timeout) { if (producer == NULL) { return NULL_POINTER; } - reinterpret_cast(producer)->setSendMsgTimeout(timeout); + reinterpret_cast(producer)->set_send_msg_timeout(timeout); return OK; } @@ -535,7 +535,7 @@ int SetProducerCompressMsgBodyOverHowmuch(CProducer* producer, int howmuch) { if (producer == NULL) { return NULL_POINTER; } - reinterpret_cast(producer)->setCompressMsgBodyOverHowmuch(howmuch); + reinterpret_cast(producer)->set_compress_msg_body_over_howmuch(howmuch); return OK; } @@ -543,7 +543,7 @@ int SetProducerCompressLevel(CProducer* producer, int level) { if (producer == NULL) { return NULL_POINTER; } - reinterpret_cast(producer)->setCompressLevel(level); + reinterpret_cast(producer)->set_compress_level(level); return OK; } @@ -551,6 +551,6 @@ int SetProducerMaxMessageSize(CProducer* producer, int size) { if (producer == NULL) { return NULL_POINTER; } - reinterpret_cast(producer)->setMaxMessageSize(size); + reinterpret_cast(producer)->set_max_message_size(size); return OK; } diff --git a/src/extern/CPullConsumer.cpp b/src/extern/CPullConsumer.cpp index bce4b6148..b4ed9ac6e 100644 --- a/src/extern/CPullConsumer.cpp +++ b/src/extern/CPullConsumer.cpp @@ -66,7 +66,7 @@ int SetPullConsumerGroupID(CPullConsumer* consumer, const char* groupId) { if (consumer == NULL || groupId == NULL) { return NULL_POINTER; } - reinterpret_cast(consumer)->setGroupName(groupId); + reinterpret_cast(consumer)->set_group_name(groupId); return OK; } @@ -74,14 +74,14 @@ const char* GetPullConsumerGroupID(CPullConsumer* consumer) { if (consumer == NULL) { return NULL; } - return reinterpret_cast(consumer)->getGroupName().c_str(); + return reinterpret_cast(consumer)->group_name().c_str(); } int SetPullConsumerNameServerAddress(CPullConsumer* consumer, const char* namesrv) { if (consumer == NULL) { return NULL_POINTER; } - reinterpret_cast(consumer)->setNamesrvAddr(namesrv); + reinterpret_cast(consumer)->set_namesrv_addr(namesrv); return OK; } diff --git a/src/extern/CPushConsumer.cpp b/src/extern/CPushConsumer.cpp index 6287a2e1c..feb769391 100644 --- a/src/extern/CPushConsumer.cpp +++ b/src/extern/CPushConsumer.cpp @@ -79,7 +79,7 @@ CPushConsumer* CreatePushConsumer(const char* groupId) { return NULL; } auto* defaultMQPushConsumer = new DefaultMQPushConsumer(groupId); - defaultMQPushConsumer->setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET); + defaultMQPushConsumer->set_consume_from_where(CONSUME_FROM_LAST_OFFSET); return reinterpret_cast(defaultMQPushConsumer); } @@ -116,7 +116,7 @@ int SetPushConsumerGroupID(CPushConsumer* consumer, const char* groupId) { if (consumer == NULL || groupId == NULL) { return NULL_POINTER; } - reinterpret_cast(consumer)->setGroupName(groupId); + reinterpret_cast(consumer)->set_group_name(groupId); return OK; } @@ -124,14 +124,14 @@ const char* GetPushConsumerGroupID(CPushConsumer* consumer) { if (consumer == NULL) { return NULL; } - return reinterpret_cast(consumer)->getGroupName().c_str(); + return reinterpret_cast(consumer)->group_name().c_str(); } int SetPushConsumerNameServerAddress(CPushConsumer* consumer, const char* namesrv) { if (consumer == NULL) { return NULL_POINTER; } - reinterpret_cast(consumer)->setNamesrvAddr(namesrv); + reinterpret_cast(consumer)->set_namesrv_addr(namesrv); return OK; } @@ -191,7 +191,7 @@ int SetPushConsumerMessageModel(CPushConsumer* consumer, CMessageModel messageMo if (consumer == NULL) { return NULL_POINTER; } - reinterpret_cast(consumer)->setMessageModel(MessageModel((int)messageModel)); + reinterpret_cast(consumer)->set_message_model(MessageModel((int)messageModel)); return OK; } @@ -199,7 +199,7 @@ int SetPushConsumerThreadCount(CPushConsumer* consumer, int threadCount) { if (consumer == NULL || threadCount == 0) { return NULL_POINTER; } - reinterpret_cast(consumer)->setConsumeThreadNum(threadCount); + reinterpret_cast(consumer)->set_consume_thread_nums(threadCount); return OK; } @@ -207,7 +207,7 @@ int SetPushConsumerMessageBatchMaxSize(CPushConsumer* consumer, int batchSize) { if (consumer == NULL || batchSize == 0) { return NULL_POINTER; } - reinterpret_cast(consumer)->setConsumeMessageBatchMaxSize(batchSize); + reinterpret_cast(consumer)->set_consume_message_batch_max_size(batchSize); return OK; } @@ -215,7 +215,7 @@ int SetPushConsumerMaxCacheMessageSize(CPushConsumer* consumer, int maxCacheSize if (consumer == NULL || maxCacheSize <= 0) { return NULL_POINTER; } - reinterpret_cast(consumer)->setMaxCacheMsgSizePerQueue(maxCacheSize); + reinterpret_cast(consumer)->set_max_cache_msg_size_per_queue(maxCacheSize); return OK; } @@ -229,7 +229,7 @@ int SetPushConsumerInstanceName(CPushConsumer* consumer, const char* instanceNam if (consumer == NULL) { return NULL_POINTER; } - reinterpret_cast(consumer)->setInstanceName(instanceName); + reinterpret_cast(consumer)->set_instance_name(instanceName); return OK; } diff --git a/src/message/MQMessage.cpp b/src/message/MQMessage.cpp index 0e46e9dfb..af115be85 100644 --- a/src/message/MQMessage.cpp +++ b/src/message/MQMessage.cpp @@ -62,92 +62,92 @@ void MQMessage::clearProperty(const std::string& name) { message_impl_->clearProperty(name); } -const std::string& MQMessage::getTopic() const { - return message_impl_->getTopic(); +const std::string& MQMessage::topic() const { + return message_impl_->topic(); } -void MQMessage::setTopic(const std::string& topic) { - message_impl_->setTopic(topic); +void MQMessage::set_topic(const std::string& topic) { + message_impl_->set_topic(topic); } -void MQMessage::setTopic(const char* body, int len) { - message_impl_->setTopic(body, len); +void MQMessage::set_topic(const char* body, int len) { + message_impl_->set_topic(body, len); } -const std::string& MQMessage::getTags() const { - return message_impl_->getTags(); +const std::string& MQMessage::tags() const { + return message_impl_->tags(); } -void MQMessage::setTags(const std::string& tags) { - message_impl_->setTags(tags); +void MQMessage::set_tags(const std::string& tags) { + message_impl_->set_tags(tags); } -const std::string& MQMessage::getKeys() const { - return message_impl_->getKeys(); +const std::string& MQMessage::keys() const { + return message_impl_->keys(); } -void MQMessage::setKeys(const std::string& keys) { - message_impl_->setKeys(keys); +void MQMessage::set_keys(const std::string& keys) { + message_impl_->set_keys(keys); } -void MQMessage::setKeys(const std::vector& keys) { - message_impl_->setKeys(keys); +void MQMessage::set_keys(const std::vector& keys) { + message_impl_->set_keys(keys); } -int MQMessage::getDelayTimeLevel() const { - return message_impl_->getDelayTimeLevel(); +int MQMessage::delay_time_level() const { + return message_impl_->delay_time_level(); } -void MQMessage::setDelayTimeLevel(int level) { - message_impl_->setDelayTimeLevel(level); +void MQMessage::set_delay_time_level(int level) { + message_impl_->set_delay_time_level(level); } -bool MQMessage::isWaitStoreMsgOK() const { - return message_impl_->isWaitStoreMsgOK(); +bool MQMessage::wait_store_msg_ok() const { + return message_impl_->wait_store_msg_ok(); } -void MQMessage::setWaitStoreMsgOK(bool waitStoreMsgOK) { - message_impl_->setWaitStoreMsgOK(waitStoreMsgOK); +void MQMessage::set_wait_store_msg_ok(bool waitStoreMsgOK) { + message_impl_->set_wait_store_msg_ok(waitStoreMsgOK); } -int32_t MQMessage::getFlag() const { - return message_impl_->getFlag(); +int32_t MQMessage::flag() const { + return message_impl_->flag(); } -void MQMessage::setFlag(int32_t flag) { - message_impl_->setFlag(flag); +void MQMessage::set_flag(int32_t flag) { + message_impl_->set_flag(flag); } -const std::string& MQMessage::getBody() const { - return message_impl_->getBody(); +const std::string& MQMessage::body() const { + return message_impl_->body(); } -void MQMessage::setBody(const std::string& body) { - message_impl_->setBody(body); +void MQMessage::set_body(const std::string& body) { + message_impl_->set_body(body); } -void MQMessage::setBody(std::string&& body) { - message_impl_->setBody(std::move(body)); +void MQMessage::set_body(std::string&& body) { + message_impl_->set_body(std::move(body)); } -const std::string& MQMessage::getTransactionId() const { - return message_impl_->getTransactionId(); +const std::string& MQMessage::transaction_id() const { + return message_impl_->transaction_id(); } -void MQMessage::setTransactionId(const std::string& transactionId) { - message_impl_->setTransactionId(transactionId); +void MQMessage::set_transaction_id(const std::string& transactionId) { + message_impl_->set_transaction_id(transactionId); } -const std::map& MQMessage::getProperties() const { - return message_impl_->getProperties(); +const std::map& MQMessage::properties() const { + return message_impl_->properties(); } -void MQMessage::setProperties(const std::map& properties) { - message_impl_->setProperties(properties); +void MQMessage::set_properties(const std::map& properties) { + message_impl_->set_properties(properties); } -void MQMessage::setProperties(std::map&& properties) { - message_impl_->setProperties(std::move(properties)); +void MQMessage::set_properties(std::map&& properties) { + message_impl_->set_properties(std::move(properties)); } bool MQMessage::isBatch() const { diff --git a/src/message/MQMessageExt.cpp b/src/message/MQMessageExt.cpp index 957c02392..a58d0352c 100644 --- a/src/message/MQMessageExt.cpp +++ b/src/message/MQMessageExt.cpp @@ -33,116 +33,116 @@ MQMessageExt::MQMessageExt(int queueId, MQMessageExt::~MQMessageExt() = default; -int32_t MQMessageExt::getStoreSize() const { - return dynamic_cast(message_impl_.get())->getStoreSize(); +int32_t MQMessageExt::store_size() const { + return dynamic_cast(message_impl_.get())->store_size(); } -void MQMessageExt::setStoreSize(int32_t storeSize) { - dynamic_cast(message_impl_.get())->setStoreSize(storeSize); +void MQMessageExt::set_store_size(int32_t storeSize) { + dynamic_cast(message_impl_.get())->set_store_size(storeSize); } -int32_t MQMessageExt::getBodyCRC() const { - return dynamic_cast(message_impl_.get())->getBodyCRC(); +int32_t MQMessageExt::body_crc() const { + return dynamic_cast(message_impl_.get())->body_crc(); } -void MQMessageExt::setBodyCRC(int32_t bodyCRC) { - dynamic_cast(message_impl_.get())->setBodyCRC(bodyCRC); +void MQMessageExt::set_body_crc(int32_t bodyCRC) { + dynamic_cast(message_impl_.get())->set_body_crc(bodyCRC); } -int32_t MQMessageExt::getQueueId() const { - return dynamic_cast(message_impl_.get())->getQueueId(); +int32_t MQMessageExt::queue_id() const { + return dynamic_cast(message_impl_.get())->queue_id(); } -void MQMessageExt::setQueueId(int32_t queueId) { - dynamic_cast(message_impl_.get())->setQueueId(queueId); +void MQMessageExt::set_queue_id(int32_t queueId) { + dynamic_cast(message_impl_.get())->set_queue_id(queueId); } -int64_t MQMessageExt::getQueueOffset() const { - return dynamic_cast(message_impl_.get())->getQueueOffset(); +int64_t MQMessageExt::queue_offset() const { + return dynamic_cast(message_impl_.get())->queue_offset(); } -void MQMessageExt::setQueueOffset(int64_t queueOffset) { - dynamic_cast(message_impl_.get())->setQueueOffset(queueOffset); +void MQMessageExt::set_queue_offset(int64_t queueOffset) { + dynamic_cast(message_impl_.get())->set_queue_offset(queueOffset); } -int64_t MQMessageExt::getCommitLogOffset() const { - return dynamic_cast(message_impl_.get())->getCommitLogOffset(); +int64_t MQMessageExt::commit_log_offset() const { + return dynamic_cast(message_impl_.get())->commit_log_offset(); } -void MQMessageExt::setCommitLogOffset(int64_t physicOffset) { - dynamic_cast(message_impl_.get())->setCommitLogOffset(physicOffset); +void MQMessageExt::set_commit_log_offset(int64_t physicOffset) { + dynamic_cast(message_impl_.get())->set_commit_log_offset(physicOffset); } -int32_t MQMessageExt::getSysFlag() const { - return dynamic_cast(message_impl_.get())->getSysFlag(); +int32_t MQMessageExt::sys_flag() const { + return dynamic_cast(message_impl_.get())->sys_flag(); } -void MQMessageExt::setSysFlag(int32_t sysFlag) { - dynamic_cast(message_impl_.get())->setSysFlag(sysFlag); +void MQMessageExt::set_sys_flag(int32_t sysFlag) { + dynamic_cast(message_impl_.get())->set_sys_flag(sysFlag); } -int64_t MQMessageExt::getBornTimestamp() const { - return dynamic_cast(message_impl_.get())->getBornTimestamp(); +int64_t MQMessageExt::born_timestamp() const { + return dynamic_cast(message_impl_.get())->born_timestamp(); } -void MQMessageExt::setBornTimestamp(int64_t bornTimestamp) { - dynamic_cast(message_impl_.get())->setBornTimestamp(bornTimestamp); +void MQMessageExt::set_born_timestamp(int64_t bornTimestamp) { + dynamic_cast(message_impl_.get())->set_born_timestamp(bornTimestamp); } -std::string MQMessageExt::getBornHostString() const { - return dynamic_cast(message_impl_.get())->getBornHostString(); +std::string MQMessageExt::born_host_string() const { + return dynamic_cast(message_impl_.get())->born_host_string(); } -const struct sockaddr* MQMessageExt::getBornHost() const { - return dynamic_cast(message_impl_.get())->getBornHost(); +const struct sockaddr* MQMessageExt::born_host() const { + return dynamic_cast(message_impl_.get())->born_host(); } -void MQMessageExt::setBornHost(const struct sockaddr* bornHost) { - dynamic_cast(message_impl_.get())->setBornHost(bornHost); +void MQMessageExt::set_born_host(const struct sockaddr* bornHost) { + dynamic_cast(message_impl_.get())->set_born_host(bornHost); } -int64_t MQMessageExt::getStoreTimestamp() const { - return dynamic_cast(message_impl_.get())->getStoreTimestamp(); +int64_t MQMessageExt::store_timestamp() const { + return dynamic_cast(message_impl_.get())->store_timestamp(); } -void MQMessageExt::setStoreTimestamp(int64_t storeTimestamp) { - dynamic_cast(message_impl_.get())->setStoreTimestamp(storeTimestamp); +void MQMessageExt::set_store_timestamp(int64_t storeTimestamp) { + dynamic_cast(message_impl_.get())->set_store_timestamp(storeTimestamp); } -std::string MQMessageExt::getStoreHostString() const { - return dynamic_cast(message_impl_.get())->getStoreHostString(); +std::string MQMessageExt::store_host_string() const { + return dynamic_cast(message_impl_.get())->store_host_string(); } -const struct sockaddr* MQMessageExt::getStoreHost() const { - return dynamic_cast(message_impl_.get())->getStoreHost(); +const struct sockaddr* MQMessageExt::store_host() const { + return dynamic_cast(message_impl_.get())->store_host(); } -void MQMessageExt::setStoreHost(const struct sockaddr* storeHost) { - dynamic_cast(message_impl_.get())->setStoreHost(storeHost); +void MQMessageExt::set_store_host(const struct sockaddr* storeHost) { + dynamic_cast(message_impl_.get())->set_store_host(storeHost); } -int32_t MQMessageExt::getReconsumeTimes() const { - return dynamic_cast(message_impl_.get())->getReconsumeTimes(); +int32_t MQMessageExt::reconsume_times() const { + return dynamic_cast(message_impl_.get())->reconsume_times(); } -void MQMessageExt::setReconsumeTimes(int32_t reconsumeTimes) { - dynamic_cast(message_impl_.get())->setReconsumeTimes(reconsumeTimes); +void MQMessageExt::set_reconsume_times(int32_t reconsumeTimes) { + dynamic_cast(message_impl_.get())->set_reconsume_times(reconsumeTimes); } -int64_t MQMessageExt::getPreparedTransactionOffset() const { - return dynamic_cast(message_impl_.get())->getPreparedTransactionOffset(); +int64_t MQMessageExt::prepared_transaction_offset() const { + return dynamic_cast(message_impl_.get())->prepared_transaction_offset(); } -void MQMessageExt::setPreparedTransactionOffset(int64_t preparedTransactionOffset) { - dynamic_cast(message_impl_.get())->setPreparedTransactionOffset(preparedTransactionOffset); +void MQMessageExt::set_prepared_transaction_offset(int64_t preparedTransactionOffset) { + dynamic_cast(message_impl_.get())->set_prepared_transaction_offset(preparedTransactionOffset); } -const std::string& MQMessageExt::getMsgId() const { - return dynamic_cast(message_impl_.get())->getMsgId(); +const std::string& MQMessageExt::msg_id() const { + return dynamic_cast(message_impl_.get())->msg_id(); } -void MQMessageExt::setMsgId(const std::string& msgId) { - dynamic_cast(message_impl_.get())->setMsgId(msgId); +void MQMessageExt::set_msg_id(const std::string& msgId) { + dynamic_cast(message_impl_.get())->set_msg_id(msgId); } } // namespace rocketmq diff --git a/src/message/MessageAccessor.hpp b/src/message/MessageAccessor.hpp index c10f9e08d..87c1cacaa 100644 --- a/src/message/MessageAccessor.hpp +++ b/src/message/MessageAccessor.hpp @@ -28,7 +28,7 @@ class MessageAccessor { static inline void clearProperty(Message& msg, const std::string& name) { msg.clearProperty(name); } static inline void setProperties(Message& msg, std::map&& properties) { - msg.setProperties(std::move(properties)); + msg.set_properties(std::move(properties)); } static inline void putProperty(Message& msg, const std::string& name, const std::string& value) { diff --git a/src/message/MessageBatch.cpp b/src/message/MessageBatch.cpp index 1f859f6e8..4030fd6db 100644 --- a/src/message/MessageBatch.cpp +++ b/src/message/MessageBatch.cpp @@ -28,30 +28,30 @@ std::shared_ptr MessageBatch::generateFromList(std::vector 0) { + if (message.delay_time_level() > 0) { THROW_MQEXCEPTION(MQClientException, "TimeDelayLevel in not supported for batching", -1); } if (is_first) { is_first = false; - topic = message.getTopic(); - wait_store_msg_ok = message.isWaitStoreMsgOK(); + topic = message.topic(); + wait_store_msg_ok = message.wait_store_msg_ok(); if (UtilAll::isRetryTopic(topic)) { THROW_MQEXCEPTION(MQClientException, "Retry Group is not supported for batching", -1); } } else { - if (message.getTopic() != topic) { + if (message.topic() != topic) { THROW_MQEXCEPTION(MQClientException, "The topic of the messages in one batch should be the same", -1); } - if (message.isWaitStoreMsgOK() != wait_store_msg_ok) { + if (message.wait_store_msg_ok() != wait_store_msg_ok) { THROW_MQEXCEPTION(MQClientException, "The waitStoreMsgOK of the messages in one batch should the same", -2); } } } auto batchMessage = std::make_shared(messages); - batchMessage->setTopic(topic); - batchMessage->setWaitStoreMsgOK(wait_store_msg_ok); + batchMessage->set_topic(topic); + batchMessage->set_wait_store_msg_ok(wait_store_msg_ok); return batchMessage; } diff --git a/src/message/MessageDecoder.cpp b/src/message/MessageDecoder.cpp index 128ca7f90..a36d3bf96 100644 --- a/src/message/MessageDecoder.cpp +++ b/src/message/MessageDecoder.cpp @@ -89,64 +89,64 @@ MessageExtPtr MessageDecoder::decode(ByteBuffer& byteBuffer, bool readBody, bool // 1 TOTALSIZE int32_t storeSize = byteBuffer.getInt(); - msgExt->setStoreSize(storeSize); + msgExt->set_store_size(storeSize); // 2 MAGICCODE sizeof(int) byteBuffer.getInt(); // 3 BODYCRC int32_t bodyCRC = byteBuffer.getInt(); - msgExt->setBodyCRC(bodyCRC); + msgExt->set_body_crc(bodyCRC); // 4 QUEUEID int32_t queueId = byteBuffer.getInt(); - msgExt->setQueueId(queueId); + msgExt->set_queue_id(queueId); // 5 FLAG int32_t flag = byteBuffer.getInt(); - msgExt->setFlag(flag); + msgExt->set_flag(flag); // 6 QUEUEOFFSET int64_t queueOffset = byteBuffer.getLong(); - msgExt->setQueueOffset(queueOffset); + msgExt->set_queue_offset(queueOffset); // 7 PHYSICALOFFSET int64_t physicOffset = byteBuffer.getLong(); - msgExt->setCommitLogOffset(physicOffset); + msgExt->set_commit_log_offset(physicOffset); // 8 SYSFLAG int32_t sysFlag = byteBuffer.getInt(); - msgExt->setSysFlag(sysFlag); + msgExt->set_sys_flag(sysFlag); // 9 BORNTIMESTAMP int64_t bornTimeStamp = byteBuffer.getLong(); - msgExt->setBornTimestamp(bornTimeStamp); + msgExt->set_born_timestamp(bornTimeStamp); // 10 BORNHOST int bornhostIPLength = (sysFlag & MessageSysFlag::BORNHOST_V6_FLAG) == 0 ? 4 : 16; ByteArray bornHost(bornhostIPLength); byteBuffer.get(bornHost, 0, bornhostIPLength); int32_t bornPort = byteBuffer.getInt(); - msgExt->setBornHost(ipPort2SocketAddress(bornHost, bornPort)); + msgExt->set_born_host(ipPort2SocketAddress(bornHost, bornPort)); // 11 STORETIMESTAMP int64_t storeTimestamp = byteBuffer.getLong(); - msgExt->setStoreTimestamp(storeTimestamp); + msgExt->set_store_timestamp(storeTimestamp); // 12 STOREHOST int storehostIPLength = (sysFlag & MessageSysFlag::STOREHOST_V6_FLAG) == 0 ? 4 : 16; ByteArray storeHost(bornhostIPLength); byteBuffer.get(storeHost, 0, storehostIPLength); int32_t storePort = byteBuffer.getInt(); - msgExt->setStoreHost(ipPort2SocketAddress(storeHost, storePort)); + msgExt->set_store_host(ipPort2SocketAddress(storeHost, storePort)); // 13 RECONSUMETIMES int32_t reconsumeTimes = byteBuffer.getInt(); - msgExt->setReconsumeTimes(reconsumeTimes); + msgExt->set_reconsume_times(reconsumeTimes); // 14 Prepared Transaction Offset int64_t preparedTransactionOffset = byteBuffer.getLong(); - msgExt->setPreparedTransactionOffset(preparedTransactionOffset); + msgExt->set_prepared_transaction_offset(preparedTransactionOffset); // 15 BODY int uncompress_failed = false; @@ -160,12 +160,12 @@ MessageExtPtr MessageDecoder::decode(ByteBuffer& byteBuffer, bool readBody, bool if (deCompressBody && (sysFlag & MessageSysFlag::COMPRESSED_FLAG) == MessageSysFlag::COMPRESSED_FLAG) { std::string origin_body; if (UtilAll::inflate(body, origin_body)) { - msgExt->setBody(std::move(origin_body)); + msgExt->set_body(std::move(origin_body)); } else { uncompress_failed = true; } } else { - msgExt->setBody(std::string(body.array(), body.size())); + msgExt->set_body(std::string(body.array(), body.size())); } } else { // skip body @@ -177,7 +177,7 @@ MessageExtPtr MessageDecoder::decode(ByteBuffer& byteBuffer, bool readBody, bool int8_t topicLen = byteBuffer.get(); ByteArray topic(topicLen); byteBuffer.get(topic); - msgExt->setTopic(topic.array(), topic.size()); + msgExt->set_topic(topic.array(), topic.size()); // 17 properties int16_t propertiesLen = byteBuffer.getShort(); @@ -190,11 +190,11 @@ MessageExtPtr MessageDecoder::decode(ByteBuffer& byteBuffer, bool readBody, bool } // 18 msg ID - std::string msgId = createMessageId(msgExt->getStoreHost(), (int64_t)msgExt->getCommitLogOffset()); - msgExt->MessageExtImpl::setMsgId(msgId); + std::string msgId = createMessageId(msgExt->store_host(), (int64_t)msgExt->commit_log_offset()); + msgExt->MessageExtImpl::set_msg_id(msgId); if (uncompress_failed) { - LOG_WARN_NEW("can not uncompress message, id:{}", msgExt->getMsgId()); + LOG_WARN_NEW("can not uncompress message, id:{}", msgExt->msg_id()); } return msgExt; @@ -254,9 +254,9 @@ std::map MessageDecoder::string2messageProperties(cons } std::string MessageDecoder::encodeMessage(Message& message) { - const auto& body = message.getBody(); + const auto& body = message.body(); uint32_t bodyLen = body.size(); - std::string properties = MessageDecoder::messageProperties2String(message.getProperties()); + std::string properties = MessageDecoder::messageProperties2String(message.properties()); uint16_t propertiesLength = (int16_t)properties.size(); uint32_t storeSize = 4 // 1 TOTALSIZE + 4 // 2 MAGICCODE @@ -283,7 +283,7 @@ std::string MessageDecoder::encodeMessage(Message& message) { encodeMsg.append((char*)&bodyCrc_net, sizeof(uint32_t)); // 4 FLAG - uint32_t flag = message.getFlag(); + uint32_t flag = message.flag(); uint32_t flag_net = ByteOrderUtil::NorminalBigEndian(flag); encodeMsg.append((char*)&flag_net, sizeof(uint32_t)); diff --git a/src/message/MessageExtImpl.cpp b/src/message/MessageExtImpl.cpp index 94b38c459..f43ac357a 100644 --- a/src/message/MessageExtImpl.cpp +++ b/src/message/MessageExtImpl.cpp @@ -66,123 +66,123 @@ TopicFilterType MessageExtImpl::parseTopicFilterType(int32_t sysFlag) { return SINGLE_TAG; } -int32_t MessageExtImpl::getStoreSize() const { +int32_t MessageExtImpl::store_size() const { return store_size_; } -void MessageExtImpl::setStoreSize(int32_t storeSize) { +void MessageExtImpl::set_store_size(int32_t storeSize) { store_size_ = storeSize; } -int32_t MessageExtImpl::getBodyCRC() const { +int32_t MessageExtImpl::body_crc() const { return body_crc_; } -void MessageExtImpl::setBodyCRC(int32_t bodyCRC) { +void MessageExtImpl::set_body_crc(int32_t bodyCRC) { body_crc_ = bodyCRC; } -int32_t MessageExtImpl::getQueueId() const { +int32_t MessageExtImpl::queue_id() const { return queue_id_; } -void MessageExtImpl::setQueueId(int32_t queueId) { +void MessageExtImpl::set_queue_id(int32_t queueId) { queue_id_ = queueId; } -int64_t MessageExtImpl::getQueueOffset() const { +int64_t MessageExtImpl::queue_offset() const { return queue_offset_; } -void MessageExtImpl::setQueueOffset(int64_t queueOffset) { +void MessageExtImpl::set_queue_offset(int64_t queueOffset) { queue_offset_ = queueOffset; } -int64_t MessageExtImpl::getCommitLogOffset() const { +int64_t MessageExtImpl::commit_log_offset() const { return commit_log_offset_; } -void MessageExtImpl::setCommitLogOffset(int64_t physicOffset) { +void MessageExtImpl::set_commit_log_offset(int64_t physicOffset) { commit_log_offset_ = physicOffset; } -int32_t MessageExtImpl::getSysFlag() const { +int32_t MessageExtImpl::sys_flag() const { return sys_flag_; } -void MessageExtImpl::setSysFlag(int32_t sysFlag) { +void MessageExtImpl::set_sys_flag(int32_t sysFlag) { sys_flag_ = sysFlag; } -int64_t MessageExtImpl::getBornTimestamp() const { +int64_t MessageExtImpl::born_timestamp() const { return born_timestamp_; } -void MessageExtImpl::setBornTimestamp(int64_t bornTimestamp) { +void MessageExtImpl::set_born_timestamp(int64_t bornTimestamp) { born_timestamp_ = bornTimestamp; } -const struct sockaddr* MessageExtImpl::getBornHost() const { +const struct sockaddr* MessageExtImpl::born_host() const { return born_host_; } -std::string MessageExtImpl::getBornHostString() const { +std::string MessageExtImpl::born_host_string() const { return socketAddress2String(born_host_); } -void MessageExtImpl::setBornHost(const struct sockaddr* bornHost) { +void MessageExtImpl::set_born_host(const struct sockaddr* bornHost) { born_host_ = copySocketAddress(born_host_, bornHost); } -int64_t MessageExtImpl::getStoreTimestamp() const { +int64_t MessageExtImpl::store_timestamp() const { return store_timestamp_; } -void MessageExtImpl::setStoreTimestamp(int64_t storeTimestamp) { +void MessageExtImpl::set_store_timestamp(int64_t storeTimestamp) { store_timestamp_ = storeTimestamp; } -const struct sockaddr* MessageExtImpl::getStoreHost() const { +const struct sockaddr* MessageExtImpl::store_host() const { return store_host_; } -std::string MessageExtImpl::getStoreHostString() const { +std::string MessageExtImpl::store_host_string() const { return socketAddress2String(store_host_); } -void MessageExtImpl::setStoreHost(const struct sockaddr* storeHost) { +void MessageExtImpl::set_store_host(const struct sockaddr* storeHost) { store_host_ = copySocketAddress(store_host_, storeHost); } -const std::string& MessageExtImpl::getMsgId() const { +const std::string& MessageExtImpl::msg_id() const { return msg_id_; } -void MessageExtImpl::setMsgId(const std::string& msgId) { +void MessageExtImpl::set_msg_id(const std::string& msgId) { msg_id_ = msgId; } -int32_t MessageExtImpl::getReconsumeTimes() const { +int32_t MessageExtImpl::reconsume_times() const { return reconsume_times_; } -void MessageExtImpl::setReconsumeTimes(int32_t reconsumeTimes) { +void MessageExtImpl::set_reconsume_times(int32_t reconsumeTimes) { reconsume_times_ = reconsumeTimes; } -int64_t MessageExtImpl::getPreparedTransactionOffset() const { +int64_t MessageExtImpl::prepared_transaction_offset() const { return prepared_transaction_offset_; } -void MessageExtImpl::setPreparedTransactionOffset(int64_t preparedTransactionOffset) { +void MessageExtImpl::set_prepared_transaction_offset(int64_t preparedTransactionOffset) { prepared_transaction_offset_ = preparedTransactionOffset; } std::string MessageExtImpl::toString() const { std::stringstream ss; ss << "MessageExt [queueId=" << queue_id_ << ", storeSize=" << store_size_ << ", queueOffset=" << queue_offset_ - << ", sysFlag=" << sys_flag_ << ", bornTimestamp=" << born_timestamp_ << ", bornHost=" << getBornHostString() - << ", storeTimestamp=" << store_timestamp_ << ", storeHost=" << getStoreHostString() << ", msgId=" << getMsgId() + << ", sysFlag=" << sys_flag_ << ", bornTimestamp=" << born_timestamp_ << ", bornHost=" << born_host_string() + << ", storeTimestamp=" << store_timestamp_ << ", storeHost=" << store_host_string() << ", msgId=" << msg_id() << ", commitLogOffset=" << commit_log_offset_ << ", bodyCRC=" << body_crc_ << ", reconsumeTimes=" << reconsume_times_ << ", preparedTransactionOffset=" << prepared_transaction_offset_ << ", toString()=" << MessageImpl::toString() << "]"; @@ -193,22 +193,22 @@ std::string MessageExtImpl::toString() const { // MessageClientExtImpl // ============================ -const std::string& MessageClientExtImpl::getMsgId() const { +const std::string& MessageClientExtImpl::msg_id() const { const auto& unique_id = MessageClientIDSetter::getUniqID(*this); - return unique_id.empty() ? getOffsetMsgId() : unique_id; + return unique_id.empty() ? offset_msg_id() : unique_id; } -void MessageClientExtImpl::setMsgId(const std::string& msgId) { +void MessageClientExtImpl::set_msg_id(const std::string& msgId) { // DO NOTHING // MessageClientIDSetter::setUniqID(*this); } -const std::string& MessageClientExtImpl::getOffsetMsgId() const { - return MessageExtImpl::getMsgId(); +const std::string& MessageClientExtImpl::offset_msg_id() const { + return MessageExtImpl::msg_id(); } -void MessageClientExtImpl::setOffsetMsgId(const std::string& offsetMsgId) { - return MessageExtImpl::setMsgId(offsetMsgId); +void MessageClientExtImpl::set_offset_msg_id(const std::string& offsetMsgId) { + return MessageExtImpl::set_msg_id(offsetMsgId); } } // namespace rocketmq diff --git a/src/message/MessageExtImpl.h b/src/message/MessageExtImpl.h index af9e1ff7f..5d85ceae8 100644 --- a/src/message/MessageExtImpl.h +++ b/src/message/MessageExtImpl.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef ROCKETMQ_MESSAGE_MESSAGEEXT_H_ -#define ROCKETMQ_MESSAGE_MESSAGEEXT_H_ +#ifndef ROCKETMQ_MESSAGE_MESSAGEEXTIMPL_H_ +#define ROCKETMQ_MESSAGE_MESSAGEEXTIMPL_H_ #include "MessageExt.h" #include "MessageImpl.h" @@ -43,46 +43,46 @@ class MessageExtImpl : public MessageImpl, // base static TopicFilterType parseTopicFilterType(int32_t sysFlag); public: // MessageExt - int32_t getStoreSize() const override; - void setStoreSize(int32_t storeSize) override; + int32_t store_size() const override; + void set_store_size(int32_t storeSize) override; - int32_t getBodyCRC() const override; - void setBodyCRC(int32_t bodyCRC) override; + int32_t body_crc() const override; + void set_body_crc(int32_t bodyCRC) override; - int32_t getQueueId() const override; - void setQueueId(int32_t queueId) override; + int32_t queue_id() const override; + void set_queue_id(int32_t queueId) override; - int64_t getQueueOffset() const override; - void setQueueOffset(int64_t queueOffset) override; + int64_t queue_offset() const override; + void set_queue_offset(int64_t queueOffset) override; - int64_t getCommitLogOffset() const override; - void setCommitLogOffset(int64_t physicOffset) override; + int64_t commit_log_offset() const override; + void set_commit_log_offset(int64_t physicOffset) override; - int32_t getSysFlag() const override; - void setSysFlag(int32_t sysFlag) override; + int32_t sys_flag() const override; + void set_sys_flag(int32_t sysFlag) override; - int64_t getBornTimestamp() const override; - void setBornTimestamp(int64_t bornTimestamp) override; + int64_t born_timestamp() const override; + void set_born_timestamp(int64_t bornTimestamp) override; - const struct sockaddr* getBornHost() const override; - std::string getBornHostString() const override; - void setBornHost(const struct sockaddr* bornHost) override; + const struct sockaddr* born_host() const override; + std::string born_host_string() const override; + void set_born_host(const struct sockaddr* bornHost) override; - int64_t getStoreTimestamp() const override; - void setStoreTimestamp(int64_t storeTimestamp) override; + int64_t store_timestamp() const override; + void set_store_timestamp(int64_t storeTimestamp) override; - const struct sockaddr* getStoreHost() const override; - std::string getStoreHostString() const override; - void setStoreHost(const struct sockaddr* storeHost) override; + const struct sockaddr* store_host() const override; + std::string store_host_string() const override; + void set_store_host(const struct sockaddr* storeHost) override; - int32_t getReconsumeTimes() const override; - void setReconsumeTimes(int32_t reconsumeTimes) override; + int32_t reconsume_times() const override; + void set_reconsume_times(int32_t reconsumeTimes) override; - int64_t getPreparedTransactionOffset() const override; - void setPreparedTransactionOffset(int64_t preparedTransactionOffset) override; + int64_t prepared_transaction_offset() const override; + void set_prepared_transaction_offset(int64_t preparedTransactionOffset) override; - const std::string& getMsgId() const override; - void setMsgId(const std::string& msgId) override; + const std::string& msg_id() const override; + void set_msg_id(const std::string& msgId) override; std::string toString() const override; @@ -104,14 +104,14 @@ class MessageExtImpl : public MessageImpl, // base class MessageClientExtImpl : public MessageExtImpl { public: // MessageExt - const std::string& getMsgId() const override; - void setMsgId(const std::string& msgId) override; + const std::string& msg_id() const override; + void set_msg_id(const std::string& msgId) override; public: - const std::string& getOffsetMsgId() const; - void setOffsetMsgId(const std::string& offsetMsgId); + const std::string& offset_msg_id() const; + void set_offset_msg_id(const std::string& offsetMsgId); }; } // namespace rocketmq -#endif // ROCKETMQ_MESSAGE_MESSAGEEXT_H_ +#endif // ROCKETMQ_MESSAGE_MESSAGEEXTIMPL_H_ diff --git a/src/message/MessageImpl.cpp b/src/message/MessageImpl.cpp index 1738952b2..d24f8ba00 100644 --- a/src/message/MessageImpl.cpp +++ b/src/message/MessageImpl.cpp @@ -38,64 +38,48 @@ MessageImpl::MessageImpl(const std::string& topic, bool waitStoreMsgOK) : topic_(topic), flag_(flag), body_(body) { if (tags.length() > 0) { - setTags(tags); + set_tags(tags); } if (keys.length() > 0) { - setKeys(keys); + set_keys(keys); } - setWaitStoreMsgOK(waitStoreMsgOK); + set_wait_store_msg_ok(waitStoreMsgOK); } MessageImpl::~MessageImpl() = default; -const std::string& MessageImpl::getProperty(const std::string& name) const { - const auto& it = properties_.find(name); - if (it != properties_.end()) { - return it->second; - } - return null; -} - -void MessageImpl::putProperty(const std::string& name, const std::string& value) { - properties_[name] = value; -} - -void MessageImpl::clearProperty(const std::string& name) { - properties_.erase(name); -} - -const std::string& MessageImpl::getTopic() const { +const std::string& MessageImpl::topic() const { return topic_; } -void MessageImpl::setTopic(const std::string& topic) { +void MessageImpl::set_topic(const std::string& topic) { topic_ = topic; } -void MessageImpl::setTopic(const char* body, int len) { +void MessageImpl::set_topic(const char* topic, int len) { topic_.clear(); - topic_.append(body, len); + topic_.append(topic, len); } -const std::string& MessageImpl::getTags() const { +const std::string& MessageImpl::tags() const { return getProperty(MQMessageConst::PROPERTY_TAGS); } -void MessageImpl::setTags(const std::string& tags) { +void MessageImpl::set_tags(const std::string& tags) { putProperty(MQMessageConst::PROPERTY_TAGS, tags); } -const std::string& MessageImpl::getKeys() const { +const std::string& MessageImpl::keys() const { return getProperty(MQMessageConst::PROPERTY_KEYS); } -void MessageImpl::setKeys(const std::string& keys) { +void MessageImpl::set_keys(const std::string& keys) { putProperty(MQMessageConst::PROPERTY_KEYS, keys); } -void MessageImpl::setKeys(const std::vector& keys) { +void MessageImpl::set_keys(const std::vector& keys) { if (keys.empty()) { return; } @@ -108,10 +92,10 @@ void MessageImpl::setKeys(const std::vector& keys) { strKeys += *it; } - setKeys(strKeys); + set_keys(strKeys); } -int MessageImpl::getDelayTimeLevel() const { +int MessageImpl::delay_time_level() const { std::string tmp = getProperty(MQMessageConst::PROPERTY_DELAY_TIME_LEVEL); if (!tmp.empty()) { return atoi(tmp.c_str()); @@ -119,62 +103,78 @@ int MessageImpl::getDelayTimeLevel() const { return 0; } -void MessageImpl::setDelayTimeLevel(int level) { +void MessageImpl::set_delay_time_level(int level) { putProperty(MQMessageConst::PROPERTY_DELAY_TIME_LEVEL, UtilAll::to_string(level)); } -bool MessageImpl::isWaitStoreMsgOK() const { +bool MessageImpl::wait_store_msg_ok() const { std::string tmp = getProperty(MQMessageConst::PROPERTY_WAIT_STORE_MSG_OK); return tmp.empty() || UtilAll::stob(tmp); } -void MessageImpl::setWaitStoreMsgOK(bool waitStoreMsgOK) { +void MessageImpl::set_wait_store_msg_ok(bool waitStoreMsgOK) { putProperty(MQMessageConst::PROPERTY_WAIT_STORE_MSG_OK, UtilAll::to_string(waitStoreMsgOK)); } -int32_t MessageImpl::getFlag() const { +int32_t MessageImpl::flag() const { return flag_; } -void MessageImpl::setFlag(int32_t flag) { +void MessageImpl::set_flag(int32_t flag) { flag_ = flag; } -const std::string& MessageImpl::getBody() const { +const std::string& MessageImpl::body() const { return body_; } -void MessageImpl::setBody(const std::string& body) { +void MessageImpl::set_body(const std::string& body) { body_ = body; } -void MessageImpl::setBody(std::string&& body) { +void MessageImpl::set_body(std::string&& body) { body_ = std::move(body); } -const std::string& MessageImpl::getTransactionId() const { +const std::string& MessageImpl::transaction_id() const { return transaction_id_; } -void MessageImpl::setTransactionId(const std::string& transactionId) { +void MessageImpl::set_transaction_id(const std::string& transactionId) { transaction_id_ = transactionId; } -const std::map& MessageImpl::getProperties() const { +const std::map& MessageImpl::properties() const { return properties_; } -void MessageImpl::setProperties(const std::map& properties) { +void MessageImpl::set_properties(const std::map& properties) { properties_ = properties; } -void MessageImpl::setProperties(std::map&& properties) { +void MessageImpl::set_properties(std::map&& properties) { properties_ = std::move(properties); } +const std::string& MessageImpl::getProperty(const std::string& name) const { + const auto& it = properties_.find(name); + if (it != properties_.end()) { + return it->second; + } + return null; +} + +void MessageImpl::putProperty(const std::string& name, const std::string& value) { + properties_[name] = value; +} + +void MessageImpl::clearProperty(const std::string& name) { + properties_.erase(name); +} + std::string MessageImpl::toString() const { std::stringstream ss; - ss << "Message [topic=" << topic_ << ", flag=" << flag_ << ", tag=" << getTags() << ", transactionId='" + ss << "Message [topic=" << topic_ << ", flag=" << flag_ << ", tag=" << tags() << ", transactionId='" << transaction_id_ + "']"; return ss.str(); } diff --git a/src/message/MessageImpl.h b/src/message/MessageImpl.h index de83e5ee2..efe4977c1 100644 --- a/src/message/MessageImpl.h +++ b/src/message/MessageImpl.h @@ -44,36 +44,36 @@ class MessageImpl : public noncopyable, // base void putProperty(const std::string& name, const std::string& value) override; void clearProperty(const std::string& name) override; - const std::string& getTopic() const override; - void setTopic(const std::string& topic) override; - void setTopic(const char* body, int len) override; + const std::string& topic() const override; + void set_topic(const std::string& topic) override; + void set_topic(const char* body, int len) override; - const std::string& getTags() const override; - void setTags(const std::string& tags) override; + const std::string& tags() const override; + void set_tags(const std::string& tags) override; - const std::string& getKeys() const override; - void setKeys(const std::string& keys) override; - void setKeys(const std::vector& keys) override; + const std::string& keys() const override; + void set_keys(const std::string& keys) override; + void set_keys(const std::vector& keys) override; - int getDelayTimeLevel() const override; - void setDelayTimeLevel(int level) override; + int delay_time_level() const override; + void set_delay_time_level(int level) override; - bool isWaitStoreMsgOK() const override; - void setWaitStoreMsgOK(bool waitStoreMsgOK) override; + bool wait_store_msg_ok() const override; + void set_wait_store_msg_ok(bool waitStoreMsgOK) override; - int32_t getFlag() const override; - void setFlag(int32_t flag) override; + int32_t flag() const override; + void set_flag(int32_t flag) override; - const std::string& getBody() const override; - void setBody(const std::string& body) override; - void setBody(std::string&& body) override; + const std::string& body() const override; + void set_body(const std::string& body) override; + void set_body(std::string&& body) override; - const std::string& getTransactionId() const override; - void setTransactionId(const std::string& transactionId) override; + const std::string& transaction_id() const override; + void set_transaction_id(const std::string& transactionId) override; - const std::map& getProperties() const override; - void setProperties(const std::map& properties) override; - void setProperties(std::map&& properties) override; + const std::map& properties() const override; + void set_properties(const std::map& properties) override; + void set_properties(std::map&& properties) override; std::string toString() const override; diff --git a/src/producer/DefaultMQProducer.cpp b/src/producer/DefaultMQProducer.cpp index f4c61f468..89fd57a8d 100644 --- a/src/producer/DefaultMQProducer.cpp +++ b/src/producer/DefaultMQProducer.cpp @@ -33,9 +33,9 @@ DefaultMQProducer::DefaultMQProducer(const std::string& groupname, : DefaultMQProducerConfigProxy(producerConfig), producer_impl_(nullptr) { // set default group name if (groupname.empty()) { - setGroupName(DEFAULT_PRODUCER_GROUP); + set_group_name(DEFAULT_PRODUCER_GROUP); } else { - setGroupName(groupname); + set_group_name(groupname); } // create DefaultMQProducerImpl @@ -69,7 +69,7 @@ SendResult DefaultMQProducer::send(MQMessage& msg, const MQMessageQueue& mq, lon } void DefaultMQProducer::send(MQMessage& msg, SendCallback* sendCallback) noexcept { - producer_impl_->send(msg, sendCallback, getSendMsgTimeout()); + producer_impl_->send(msg, sendCallback, send_msg_timeout()); } void DefaultMQProducer::send(MQMessage& msg, SendCallback* sendCallback, long timeout) noexcept { @@ -174,11 +174,11 @@ void DefaultMQProducer::request(MQMessage& msg, producer_impl_->request(msg, selector, arg, requestCallback, timeout); } -bool DefaultMQProducer::isSendLatencyFaultEnable() const { +bool DefaultMQProducer::send_latency_fault_enable() const { return dynamic_cast(producer_impl_.get())->isSendLatencyFaultEnable(); } -void DefaultMQProducer::setSendLatencyFaultEnable(bool sendLatencyFaultEnable) { +void DefaultMQProducer::set_send_latency_fault_enable(bool sendLatencyFaultEnable) { dynamic_cast(producer_impl_.get())->setSendLatencyFaultEnable(sendLatencyFaultEnable); } diff --git a/src/producer/DefaultMQProducerConfigImpl.hpp b/src/producer/DefaultMQProducerConfigImpl.hpp index 11d822385..5b1f78d3b 100644 --- a/src/producer/DefaultMQProducerConfigImpl.hpp +++ b/src/producer/DefaultMQProducerConfigImpl.hpp @@ -40,32 +40,32 @@ class DefaultMQProducerConfigImpl : virtual public DefaultMQProducerConfig, publ virtual ~DefaultMQProducerConfigImpl() = default; - int getMaxMessageSize() const override { return max_message_size_; } - void setMaxMessageSize(int maxMessageSize) override { max_message_size_ = maxMessageSize; } + int max_message_size() const override { return max_message_size_; } + void set_max_message_size(int maxMessageSize) override { max_message_size_ = maxMessageSize; } - int getCompressMsgBodyOverHowmuch() const override { return compress_msg_body_over_howmuch_; } - void setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch) override { + int compress_msg_body_over_howmuch() const override { return compress_msg_body_over_howmuch_; } + void set_compress_msg_body_over_howmuch(int compressMsgBodyOverHowmuch) override { compress_msg_body_over_howmuch_ = compressMsgBodyOverHowmuch; } - int getCompressLevel() const override { return compress_level_; } - void setCompressLevel(int compressLevel) override { + int compress_level() const override { return compress_level_; } + void set_compress_level(int compressLevel) override { if ((compressLevel >= 0 && compressLevel <= 9) || compressLevel == -1) { compress_level_ = compressLevel; } } - int getSendMsgTimeout() const override { return send_msg_timeout_; } - void setSendMsgTimeout(int sendMsgTimeout) override { send_msg_timeout_ = sendMsgTimeout; } + int send_msg_timeout() const override { return send_msg_timeout_; } + void set_send_msg_timeout(int sendMsgTimeout) override { send_msg_timeout_ = sendMsgTimeout; } - int getRetryTimes() const override { return retry_times_; } - void setRetryTimes(int times) override { retry_times_ = std::min(std::max(0, times), 15); } + int retry_times() const override { return retry_times_; } + void set_retry_times(int times) override { retry_times_ = std::min(std::max(0, times), 15); } - int getRetryTimesForAsync() const override { return retry_times_for_async_; } - void setRetryTimesForAsync(int times) override { retry_times_for_async_ = std::min(std::max(0, times), 15); } + int retry_times_for_async() const override { return retry_times_for_async_; } + void set_retry_times_for_async(int times) override { retry_times_for_async_ = std::min(std::max(0, times), 15); } - bool isRetryAnotherBrokerWhenNotStoreOK() const override { return retry_another_broker_when_not_store_ok_; } - void setRetryAnotherBrokerWhenNotStoreOK(bool retryAnotherBrokerWhenNotStoreOK) override { + bool retry_another_broker_when_not_store_ok() const override { return retry_another_broker_when_not_store_ok_; } + void set_retry_another_broker_when_not_store_ok(bool retryAnotherBrokerWhenNotStoreOK) override { retry_another_broker_when_not_store_ok_ = retryAnotherBrokerWhenNotStoreOK; } diff --git a/src/producer/DefaultMQProducerImpl.cpp b/src/producer/DefaultMQProducerImpl.cpp index 3c6b9e3a5..b33d05262 100644 --- a/src/producer/DefaultMQProducerImpl.cpp +++ b/src/producer/DefaultMQProducerImpl.cpp @@ -106,7 +106,7 @@ void DefaultMQProducerImpl::start() { switch (service_state_) { case CREATE_JUST: { - LOG_INFO_NEW("DefaultMQProducerImpl: {} start", client_config_->getGroupName()); + LOG_INFO_NEW("DefaultMQProducerImpl: {} start", client_config_->group_name()); service_state_ = START_FAILED; @@ -115,17 +115,17 @@ void DefaultMQProducerImpl::start() { MQClientImpl::start(); bool registerOK = client_instance_->registerProducer( - dynamic_cast(client_config_.get())->getGroupName(), this); + dynamic_cast(client_config_.get())->group_name(), this); if (!registerOK) { service_state_ = CREATE_JUST; - THROW_MQEXCEPTION(MQClientException, "The producer group[" + client_config_->getGroupName() + + THROW_MQEXCEPTION(MQClientException, "The producer group[" + client_config_->group_name() + "] has been created before, specify another name please.", -1); } client_instance_->start(); - LOG_INFO_NEW("the producer [{}] start OK.", client_config_->getGroupName()); + LOG_INFO_NEW("the producer [{}] start OK.", client_config_->group_name()); service_state_ = RUNNING; break; } @@ -145,7 +145,7 @@ void DefaultMQProducerImpl::shutdown() { switch (service_state_) { case RUNNING: { LOG_INFO("DefaultMQProducerImpl shutdown"); - client_instance_->unregisterProducer(client_config_->getGroupName()); + client_instance_->unregisterProducer(client_config_->group_name()); client_instance_->shutdown(); service_state_ = SHUTDOWN_ALREADY; @@ -160,7 +160,7 @@ void DefaultMQProducerImpl::shutdown() { } SendResult DefaultMQProducerImpl::send(MQMessage& msg) { - return send(msg, dynamic_cast(client_config_.get())->getSendMsgTimeout()); + return send(msg, dynamic_cast(client_config_.get())->send_msg_timeout()); } SendResult DefaultMQProducerImpl::send(MQMessage& msg, long timeout) { @@ -174,13 +174,13 @@ SendResult DefaultMQProducerImpl::send(MQMessage& msg, long timeout) { } SendResult DefaultMQProducerImpl::send(MQMessage& msg, const MQMessageQueue& mq) { - return send(msg, mq, dynamic_cast(client_config_.get())->getSendMsgTimeout()); + return send(msg, mq, dynamic_cast(client_config_.get())->send_msg_timeout()); } SendResult DefaultMQProducerImpl::send(MQMessage& msg, const MQMessageQueue& mq, long timeout) { - Validators::checkMessage(msg, dynamic_cast(client_config_.get())->getMaxMessageSize()); + Validators::checkMessage(msg, dynamic_cast(client_config_.get())->max_message_size()); - if (msg.getTopic() != mq.topic()) { + if (msg.topic() != mq.topic()) { THROW_MQEXCEPTION(MQClientException, "message's topic not equal mq's topic", -1); } @@ -194,7 +194,7 @@ SendResult DefaultMQProducerImpl::send(MQMessage& msg, const MQMessageQueue& mq, } void DefaultMQProducerImpl::send(MQMessage& msg, SendCallback* sendCallback) noexcept { - return send(msg, sendCallback, dynamic_cast(client_config_.get())->getSendMsgTimeout()); + return send(msg, sendCallback, dynamic_cast(client_config_.get())->send_msg_timeout()); } void DefaultMQProducerImpl::send(MQMessage& msg, SendCallback* sendCallback, long timeout) noexcept { @@ -213,7 +213,7 @@ void DefaultMQProducerImpl::send(MQMessage& msg, SendCallback* sendCallback, lon } void DefaultMQProducerImpl::send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept { - return send(msg, mq, sendCallback, dynamic_cast(client_config_.get())->getSendMsgTimeout()); + return send(msg, mq, sendCallback, dynamic_cast(client_config_.get())->send_msg_timeout()); } void DefaultMQProducerImpl::send(MQMessage& msg, @@ -221,9 +221,9 @@ void DefaultMQProducerImpl::send(MQMessage& msg, SendCallback* sendCallback, long timeout) noexcept { try { - Validators::checkMessage(msg, dynamic_cast(client_config_.get())->getMaxMessageSize()); + Validators::checkMessage(msg, dynamic_cast(client_config_.get())->max_message_size()); - if (msg.getTopic() != mq.topic()) { + if (msg.topic() != mq.topic()) { THROW_MQEXCEPTION(MQClientException, "message's topic not equal mq's topic", -1); } @@ -248,7 +248,7 @@ void DefaultMQProducerImpl::send(MQMessage& msg, void DefaultMQProducerImpl::sendOneway(MQMessage& msg) { try { sendDefaultImpl(msg.getMessageImpl(), ONEWAY, nullptr, - dynamic_cast(client_config_.get())->getSendMsgTimeout()); + dynamic_cast(client_config_.get())->send_msg_timeout()); } catch (MQBrokerException& e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); @@ -256,15 +256,15 @@ void DefaultMQProducerImpl::sendOneway(MQMessage& msg) { } void DefaultMQProducerImpl::sendOneway(MQMessage& msg, const MQMessageQueue& mq) { - Validators::checkMessage(msg, dynamic_cast(client_config_.get())->getMaxMessageSize()); + Validators::checkMessage(msg, dynamic_cast(client_config_.get())->max_message_size()); - if (msg.getTopic() != mq.topic()) { + if (msg.topic() != mq.topic()) { THROW_MQEXCEPTION(MQClientException, "message's topic not equal mq's topic", -1); } try { sendKernelImpl(msg.getMessageImpl(), mq, ONEWAY, nullptr, nullptr, - dynamic_cast(client_config_.get())->getSendMsgTimeout()); + dynamic_cast(client_config_.get())->send_msg_timeout()); } catch (MQBrokerException& e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); @@ -272,7 +272,7 @@ void DefaultMQProducerImpl::sendOneway(MQMessage& msg, const MQMessageQueue& mq) } SendResult DefaultMQProducerImpl::send(MQMessage& msg, MessageQueueSelector* selector, void* arg) { - return send(msg, selector, arg, dynamic_cast(client_config_.get())->getSendMsgTimeout()); + return send(msg, selector, arg, dynamic_cast(client_config_.get())->send_msg_timeout()); } SendResult DefaultMQProducerImpl::send(MQMessage& msg, MessageQueueSelector* selector, void* arg, long timeout) { @@ -290,7 +290,7 @@ void DefaultMQProducerImpl::send(MQMessage& msg, void* arg, SendCallback* sendCallback) noexcept { return send(msg, selector, arg, sendCallback, - dynamic_cast(client_config_.get())->getSendMsgTimeout()); + dynamic_cast(client_config_.get())->send_msg_timeout()); } void DefaultMQProducerImpl::send(MQMessage& msg, @@ -320,7 +320,7 @@ void DefaultMQProducerImpl::send(MQMessage& msg, void DefaultMQProducerImpl::sendOneway(MQMessage& msg, MessageQueueSelector* selector, void* arg) { try { sendSelectImpl(msg.getMessageImpl(), selector, arg, ONEWAY, nullptr, - dynamic_cast(client_config_.get())->getSendMsgTimeout()); + dynamic_cast(client_config_.get())->send_msg_timeout()); } catch (MQBrokerException& e) { std::string info = std::string("unknown exception, ") + e.what(); THROW_MQEXCEPTION(MQClientException, info, e.GetError()); @@ -330,7 +330,7 @@ void DefaultMQProducerImpl::sendOneway(MQMessage& msg, MessageQueueSelector* sel TransactionSendResult DefaultMQProducerImpl::sendMessageInTransaction(MQMessage& msg, void* arg) { try { std::unique_ptr sendResult(sendMessageInTransactionImpl( - msg.getMessageImpl(), arg, dynamic_cast(client_config_.get())->getSendMsgTimeout())); + msg.getMessageImpl(), arg, dynamic_cast(client_config_.get())->send_msg_timeout())); return *sendResult; } catch (MQException& e) { LOG_ERROR_NEW("sendMessageInTransaction failed, exception:{}", e.what()); @@ -367,10 +367,10 @@ MessagePtr DefaultMQProducerImpl::batch(std::vector& msgs) { auto messageBatch = MessageBatch::generateFromList(msgs); for (auto& message : messageBatch->messages()) { Validators::checkMessage(message, - dynamic_cast(client_config_.get())->getMaxMessageSize()); + dynamic_cast(client_config_.get())->max_message_size()); MessageClientIDSetter::setUniqID(const_cast(message)); } - messageBatch->setBody(messageBatch->encode()); + messageBatch->set_body(messageBatch->encode()); return messageBatch; } catch (std::exception& e) { THROW_MQEXCEPTION(MQClientException, "Failed to initiate the MessageBatch", -1); @@ -395,11 +395,11 @@ MQMessage DefaultMQProducerImpl::request(MQMessage& msg, long timeout) { responseMessage = requestResponseFuture->waitResponseMessage(timeout - cost); if (responseMessage == nullptr) { if (requestResponseFuture->send_request_ok()) { - std::string info = "send request message to <" + msg.getTopic() + "> OK, but wait reply message timeout, " + + std::string info = "send request message to <" + msg.topic() + "> OK, but wait reply message timeout, " + UtilAll::to_string(timeout) + " ms."; THROW_MQEXCEPTION(RequestTimeoutException, info, ClientErrorCode::REQUEST_TIMEOUT_EXCEPTION); } else { - std::string info = "send request message to <" + msg.getTopic() + "> fail"; + std::string info = "send request message to <" + msg.topic() + "> fail"; THROW_MQEXCEPTION2(MQClientException, info, -1, requestResponseFuture->cause()); } } @@ -448,11 +448,11 @@ MQMessage DefaultMQProducerImpl::request(MQMessage& msg, const MQMessageQueue& m responseMessage = requestResponseFuture->waitResponseMessage(timeout - cost); if (responseMessage == nullptr) { if (requestResponseFuture->send_request_ok()) { - std::string info = "send request message to <" + msg.getTopic() + "> OK, but wait reply message timeout, " + + std::string info = "send request message to <" + msg.topic() + "> OK, but wait reply message timeout, " + UtilAll::to_string(timeout) + " ms."; THROW_MQEXCEPTION(RequestTimeoutException, info, ClientErrorCode::REQUEST_TIMEOUT_EXCEPTION); } else { - std::string info = "send request message to <" + msg.getTopic() + "> fail"; + std::string info = "send request message to <" + msg.topic() + "> fail"; THROW_MQEXCEPTION2(MQClientException, info, -1, requestResponseFuture->cause()); } } @@ -504,11 +504,11 @@ MQMessage DefaultMQProducerImpl::request(MQMessage& msg, MessageQueueSelector* s responseMessage = requestResponseFuture->waitResponseMessage(timeout - cost); if (responseMessage == nullptr) { if (requestResponseFuture->send_request_ok()) { - std::string info = "send request message to <" + msg.getTopic() + "> OK, but wait reply message timeout, " + + std::string info = "send request message to <" + msg.topic() + "> OK, but wait reply message timeout, " + UtilAll::to_string(timeout) + " ms."; THROW_MQEXCEPTION(RequestTimeoutException, info, ClientErrorCode::REQUEST_TIMEOUT_EXCEPTION); } else { - std::string info = "send request message to <" + msg.getTopic() + "> fail"; + std::string info = "send request message to <" + msg.topic() + "> fail"; THROW_MQEXCEPTION2(MQClientException, info, -1, requestResponseFuture->cause()); } } @@ -550,14 +550,14 @@ void DefaultMQProducerImpl::prepareSendRequest(Message& msg, long timeout) { MessageAccessor::putProperty(msg, MQMessageConst::PROPERTY_MESSAGE_REPLY_TO_CLIENT, requestClientId); MessageAccessor::putProperty(msg, MQMessageConst::PROPERTY_MESSAGE_TTL, UtilAll::to_string(timeout)); - auto hasRouteData = client_instance_->getTopicRouteData(msg.getTopic()) != nullptr; + auto hasRouteData = client_instance_->getTopicRouteData(msg.topic()) != nullptr; if (!hasRouteData) { auto beginTimestamp = UtilAll::currentTimeMillis(); - client_instance_->tryToFindTopicPublishInfo(msg.getTopic()); + client_instance_->tryToFindTopicPublishInfo(msg.topic()); client_instance_->sendHeartbeatToAllBrokerWithLock(); auto cost = UtilAll::currentTimeMillis() - beginTimestamp; if (cost > 500) { - LOG_WARN_NEW("prepare send request for <{}> cost {} ms", msg.getTopic(), cost); + LOG_WARN_NEW("prepare send request for <{}> cost {} ms", msg.topic(), cost); } } } @@ -566,17 +566,17 @@ SendResult* DefaultMQProducerImpl::sendDefaultImpl(MessagePtr msg, CommunicationMode communicationMode, SendCallback* sendCallback, long timeout) { - Validators::checkMessage(*msg, dynamic_cast(client_config_.get())->getMaxMessageSize()); + Validators::checkMessage(*msg, dynamic_cast(client_config_.get())->max_message_size()); uint64_t beginTimestampFirst = UtilAll::currentTimeMillis(); uint64_t beginTimestampPrev = beginTimestampFirst; uint64_t endTimestamp = beginTimestampFirst; - auto topicPublishInfo = client_instance_->tryToFindTopicPublishInfo(msg->getTopic()); + auto topicPublishInfo = client_instance_->tryToFindTopicPublishInfo(msg->topic()); if (topicPublishInfo != nullptr && topicPublishInfo->ok()) { bool callTimeout = false; std::unique_ptr sendResult; int timesTotal = communicationMode == CommunicationMode::SYNC - ? 1 + dynamic_cast(client_config_.get())->getRetryTimes() + ? 1 + dynamic_cast(client_config_.get())->retry_times() : 1; int times = 0; std::string lastBrokerName; @@ -607,8 +607,9 @@ SendResult* DefaultMQProducerImpl::sendDefaultImpl(MessagePtr msg, case ONEWAY: return nullptr; case SYNC: - if (sendResult->getSendStatus() != SEND_OK) { - if (dynamic_cast(client_config_.get())->isRetryAnotherBrokerWhenNotStoreOK()) { + if (sendResult->send_status() != SEND_OK) { + if (dynamic_cast(client_config_.get()) + ->retry_another_broker_when_not_store_ok()) { continue; } } @@ -633,11 +634,11 @@ SendResult* DefaultMQProducerImpl::sendDefaultImpl(MessagePtr msg, std::string info = "Send [" + UtilAll::to_string(times) + "] times, still failed, cost [" + UtilAll::to_string(UtilAll::currentTimeMillis() - beginTimestampFirst) + "]ms, Topic: " + - msg->getTopic(); + msg->topic(); THROW_MQEXCEPTION(MQClientException, info, -1); } - THROW_MQEXCEPTION(MQClientException, "No route info of this topic: " + msg->getTopic(), -1); + THROW_MQEXCEPTION(MQClientException, "No route info of this topic: " + msg->topic(), -1); } const MQMessageQueue& DefaultMQProducerImpl::selectOneMessageQueue(const TopicPublishInfo* tpInfo, @@ -685,15 +686,15 @@ SendResult* DefaultMQProducerImpl::sendKernelImpl(MessagePtr msg, // TOOD: send message hook std::unique_ptr requestHeader(new SendMessageRequestHeader()); - requestHeader->producerGroup = client_config_->getGroupName(); - requestHeader->topic = msg->getTopic(); + requestHeader->producerGroup = client_config_->group_name(); + requestHeader->topic = msg->topic(); requestHeader->defaultTopic = AUTO_CREATE_TOPIC_KEY_TOPIC; requestHeader->defaultTopicQueueNums = 4; requestHeader->queueId = mq.queue_id(); requestHeader->sysFlag = sysFlag; requestHeader->bornTimestamp = UtilAll::currentTimeMillis(); - requestHeader->flag = msg->getFlag(); - requestHeader->properties = MessageDecoder::messageProperties2String(msg->getProperties()); + requestHeader->flag = msg->flag(); + requestHeader->properties = MessageDecoder::messageProperties2String(msg->properties()); requestHeader->reconsumeTimes = 0; requestHeader->unitMode = false; requestHeader->batch = msg->isBatch(); @@ -722,7 +723,7 @@ SendResult* DefaultMQProducerImpl::sendKernelImpl(MessagePtr msg, sendResult = client_instance_->getMQClientAPIImpl()->sendMessage( brokerAddr, mq.broker_name(), msg, std::move(requestHeader), timeout, communicationMode, sendCallback, topicPublishInfo, client_instance_, - dynamic_cast(client_config_.get())->getRetryTimesForAsync(), + dynamic_cast(client_config_.get())->retry_times_for_async(), shared_from_this()); } break; case ONEWAY: @@ -760,12 +761,12 @@ bool DefaultMQProducerImpl::tryToCompressMessage(Message& msg) { return true; } - const auto& body = msg.getBody(); - if (body.size() >= dynamic_cast(client_config_.get())->getCompressMsgBodyOverHowmuch()) { + const auto& body = msg.body(); + if (body.size() >= dynamic_cast(client_config_.get())->compress_msg_body_over_howmuch()) { std::string out_body; if (UtilAll::deflate(body, out_body, - dynamic_cast(client_config_.get())->getCompressLevel())) { - msg.setBody(std::move(out_body)); + dynamic_cast(client_config_.get())->compress_level())) { + msg.set_body(std::move(out_body)); msg.putProperty(MQMessageConst::PROPERTY_ALREADY_COMPRESSED_FLAG, "true"); return true; } @@ -781,9 +782,9 @@ SendResult* DefaultMQProducerImpl::sendSelectImpl(MessagePtr msg, SendCallback* sendCallback, long timeout) { auto beginStartTime = UtilAll::currentTimeMillis(); - Validators::checkMessage(*msg, dynamic_cast(client_config_.get())->getMaxMessageSize()); + Validators::checkMessage(*msg, dynamic_cast(client_config_.get())->max_message_size()); - TopicPublishInfoPtr topicPublishInfo = client_instance_->tryToFindTopicPublishInfo(msg->getTopic()); + TopicPublishInfoPtr topicPublishInfo = client_instance_->tryToFindTopicPublishInfo(msg->topic()); if (topicPublishInfo != nullptr && topicPublishInfo->ok()) { MQMessageQueue mq = selector->select(topicPublishInfo->getMessageQueueList(), MQMessage(msg), arg); @@ -795,7 +796,7 @@ SendResult* DefaultMQProducerImpl::sendSelectImpl(MessagePtr msg, return sendKernelImpl(msg, mq, communicationMode, sendCallback, nullptr, timeout - costTime); } - std::string info = std::string("No route info for this topic, ") + msg->getTopic(); + std::string info = std::string("No route info for this topic, ") + msg->topic(); THROW_MQEXCEPTION(MQClientException, info, -1); } @@ -826,7 +827,7 @@ TransactionSendResult* DefaultMQProducerImpl::sendMessageInTransactionImpl(Messa std::unique_ptr sendResult; MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_TRANSACTION_PREPARED, "true"); - MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_PRODUCER_GROUP, client_config_->getGroupName()); + MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_PRODUCER_GROUP, client_config_->group_name()); try { sendResult.reset(sendDefaultImpl(msg, SYNC, nullptr, timeout)); } catch (MQException& e) { @@ -835,15 +836,15 @@ TransactionSendResult* DefaultMQProducerImpl::sendMessageInTransactionImpl(Messa LocalTransactionState localTransactionState = LocalTransactionState::UNKNOWN; std::exception_ptr localException; - switch (sendResult->getSendStatus()) { + switch (sendResult->send_status()) { case SendStatus::SEND_OK: try { - if (!sendResult->getTransactionId().empty()) { - msg->putProperty("__transactionId__", sendResult->getTransactionId()); + if (!sendResult->transaction_id().empty()) { + msg->putProperty("__transactionId__", sendResult->transaction_id()); } const auto& transactionId = msg->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX); if (!transactionId.empty()) { - msg->setTransactionId(transactionId); + msg->set_transaction_id(transactionId); } localTransactionState = transactionListener->executeLocalTransaction(MQMessage(msg), arg); if (localTransactionState != LocalTransactionState::COMMIT_MESSAGE) { @@ -873,18 +874,18 @@ TransactionSendResult* DefaultMQProducerImpl::sendMessageInTransactionImpl(Messa // FIXME: setTransactionId will cause OOM? TransactionSendResult* transactionSendResult = new TransactionSendResult(*sendResult.get()); - transactionSendResult->setTransactionId(msg->getTransactionId()); - transactionSendResult->setLocalTransactionState(localTransactionState); + transactionSendResult->set_transaction_id(msg->transaction_id()); + transactionSendResult->set_local_transaction_state(localTransactionState); return transactionSendResult; } void DefaultMQProducerImpl::endTransaction(SendResult& sendResult, LocalTransactionState localTransactionState, std::exception_ptr& localException) { - const auto& msg_id = !sendResult.getOffsetMsgId().empty() ? sendResult.getOffsetMsgId() : sendResult.getMsgId(); + const auto& msg_id = !sendResult.offset_msg_id().empty() ? sendResult.offset_msg_id() : sendResult.msg_id(); auto id = MessageDecoder::decodeMessageId(msg_id); - const auto& transactionId = sendResult.getTransactionId(); - std::string brokerAddr = client_instance_->findBrokerAddressInPublish(sendResult.getMessageQueue().broker_name()); + const auto& transactionId = sendResult.transaction_id(); + std::string brokerAddr = client_instance_->findBrokerAddressInPublish(sendResult.message_queue().broker_name()); EndTransactionRequestHeader* requestHeader = new EndTransactionRequestHeader(); requestHeader->transactionId = transactionId; requestHeader->commitLogOffset = id.getOffset(); @@ -902,9 +903,9 @@ void DefaultMQProducerImpl::endTransaction(SendResult& sendResult, break; } - requestHeader->producerGroup = client_config_->getGroupName(); - requestHeader->tranStateTableOffset = sendResult.getQueueOffset(); - requestHeader->msgId = sendResult.getMsgId(); + requestHeader->producerGroup = client_config_->group_name(); + requestHeader->tranStateTableOffset = sendResult.queue_offset(); + requestHeader->msgId = sendResult.msg_id(); std::string remark = localException ? ("executeLocalTransactionBranch exception: " + UtilAll::to_string(localException)) : null; @@ -936,7 +937,7 @@ void DefaultMQProducerImpl::checkTransactionStateImpl(const std::string& addr, auto* transactionCheckListener = getCheckListener(); if (nullptr == transactionCheckListener) { LOG_WARN_NEW("CheckTransactionState, pick transactionCheckListener by group[{}] failed", - client_config_->getGroupName()); + client_config_->group_name()); return; } @@ -951,13 +952,13 @@ void DefaultMQProducerImpl::checkTransactionStateImpl(const std::string& addr, EndTransactionRequestHeader* endHeader = new EndTransactionRequestHeader(); endHeader->commitLogOffset = commitLogOffset; - endHeader->producerGroup = client_config_->getGroupName(); + endHeader->producerGroup = client_config_->group_name(); endHeader->tranStateTableOffset = tranStateTableOffset; endHeader->fromTransactionCheck = true; std::string uniqueKey = message->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX); if (uniqueKey.empty()) { - uniqueKey = message->getMsgId(); + uniqueKey = message->msg_id(); } endHeader->msgId = uniqueKey; diff --git a/test/src/common/ClientRPCHookTest.cpp b/test/src/common/ClientRPCHookTest.cpp index 02ce84343..e454f4224 100644 --- a/test/src/common/ClientRPCHookTest.cpp +++ b/test/src/common/ClientRPCHookTest.cpp @@ -35,9 +35,9 @@ using rocketmq::SessionCredentials; TEST(ClientRPCHookTest, BeforeRequest) { SessionCredentials sessionCredentials; - sessionCredentials.setAccessKey("accessKey"); - sessionCredentials.setSecretKey("secretKey"); - sessionCredentials.setAuthChannel("onsChannel"); + sessionCredentials.set_access_key("accessKey"); + sessionCredentials.set_secret_key("secretKey"); + sessionCredentials.set_auth_channel("onsChannel"); ClientRPCHook clientRPCHook(sessionCredentials); diff --git a/test/src/extern/CMessageExtTest.cpp b/test/src/extern/CMessageExtTest.cpp index 442ae5768..02218cae7 100644 --- a/test/src/extern/CMessageExtTest.cpp +++ b/test/src/extern/CMessageExtTest.cpp @@ -32,50 +32,50 @@ TEST(CMessageExtTest, CheckProperties) { MQMessageExt* mqMessageExt = new MQMessageExt(); CMessageExt* messageExt = (CMessageExt*)mqMessageExt; - mqMessageExt->setTopic("testTopic"); - EXPECT_EQ(GetMessageTopic(messageExt), mqMessageExt->getTopic()); + mqMessageExt->set_topic("testTopic"); + EXPECT_EQ(GetMessageTopic(messageExt), mqMessageExt->topic()); - mqMessageExt->setTags("testTags"); - EXPECT_EQ(GetMessageTags(messageExt), mqMessageExt->getTags()); + mqMessageExt->set_tags("testTags"); + EXPECT_EQ(GetMessageTags(messageExt), mqMessageExt->tags()); - mqMessageExt->setKeys("testKeys"); - EXPECT_EQ(GetMessageKeys(messageExt), mqMessageExt->getKeys()); + mqMessageExt->set_keys("testKeys"); + EXPECT_EQ(GetMessageKeys(messageExt), mqMessageExt->keys()); - mqMessageExt->setBody("testBody"); - EXPECT_EQ(GetMessageBody(messageExt), mqMessageExt->getBody()); + mqMessageExt->set_body("testBody"); + EXPECT_EQ(GetMessageBody(messageExt), mqMessageExt->body()); mqMessageExt->putProperty("testProperty", "testValue"); EXPECT_EQ(GetMessageProperty(messageExt, "testProperty"), mqMessageExt->getProperty("testProperty")); - mqMessageExt->setMsgId("msgId123456"); - EXPECT_EQ(GetMessageId(messageExt), mqMessageExt->getMsgId()); + mqMessageExt->set_msg_id("msgId123456"); + EXPECT_EQ(GetMessageId(messageExt), mqMessageExt->msg_id()); - mqMessageExt->setDelayTimeLevel(1); - EXPECT_EQ(GetMessageDelayTimeLevel(messageExt), mqMessageExt->getDelayTimeLevel()); + mqMessageExt->set_delay_time_level(1); + EXPECT_EQ(GetMessageDelayTimeLevel(messageExt), mqMessageExt->delay_time_level()); - mqMessageExt->setQueueId(4); - EXPECT_EQ(GetMessageQueueId(messageExt), mqMessageExt->getQueueId()); + mqMessageExt->set_queue_id(4); + EXPECT_EQ(GetMessageQueueId(messageExt), mqMessageExt->queue_id()); - mqMessageExt->setReconsumeTimes(1234567); - EXPECT_EQ(GetMessageReconsumeTimes(messageExt), mqMessageExt->getReconsumeTimes()); + mqMessageExt->set_reconsume_times(1234567); + EXPECT_EQ(GetMessageReconsumeTimes(messageExt), mqMessageExt->reconsume_times()); - mqMessageExt->setStoreSize(127); - EXPECT_EQ(GetMessageStoreSize(messageExt), mqMessageExt->getStoreSize()); + mqMessageExt->set_store_size(127); + EXPECT_EQ(GetMessageStoreSize(messageExt), mqMessageExt->store_size()); - mqMessageExt->setBornTimestamp(9876543); - EXPECT_EQ(GetMessageBornTimestamp(messageExt), mqMessageExt->getBornTimestamp()); + mqMessageExt->set_born_timestamp(9876543); + EXPECT_EQ(GetMessageBornTimestamp(messageExt), mqMessageExt->born_timestamp()); - mqMessageExt->setStoreTimestamp(123123); - EXPECT_EQ(GetMessageStoreTimestamp(messageExt), mqMessageExt->getStoreTimestamp()); + mqMessageExt->set_store_timestamp(123123); + EXPECT_EQ(GetMessageStoreTimestamp(messageExt), mqMessageExt->store_timestamp()); - mqMessageExt->setQueueOffset(1024); - EXPECT_EQ(GetMessageQueueOffset(messageExt), mqMessageExt->getQueueOffset()); + mqMessageExt->set_queue_offset(1024); + EXPECT_EQ(GetMessageQueueOffset(messageExt), mqMessageExt->queue_offset()); - mqMessageExt->setCommitLogOffset(2048); - EXPECT_EQ(GetMessageCommitLogOffset(messageExt), mqMessageExt->getCommitLogOffset()); + mqMessageExt->set_commit_log_offset(2048); + EXPECT_EQ(GetMessageCommitLogOffset(messageExt), mqMessageExt->commit_log_offset()); - mqMessageExt->setPreparedTransactionOffset(4096); - EXPECT_EQ(GetMessagePreparedTransactionOffset(messageExt), mqMessageExt->getPreparedTransactionOffset()); + mqMessageExt->set_prepared_transaction_offset(4096); + EXPECT_EQ(GetMessagePreparedTransactionOffset(messageExt), mqMessageExt->prepared_transaction_offset()); delete mqMessageExt; } diff --git a/test/src/extern/CMessageTest.cpp b/test/src/extern/CMessageTest.cpp index 446c3d88b..4956c390f 100644 --- a/test/src/extern/CMessageTest.cpp +++ b/test/src/extern/CMessageTest.cpp @@ -30,34 +30,34 @@ using rocketmq::MQMessage; TEST(CMessagesTest, CheckProperties) { CMessage* message = CreateMessage(NULL); MQMessage* mqMessage = (MQMessage*)message; - EXPECT_EQ(mqMessage->getTopic(), ""); + EXPECT_EQ(mqMessage->topic(), ""); SetMessageTopic(message, "testTopic"); - EXPECT_EQ(mqMessage->getTopic(), "testTopic"); + EXPECT_EQ(mqMessage->topic(), "testTopic"); SetMessageTags(message, "testTags"); - EXPECT_EQ(mqMessage->getTags(), "testTags"); + EXPECT_EQ(mqMessage->tags(), "testTags"); SetMessageKeys(message, "testKeys"); - EXPECT_EQ(mqMessage->getKeys(), "testKeys"); + EXPECT_EQ(mqMessage->keys(), "testKeys"); SetMessageBody(message, "testBody"); - EXPECT_EQ(mqMessage->getBody(), "testBody"); + EXPECT_EQ(mqMessage->body(), "testBody"); SetByteMessageBody(message, "testBody", 5); - EXPECT_EQ(mqMessage->getBody(), "testB"); + EXPECT_EQ(mqMessage->body(), "testB"); SetMessageProperty(message, "testProperty", "testValue"); EXPECT_EQ(mqMessage->getProperty("testProperty"), "testValue"); SetDelayTimeLevel(message, 1); - EXPECT_EQ(mqMessage->getDelayTimeLevel(), 1); + EXPECT_EQ(mqMessage->delay_time_level(), 1); EXPECT_EQ(DestroyMessage(message), OK); message = CreateMessage("testTopic"); mqMessage = (MQMessage*)message; - EXPECT_EQ(mqMessage->getTopic(), "testTopic"); + EXPECT_EQ(mqMessage->topic(), "testTopic"); EXPECT_EQ(DestroyMessage(message), OK); } diff --git a/test/src/extern/CProducerTest.cpp b/test/src/extern/CProducerTest.cpp index 17ed7c602..bb0988410 100644 --- a/test/src/extern/CProducerTest.cpp +++ b/test/src/extern/CProducerTest.cpp @@ -174,25 +174,25 @@ TEST(CProducerTest, Info) { CProducer* cProducer = CreateProducer("groupTest"); DefaultMQProducer* defaultMQProducer = (DefaultMQProducer*)cProducer; EXPECT_TRUE(cProducer != NULL); - EXPECT_EQ(defaultMQProducer->getGroupName(), "groupTest"); + EXPECT_EQ(defaultMQProducer->group_name(), "groupTest"); EXPECT_EQ(SetProducerNameServerAddress(cProducer, "127.0.0.1:9876"), OK); - EXPECT_EQ(defaultMQProducer->getNamesrvAddr(), "127.0.0.1:9876"); + EXPECT_EQ(defaultMQProducer->namesrv_addr(), "127.0.0.1:9876"); EXPECT_EQ(SetProducerGroupName(cProducer, "testGroup"), OK); - EXPECT_EQ(defaultMQProducer->getGroupName(), "testGroup"); + EXPECT_EQ(defaultMQProducer->group_name(), "testGroup"); EXPECT_EQ(SetProducerInstanceName(cProducer, "instance"), OK); - EXPECT_EQ(defaultMQProducer->getInstanceName(), "instance"); + EXPECT_EQ(defaultMQProducer->instance_name(), "instance"); EXPECT_EQ(SetProducerSendMsgTimeout(cProducer, 1), OK); - EXPECT_EQ(defaultMQProducer->getSendMsgTimeout(), 1); + EXPECT_EQ(defaultMQProducer->send_msg_timeout(), 1); EXPECT_EQ(SetProducerMaxMessageSize(cProducer, 2), OK); - EXPECT_EQ(defaultMQProducer->getMaxMessageSize(), 2); + EXPECT_EQ(defaultMQProducer->max_message_size(), 2); EXPECT_EQ(SetProducerCompressLevel(cProducer, 1), OK); - EXPECT_EQ(defaultMQProducer->getCompressLevel(), 1); + EXPECT_EQ(defaultMQProducer->compress_level(), 1); EXPECT_EQ(SetProducerSessionCredentials(NULL, NULL, NULL, NULL), NULL_POINTER); EXPECT_EQ(SetProducerSessionCredentials(cProducer, "accessKey", "secretKey", "channel"), OK); diff --git a/test/src/extern/CPullConsumerTest.cpp b/test/src/extern/CPullConsumerTest.cpp index df323648c..51b79dcc8 100644 --- a/test/src/extern/CPullConsumerTest.cpp +++ b/test/src/extern/CPullConsumerTest.cpp @@ -147,10 +147,10 @@ TEST(CPullConsumerTest, Init) { EXPECT_FALSE(pullConsumer == NULL); EXPECT_EQ(SetPullConsumerGroupID(pullConsumer, "groupId"), OK); - EXPECT_EQ(GetPullConsumerGroupID(pullConsumer), defaultMQPullConsumer->getGroupName().c_str()); + EXPECT_EQ(GetPullConsumerGroupID(pullConsumer), defaultMQPullConsumer->group_name().c_str()); EXPECT_EQ(SetPullConsumerNameServerAddress(pullConsumer, "127.0.0.1:10091"), OK); - EXPECT_EQ(defaultMQPullConsumer->getNamesrvAddr(), "127.0.0.1:10091"); + EXPECT_EQ(defaultMQPullConsumer->namesrv_addr(), "127.0.0.1:10091"); EXPECT_EQ(SetPullConsumerSessionCredentials(pullConsumer, "accessKey", "secretKey", "channel"), OK); // SessionCredentials sessionCredentials = defaultMQPullConsumer->getSessionCredentials(); @@ -168,10 +168,10 @@ TEST(CPullConsumerTest, CheckNull) { EXPECT_FALSE(pullConsumer == NULL); EXPECT_EQ(SetPullConsumerGroupID(pullConsumer, "groupId"), OK); - EXPECT_EQ(GetPullConsumerGroupID(pullConsumer), defaultMQPullConsumer->getGroupName().c_str()); + EXPECT_EQ(GetPullConsumerGroupID(pullConsumer), defaultMQPullConsumer->group_name().c_str()); EXPECT_EQ(SetPullConsumerNameServerAddress(pullConsumer, "127.0.0.1:10091"), OK); - EXPECT_EQ(defaultMQPullConsumer->getNamesrvAddr(), "127.0.0.1:10091"); + EXPECT_EQ(defaultMQPullConsumer->namesrv_addr(), "127.0.0.1:10091"); EXPECT_EQ(SetPullConsumerSessionCredentials(pullConsumer, "accessKey", "secretKey", "channel"), OK); // SessionCredentials sessionCredentials = defaultMQPullConsumer->getSessionCredentials(); diff --git a/test/src/extern/CPushConsumerTest.cpp b/test/src/extern/CPushConsumerTest.cpp index e41d7f81c..a59916989 100644 --- a/test/src/extern/CPushConsumerTest.cpp +++ b/test/src/extern/CPushConsumerTest.cpp @@ -71,7 +71,7 @@ TEST(CPushComsumerTest, Info) { EXPECT_STREQ(GetPushConsumerGroupID(cPushConsumer), "testGroupTwo"); EXPECT_EQ(SetPushConsumerNameServerAddress(cPushConsumer, "127.0.0.1:9876"), OK); - EXPECT_EQ(mqPushConsumer->getNamesrvAddr(), "127.0.0.1:9876"); + EXPECT_EQ(mqPushConsumer->namesrv_addr(), "127.0.0.1:9876"); EXPECT_EQ(Subscribe(cPushConsumer, "testTopic", "testSub"), OK); @@ -86,20 +86,20 @@ TEST(CPushComsumerTest, Info) { EXPECT_EQ(UnregisterMessageCallback(cPushConsumer), OK); EXPECT_EQ(SetPushConsumerThreadCount(cPushConsumer, 10), OK); - EXPECT_EQ(mqPushConsumer->getConsumeThreadNum(), 10); + EXPECT_EQ(mqPushConsumer->consume_thread_nums(), 10); EXPECT_EQ(SetPushConsumerMessageBatchMaxSize(cPushConsumer, 1024), OK); - EXPECT_EQ(mqPushConsumer->getConsumeMessageBatchMaxSize(), 1024); + EXPECT_EQ(mqPushConsumer->consume_message_batch_max_size(), 1024); EXPECT_EQ(SetPushConsumerInstanceName(cPushConsumer, "instance"), OK); - EXPECT_EQ(mqPushConsumer->getInstanceName(), "instance"); + EXPECT_EQ(mqPushConsumer->instance_name(), "instance"); EXPECT_EQ(SetPushConsumerSessionCredentials(cPushConsumer, "accessKey", "secretKey", "channel"), OK); // SessionCredentials sessionCredentials = mqPushConsumer->getSessionCredentials(); // EXPECT_EQ(sessionCredentials.getAccessKey(), "accessKey"); EXPECT_EQ(SetPushConsumerMessageModel(cPushConsumer, BROADCASTING), OK); - EXPECT_EQ(mqPushConsumer->getMessageModel(), MessageModel::BROADCASTING); + EXPECT_EQ(mqPushConsumer->message_model(), MessageModel::BROADCASTING); DestroyPushConsumer(cPushConsumer); } diff --git a/test/src/message/MQMessageExtTest.cpp b/test/src/message/MQMessageExtTest.cpp index 400d90008..b889aa8a6 100644 --- a/test/src/message/MQMessageExtTest.cpp +++ b/test/src/message/MQMessageExtTest.cpp @@ -36,64 +36,64 @@ using rocketmq::TopicFilterType; TEST(MessageExtTest, MessageClientExtImpl) { MessageClientExtImpl messageClientExt; - EXPECT_EQ(messageClientExt.getQueueOffset(), 0); - EXPECT_EQ(messageClientExt.getCommitLogOffset(), 0); - EXPECT_EQ(messageClientExt.getBornTimestamp(), 0); - EXPECT_EQ(messageClientExt.getStoreTimestamp(), 0); - EXPECT_EQ(messageClientExt.getPreparedTransactionOffset(), 0); - EXPECT_EQ(messageClientExt.getQueueId(), 0); - EXPECT_EQ(messageClientExt.getStoreSize(), 0); - EXPECT_EQ(messageClientExt.getReconsumeTimes(), 3); - EXPECT_EQ(messageClientExt.getBodyCRC(), 0); - EXPECT_EQ(messageClientExt.getMsgId(), ""); - EXPECT_EQ(messageClientExt.getOffsetMsgId(), ""); + EXPECT_EQ(messageClientExt.queue_offset(), 0); + EXPECT_EQ(messageClientExt.commit_log_offset(), 0); + EXPECT_EQ(messageClientExt.born_timestamp(), 0); + EXPECT_EQ(messageClientExt.store_timestamp(), 0); + EXPECT_EQ(messageClientExt.prepared_transaction_offset(), 0); + EXPECT_EQ(messageClientExt.queue_id(), 0); + EXPECT_EQ(messageClientExt.store_size(), 0); + EXPECT_EQ(messageClientExt.reconsume_times(), 3); + EXPECT_EQ(messageClientExt.body_crc(), 0); + EXPECT_EQ(messageClientExt.msg_id(), ""); + EXPECT_EQ(messageClientExt.offset_msg_id(), ""); - messageClientExt.setQueueOffset(1); - EXPECT_EQ(messageClientExt.getQueueOffset(), 1); + messageClientExt.set_queue_offset(1); + EXPECT_EQ(messageClientExt.queue_offset(), 1); - messageClientExt.setCommitLogOffset(1024); - EXPECT_EQ(messageClientExt.getCommitLogOffset(), 1024); + messageClientExt.set_commit_log_offset(1024); + EXPECT_EQ(messageClientExt.commit_log_offset(), 1024); - messageClientExt.setBornTimestamp(1024); - EXPECT_EQ(messageClientExt.getBornTimestamp(), 1024); + messageClientExt.set_born_timestamp(1024); + EXPECT_EQ(messageClientExt.born_timestamp(), 1024); - messageClientExt.setStoreTimestamp(2048); - EXPECT_EQ(messageClientExt.getStoreTimestamp(), 2048); + messageClientExt.set_store_timestamp(2048); + EXPECT_EQ(messageClientExt.store_timestamp(), 2048); - messageClientExt.setPreparedTransactionOffset(4096); - EXPECT_EQ(messageClientExt.getPreparedTransactionOffset(), 4096); + messageClientExt.set_prepared_transaction_offset(4096); + EXPECT_EQ(messageClientExt.prepared_transaction_offset(), 4096); - messageClientExt.setQueueId(2); - EXPECT_EQ(messageClientExt.getQueueId(), 2); + messageClientExt.set_queue_id(2); + EXPECT_EQ(messageClientExt.queue_id(), 2); - messageClientExt.setStoreSize(12); - EXPECT_EQ(messageClientExt.getStoreSize(), 12); + messageClientExt.set_store_size(12); + EXPECT_EQ(messageClientExt.store_size(), 12); - messageClientExt.setReconsumeTimes(48); - EXPECT_EQ(messageClientExt.getReconsumeTimes(), 48); + messageClientExt.set_reconsume_times(48); + EXPECT_EQ(messageClientExt.reconsume_times(), 48); - messageClientExt.setBodyCRC(32); - EXPECT_EQ(messageClientExt.getBodyCRC(), 32); + messageClientExt.set_body_crc(32); + EXPECT_EQ(messageClientExt.body_crc(), 32); - messageClientExt.setMsgId("MsgId"); - EXPECT_EQ(messageClientExt.getMsgId(), ""); + messageClientExt.set_msg_id("MsgId"); + EXPECT_EQ(messageClientExt.msg_id(), ""); messageClientExt.putProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX, "MsgId"); - EXPECT_EQ(messageClientExt.getMsgId(), "MsgId"); + EXPECT_EQ(messageClientExt.msg_id(), "MsgId"); - messageClientExt.setOffsetMsgId("offsetMsgId"); - EXPECT_EQ(messageClientExt.getOffsetMsgId(), "offsetMsgId"); + messageClientExt.set_offset_msg_id("offsetMsgId"); + EXPECT_EQ(messageClientExt.offset_msg_id(), "offsetMsgId"); - messageClientExt.setBornTimestamp(1111); - EXPECT_EQ(messageClientExt.getBornTimestamp(), 1111); + messageClientExt.set_born_timestamp(1111); + EXPECT_EQ(messageClientExt.born_timestamp(), 1111); - messageClientExt.setStoreTimestamp(2222); - EXPECT_EQ(messageClientExt.getStoreTimestamp(), 2222); + messageClientExt.set_store_timestamp(2222); + EXPECT_EQ(messageClientExt.store_timestamp(), 2222); - messageClientExt.setBornHost(rocketmq::string2SocketAddress("127.0.0.1:10091")); - EXPECT_EQ(messageClientExt.getBornHostString(), "127.0.0.1:10091"); + messageClientExt.set_born_host(rocketmq::string2SocketAddress("127.0.0.1:10091")); + EXPECT_EQ(messageClientExt.born_host_string(), "127.0.0.1:10091"); - messageClientExt.setStoreHost(rocketmq::string2SocketAddress("127.0.0.2:10092")); - EXPECT_EQ(messageClientExt.getStoreHostString(), "127.0.0.2:10092"); + messageClientExt.set_store_host(rocketmq::string2SocketAddress("127.0.0.2:10092")); + EXPECT_EQ(messageClientExt.store_host_string(), "127.0.0.2:10092"); } TEST(MessageExtTest, MessageExt) { @@ -101,18 +101,18 @@ TEST(MessageExtTest, MessageExt) { struct sockaddr* storeHost = rocketmq::copySocketAddress(nullptr, rocketmq::string2SocketAddress("127.0.0.2:10092")); MQMessageExt messageExt(2, 1024, bronHost, 2048, storeHost, "msgId"); - EXPECT_EQ(messageExt.getQueueOffset(), 0); - EXPECT_EQ(messageExt.getCommitLogOffset(), 0); - EXPECT_EQ(messageExt.getBornTimestamp(), 1024); - EXPECT_EQ(messageExt.getStoreTimestamp(), 2048); - EXPECT_EQ(messageExt.getPreparedTransactionOffset(), 0); - EXPECT_EQ(messageExt.getQueueId(), 2); - EXPECT_EQ(messageExt.getStoreSize(), 0); - EXPECT_EQ(messageExt.getReconsumeTimes(), 3); - EXPECT_EQ(messageExt.getBodyCRC(), 0); - EXPECT_EQ(messageExt.getMsgId(), "msgId"); - EXPECT_EQ(messageExt.getBornHostString(), "127.0.0.1:10091"); - EXPECT_EQ(messageExt.getStoreHostString(), "127.0.0.2:10092"); + EXPECT_EQ(messageExt.queue_offset(), 0); + EXPECT_EQ(messageExt.commit_log_offset(), 0); + EXPECT_EQ(messageExt.born_timestamp(), 1024); + EXPECT_EQ(messageExt.store_timestamp(), 2048); + EXPECT_EQ(messageExt.prepared_transaction_offset(), 0); + EXPECT_EQ(messageExt.queue_id(), 2); + EXPECT_EQ(messageExt.store_size(), 0); + EXPECT_EQ(messageExt.reconsume_times(), 3); + EXPECT_EQ(messageExt.body_crc(), 0); + EXPECT_EQ(messageExt.msg_id(), "msgId"); + EXPECT_EQ(messageExt.born_host_string(), "127.0.0.1:10091"); + EXPECT_EQ(messageExt.store_host_string(), "127.0.0.2:10092"); free(bronHost); free(storeHost); diff --git a/test/src/message/MQMessageTest.cpp b/test/src/message/MQMessageTest.cpp index 515e384ed..b398726e8 100644 --- a/test/src/message/MQMessageTest.cpp +++ b/test/src/message/MQMessageTest.cpp @@ -31,97 +31,97 @@ using rocketmq::MQMessageConst; TEST(MessageTest, Init) { MQMessage messageOne; - EXPECT_EQ(messageOne.getTopic(), ""); - EXPECT_EQ(messageOne.getBody(), ""); - EXPECT_EQ(messageOne.getTags(), ""); - EXPECT_EQ(messageOne.getFlag(), 0); + EXPECT_EQ(messageOne.topic(), ""); + EXPECT_EQ(messageOne.body(), ""); + EXPECT_EQ(messageOne.tags(), ""); + EXPECT_EQ(messageOne.flag(), 0); MQMessage messageTwo("test", "testBody"); - EXPECT_EQ(messageTwo.getTopic(), "test"); - EXPECT_EQ(messageTwo.getBody(), "testBody"); - EXPECT_EQ(messageTwo.getTags(), ""); - EXPECT_EQ(messageTwo.getFlag(), 0); + EXPECT_EQ(messageTwo.topic(), "test"); + EXPECT_EQ(messageTwo.body(), "testBody"); + EXPECT_EQ(messageTwo.tags(), ""); + EXPECT_EQ(messageTwo.flag(), 0); MQMessage messageThree("test", "tagTest", "testBody"); - EXPECT_EQ(messageThree.getTopic(), "test"); - EXPECT_EQ(messageThree.getBody(), "testBody"); - EXPECT_EQ(messageThree.getTags(), "tagTest"); - EXPECT_EQ(messageThree.getFlag(), 0); + EXPECT_EQ(messageThree.topic(), "test"); + EXPECT_EQ(messageThree.body(), "testBody"); + EXPECT_EQ(messageThree.tags(), "tagTest"); + EXPECT_EQ(messageThree.flag(), 0); MQMessage messageFour("test", "tagTest", "testKey", "testBody"); - EXPECT_EQ(messageFour.getTopic(), "test"); - EXPECT_EQ(messageFour.getBody(), "testBody"); - EXPECT_EQ(messageFour.getTags(), "tagTest"); - EXPECT_EQ(messageFour.getKeys(), "testKey"); - EXPECT_EQ(messageFour.getFlag(), 0); + EXPECT_EQ(messageFour.topic(), "test"); + EXPECT_EQ(messageFour.body(), "testBody"); + EXPECT_EQ(messageFour.tags(), "tagTest"); + EXPECT_EQ(messageFour.keys(), "testKey"); + EXPECT_EQ(messageFour.flag(), 0); MQMessage messageFive("test", "tagTest", "testKey", 1, "testBody", 2); - EXPECT_EQ(messageFive.getTopic(), "test"); - EXPECT_EQ(messageFive.getBody(), "testBody"); - EXPECT_EQ(messageFive.getTags(), "tagTest"); - EXPECT_EQ(messageFive.getKeys(), "testKey"); - EXPECT_EQ(messageFive.getFlag(), 1); + EXPECT_EQ(messageFive.topic(), "test"); + EXPECT_EQ(messageFive.body(), "testBody"); + EXPECT_EQ(messageFive.tags(), "tagTest"); + EXPECT_EQ(messageFive.keys(), "testKey"); + EXPECT_EQ(messageFive.flag(), 1); MQMessage messageSix(messageFive); - EXPECT_EQ(messageSix.getTopic(), "test"); - EXPECT_EQ(messageSix.getBody(), "testBody"); - EXPECT_EQ(messageSix.getTags(), "tagTest"); - EXPECT_EQ(messageSix.getKeys(), "testKey"); - EXPECT_EQ(messageSix.getFlag(), 1); + EXPECT_EQ(messageSix.topic(), "test"); + EXPECT_EQ(messageSix.body(), "testBody"); + EXPECT_EQ(messageSix.tags(), "tagTest"); + EXPECT_EQ(messageSix.keys(), "testKey"); + EXPECT_EQ(messageSix.flag(), 1); } TEST(MessageTest, GetterAndSetter) { MQMessage message; - EXPECT_EQ(message.getTopic(), ""); // default - message.setTopic("testTopic"); - EXPECT_EQ(message.getTopic(), "testTopic"); + EXPECT_EQ(message.topic(), ""); // default + message.set_topic("testTopic"); + EXPECT_EQ(message.topic(), "testTopic"); const char* topic = "testTopic"; - message.setTopic(topic, 5); - EXPECT_EQ(message.getTopic(), "testT"); - - EXPECT_EQ(message.getBody(), ""); // default - message.setBody("testBody"); - EXPECT_EQ(message.getBody(), "testBody"); - - EXPECT_EQ(message.getTags(), ""); // default - message.setTags("testTags"); - EXPECT_EQ(message.getTags(), "testTags"); - - EXPECT_EQ(message.getKeys(), ""); // default - message.setKeys("testKeys"); - EXPECT_EQ(message.getKeys(), "testKeys"); - - EXPECT_EQ(message.getFlag(), 0); // default - message.setFlag(2); - EXPECT_EQ(message.getFlag(), 2); - - EXPECT_EQ(message.isWaitStoreMsgOK(), true); // default - message.setWaitStoreMsgOK(false); - EXPECT_EQ(message.isWaitStoreMsgOK(), false); - message.setWaitStoreMsgOK(true); - EXPECT_EQ(message.isWaitStoreMsgOK(), true); - - EXPECT_EQ(message.getDelayTimeLevel(), 0); // default - message.setDelayTimeLevel(1); - EXPECT_EQ(message.getDelayTimeLevel(), 1); + message.set_topic(topic, 5); + EXPECT_EQ(message.topic(), "testT"); + + EXPECT_EQ(message.body(), ""); // default + message.set_body("testBody"); + EXPECT_EQ(message.body(), "testBody"); + + EXPECT_EQ(message.tags(), ""); // default + message.set_tags("testTags"); + EXPECT_EQ(message.tags(), "testTags"); + + EXPECT_EQ(message.keys(), ""); // default + message.set_keys("testKeys"); + EXPECT_EQ(message.keys(), "testKeys"); + + EXPECT_EQ(message.flag(), 0); // default + message.set_flag(2); + EXPECT_EQ(message.flag(), 2); + + EXPECT_EQ(message.wait_store_msg_ok(), true); // default + message.set_wait_store_msg_ok(false); + EXPECT_EQ(message.wait_store_msg_ok(), false); + message.set_wait_store_msg_ok(true); + EXPECT_EQ(message.wait_store_msg_ok(), true); + + EXPECT_EQ(message.delay_time_level(), 0); // default + message.set_delay_time_level(1); + EXPECT_EQ(message.delay_time_level(), 1); } TEST(MessageTest, Properties) { MQMessage message; - EXPECT_EQ(message.getProperties().size(), 1); + EXPECT_EQ(message.properties().size(), 1); EXPECT_EQ(message.getProperty(MQMessageConst::PROPERTY_TRANSACTION_PREPARED), ""); message.putProperty(MQMessageConst::PROPERTY_TRANSACTION_PREPARED, "true"); - EXPECT_EQ(message.getProperties().size(), 2); + EXPECT_EQ(message.properties().size(), 2); EXPECT_EQ(message.getProperty(MQMessageConst::PROPERTY_TRANSACTION_PREPARED), "true"); std::map newProperties; newProperties[MQMessageConst::PROPERTY_TRANSACTION_PREPARED] = "false"; - message.setProperties(newProperties); - EXPECT_EQ(message.getProperties().size(), 1); + message.set_properties(newProperties); + EXPECT_EQ(message.properties().size(), 1); EXPECT_EQ(message.getProperty(MQMessageConst::PROPERTY_TRANSACTION_PREPARED), "false"); } diff --git a/test/src/message/MessageDecoderTest.cpp b/test/src/message/MessageDecoderTest.cpp index 8f15e02e5..d602d80aa 100644 --- a/test/src/message/MessageDecoderTest.cpp +++ b/test/src/message/MessageDecoderTest.cpp @@ -71,77 +71,77 @@ TEST(MessageDecoderTest, Decode) { // 1 TOTALSIZE 4=0+4 byteBuffer->putInt(111); - msgExt.setStoreSize(111); + msgExt.set_store_size(111); // 2 MAGICCODE sizeof(int) 8=4+4 byteBuffer->putInt(14); // 3 BODYCRC 12=8+4 byteBuffer->putInt(24); - msgExt.setBodyCRC(24); + msgExt.set_body_crc(24); // 4 QUEUEID 16=12+4 byteBuffer->putInt(4); - msgExt.setQueueId(4); + msgExt.set_queue_id(4); // 5 FLAG 20=16+4 byteBuffer->putInt(4); - msgExt.setFlag(4); + msgExt.set_flag(4); // 6 QUEUEOFFSET 28=20+8 byteBuffer->putLong(1024LL); - msgExt.setQueueOffset(1024LL); + msgExt.set_queue_offset(1024LL); // 7 PHYSICALOFFSET 36=28+8 byteBuffer->putLong(2048LL); - msgExt.setCommitLogOffset(2048LL); + msgExt.set_commit_log_offset(2048LL); // 8 SYSFLAG 40=36+4 byteBuffer->putInt(0); - msgExt.setSysFlag(0); + msgExt.set_sys_flag(0); // 9 BORNTIMESTAMP 48=40+8 byteBuffer->putLong(4096LL); - msgExt.setBornTimestamp(4096LL); + msgExt.set_born_timestamp(4096LL); // 10 BORNHOST 56=48+4+4 byteBuffer->putInt(ntohl(inet_addr("127.0.0.1"))); byteBuffer->putInt(10091); - msgExt.setBornHost(rocketmq::string2SocketAddress("127.0.0.1:10091")); + msgExt.set_born_host(rocketmq::string2SocketAddress("127.0.0.1:10091")); // 11 STORETIMESTAMP 64=56+8 byteBuffer->putLong(4096LL); - msgExt.setStoreTimestamp(4096LL); + msgExt.set_store_timestamp(4096LL); // 12 STOREHOST 72=64+4+4 byteBuffer->putInt(ntohl(inet_addr("127.0.0.2"))); byteBuffer->putInt(10092); - msgExt.setStoreHost(rocketmq::string2SocketAddress("127.0.0.2:10092")); + msgExt.set_store_host(rocketmq::string2SocketAddress("127.0.0.2:10092")); // 13 RECONSUMETIMES 76=72+4 byteBuffer->putInt(18); - msgExt.setReconsumeTimes(18); + msgExt.set_reconsume_times(18); // 14 Prepared Transaction Offset 84=76+8 byteBuffer->putLong(12LL); - msgExt.setPreparedTransactionOffset(12LL); + msgExt.set_prepared_transaction_offset(12LL); // 15 BODY 98=84+4+10 std::string body("1234567890"); byteBuffer->putInt(body.size()); byteBuffer->put(*stoba(body)); - msgExt.setBody(body); + msgExt.set_body(body); // 16 TOPIC 109=98+1+10 std::string topic = "topic_1234"; byteBuffer->put((int8_t)topic.size()); byteBuffer->put(*stoba(topic)); - msgExt.setTopic(topic); + msgExt.set_topic(topic); // 17 PROPERTIES 111=109+2 byteBuffer->putShort(0); - msgExt.setMsgId(MessageDecoder::createMessageId(msgExt.getStoreHost(), (int64_t)msgExt.getCommitLogOffset())); + msgExt.set_msg_id(MessageDecoder::createMessageId(msgExt.store_host(), (int64_t)msgExt.commit_log_offset())); byteBuffer->flip(); auto msgs = MessageDecoder::decodes(*byteBuffer); @@ -153,7 +153,7 @@ TEST(MessageDecoderTest, Decode) { byteBuffer->rewind(); msgs = MessageDecoder::decodes(*byteBuffer, false); - EXPECT_EQ(msgs[0]->getBody(), ""); + EXPECT_EQ(msgs[0]->body(), ""); //=============================================================== @@ -162,7 +162,7 @@ TEST(MessageDecoderTest, Decode) { // 8 SYSFLAG 40=36+4 byteBuffer->position(36); byteBuffer->putInt(0 | MessageSysFlag::COMPRESSED_FLAG); - msgExt.setSysFlag(0 | MessageSysFlag::COMPRESSED_FLAG); + msgExt.set_sys_flag(0 | MessageSysFlag::COMPRESSED_FLAG); // 15 Body 84 std::string compressedBody; @@ -170,12 +170,12 @@ TEST(MessageDecoderTest, Decode) { byteBuffer->position(84); byteBuffer->putInt(compressedBody.size()); byteBuffer->put(*stoba(compressedBody)); - msgExt.setBody(compressedBody); + msgExt.set_body(compressedBody); // 16 TOPIC byteBuffer->put((int8_t)topic.size()); byteBuffer->put(*stoba(topic)); - msgExt.setTopic(topic); + msgExt.set_topic(topic); // 17 PROPERTIES std::map properties; @@ -184,13 +184,13 @@ TEST(MessageDecoderTest, Decode) { std::string props = MessageDecoder::messageProperties2String(properties); byteBuffer->putShort(props.size()); byteBuffer->put(*stoba(props)); - msgExt.setProperties(properties); - msgExt.setMsgId("123456"); + msgExt.set_properties(properties); + msgExt.set_msg_id("123456"); byteBuffer->flip(); byteBuffer->putInt(byteBuffer->limit()); - msgExt.setStoreSize(byteBuffer->limit()); + msgExt.set_store_size(byteBuffer->limit()); byteBuffer->rewind(); msgs = MessageDecoder::decodes(*byteBuffer); From 9c1c68959983e9b360eb9422bfba860636626602 Mon Sep 17 00:00:00 2001 From: James Yin Date: Thu, 30 Jul 2020 16:03:56 +0800 Subject: [PATCH 18/62] style: protocol --- src/ClientRemotingProcessor.cpp | 32 ++-- src/MQClientAPIImpl.cpp | 3 +- src/MQClientAPIImpl.h | 7 +- src/MQClientInstance.cpp | 28 +-- src/MQClientInstance.h | 6 +- src/common/FilterAPI.hpp | 18 +- src/common/UtilAll.cpp | 1 + src/consumer/DefaultMQPushConsumerImpl.cpp | 4 +- src/consumer/DefaultMQPushConsumerImpl.h | 2 +- src/consumer/LocalFileOffsetStore.cpp | 2 +- src/consumer/MQConsumerInner.h | 4 +- src/consumer/ProcessQueue.cpp | 2 +- src/consumer/PullAPIWrapper.cpp | 2 +- src/consumer/PullAPIWrapper.h | 2 +- src/consumer/RebalanceImpl.cpp | 25 ++- src/consumer/RebalanceImpl.h | 2 +- src/consumer/RemoteBrokerOffsetStore.cpp | 2 +- src/consumer/SubscriptionData.cpp | 87 --------- src/log/Logging.h | 4 + src/producer/TopicPublishInfo.hpp | 2 +- src/protocol/HeartbeatData.h | 109 ----------- src/protocol/MessageQueue.cpp | 29 --- .../{MessageQueue.h => MessageQueue.hpp} | 14 +- src/protocol/TopicList.h | 6 +- .../{ => body}/ConsumerRunningInfo.cpp | 0 src/protocol/{ => body}/ConsumerRunningInfo.h | 6 +- src/protocol/body/LockBatchBody.cpp | 116 ------------ src/protocol/body/LockBatchBody.h | 80 -------- src/protocol/body/LockBatchRequestBody.hpp | 61 ++++++ src/protocol/body/LockBatchResponseBody.hpp | 57 ++++++ .../ProcessQueueInfo.hpp} | 6 +- src/protocol/body/ResetOffsetBody.cpp | 45 ----- src/protocol/body/ResetOffsetBody.hpp | 53 ++++++ src/protocol/{ => body}/TopicRouteData.hpp | 10 +- src/protocol/body/UnlockBatchRequestBody.hpp | 61 ++++++ .../header/ReplyMessageRequestHeader.cpp | 175 ------------------ .../header/ReplyMessageRequestHeader.h | 92 --------- .../header/ReplyMessageRequestHeader.hpp | 132 +++++++++++++ src/protocol/heartbeat/ConsumerData.hpp | 83 +++++++++ src/protocol/heartbeat/HeartbeatData.hpp | 66 +++++++ .../ProducerData.hpp} | 30 +-- .../heartbeat/SubscriptionData.hpp} | 76 +++++--- test/src/protocol/ConsumerRunningInfoTest.cpp | 3 - test/src/protocol/HeartbeatDataTest.cpp | 51 ++--- test/src/protocol/LockBatchBodyTest.cpp | 18 +- test/src/protocol/MessageQueueTest.cpp | 2 +- test/src/protocol/TopicRouteDataTest.cpp | 2 +- .../transport/ClientRemotingProcessorTest.cpp | 2 +- 48 files changed, 711 insertions(+), 909 deletions(-) delete mode 100644 src/consumer/SubscriptionData.cpp delete mode 100644 src/protocol/HeartbeatData.h delete mode 100644 src/protocol/MessageQueue.cpp rename src/protocol/{MessageQueue.h => MessageQueue.hpp} (73%) rename src/protocol/{ => body}/ConsumerRunningInfo.cpp (100%) rename src/protocol/{ => body}/ConsumerRunningInfo.h (96%) delete mode 100644 src/protocol/body/LockBatchBody.cpp delete mode 100644 src/protocol/body/LockBatchBody.h create mode 100644 src/protocol/body/LockBatchRequestBody.hpp create mode 100644 src/protocol/body/LockBatchResponseBody.hpp rename src/protocol/{ProcessQueueInfo.h => body/ProcessQueueInfo.hpp} (94%) delete mode 100644 src/protocol/body/ResetOffsetBody.cpp create mode 100644 src/protocol/body/ResetOffsetBody.hpp rename src/protocol/{ => body}/TopicRouteData.hpp (96%) create mode 100644 src/protocol/body/UnlockBatchRequestBody.hpp delete mode 100644 src/protocol/header/ReplyMessageRequestHeader.cpp delete mode 100644 src/protocol/header/ReplyMessageRequestHeader.h create mode 100644 src/protocol/header/ReplyMessageRequestHeader.hpp create mode 100644 src/protocol/heartbeat/ConsumerData.hpp create mode 100644 src/protocol/heartbeat/HeartbeatData.hpp rename src/protocol/{body/ResetOffsetBody.h => heartbeat/ProducerData.hpp} (55%) rename src/{common/SubscriptionData.h => protocol/heartbeat/SubscriptionData.hpp} (50%) diff --git a/src/ClientRemotingProcessor.cpp b/src/ClientRemotingProcessor.cpp index 518e4649b..cbc83637a 100644 --- a/src/ClientRemotingProcessor.cpp +++ b/src/ClientRemotingProcessor.cpp @@ -16,16 +16,16 @@ */ #include "ClientRemotingProcessor.h" -#include "ConsumerRunningInfo.h" #include "MessageDecoder.h" #include "MQProtos.h" #include "MessageAccessor.hpp" #include "MessageSysFlag.h" #include "RequestFutureTable.h" #include "SocketUtil.h" -#include "protocol/body/ResetOffsetBody.h" +#include "protocol/body/ConsumerRunningInfo.h" +#include "protocol/body/ResetOffsetBody.hpp" #include "protocol/header/CommandHeader.h" -#include "protocol/header/ReplyMessageRequestHeader.h" +#include "protocol/header/ReplyMessageRequestHeader.hpp" namespace rocketmq { @@ -106,7 +106,7 @@ RemotingCommand* ClientRemotingProcessor::resetOffset(RemotingCommand* request) if (requestBody != nullptr && requestBody->size() > 0) { std::unique_ptr body(ResetOffsetBody::Decode(*requestBody)); if (body != nullptr) { - client_instance_->resetOffset(responseHeader->getGroup(), responseHeader->getTopic(), body->getOffsetTable()); + client_instance_->resetOffset(responseHeader->getGroup(), responseHeader->getTopic(), body->offset_table()); } else { LOG_ERROR("resetOffset failed as received data could not be unserialized"); } @@ -148,20 +148,20 @@ RemotingCommand* ClientRemotingProcessor::receiveReplyMessage(RemotingCommand* r try { std::unique_ptr msg(new MQMessageExt); - msg->set_topic(requestHeader->getTopic()); - msg->set_queue_id(requestHeader->getQueueId()); - msg->set_store_timestamp(requestHeader->getStoreTimestamp()); + msg->set_topic(requestHeader->topic()); + msg->set_queue_id(requestHeader->queue_id()); + msg->set_store_timestamp(requestHeader->store_timestamp()); - if (!requestHeader->getBornHost().empty()) { - msg->set_born_host(string2SocketAddress(requestHeader->getBornHost())); + if (!requestHeader->born_host().empty()) { + msg->set_born_host(string2SocketAddress(requestHeader->born_host())); } - if (!requestHeader->getStoreHost().empty()) { - msg->set_store_host(string2SocketAddress(requestHeader->getStoreHost())); + if (!requestHeader->store_host().empty()) { + msg->set_store_host(string2SocketAddress(requestHeader->store_host())); } auto body = request->body(); - if ((requestHeader->getSysFlag() & MessageSysFlag::COMPRESSED_FLAG) == MessageSysFlag::COMPRESSED_FLAG) { + if ((requestHeader->sys_flag() & MessageSysFlag::COMPRESSED_FLAG) == MessageSysFlag::COMPRESSED_FLAG) { std::string origin_body; if (UtilAll::inflate(*body, origin_body)) { msg->set_body(std::move(origin_body)); @@ -172,12 +172,12 @@ RemotingCommand* ClientRemotingProcessor::receiveReplyMessage(RemotingCommand* r msg->set_body(std::string(body->array(), body->size())); } - msg->set_flag(requestHeader->getFlag()); - MessageAccessor::setProperties(*msg, MessageDecoder::string2messageProperties(requestHeader->getProperties())); + msg->set_flag(requestHeader->flag()); + MessageAccessor::setProperties(*msg, MessageDecoder::string2messageProperties(requestHeader->properties())); MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_REPLY_MESSAGE_ARRIVE_TIME, UtilAll::to_string(receiveTime)); - msg->set_born_timestamp(requestHeader->getBornTimestamp()); - msg->set_reconsume_times(requestHeader->getReconsumeTimes()); + msg->set_born_timestamp(requestHeader->born_timestamp()); + msg->set_reconsume_times(requestHeader->reconsume_times()); LOG_DEBUG_NEW("receive reply message:{}", msg->toString()); processReplyMessage(std::move(msg)); diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index cb17dfdf3..c3e010fb7 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -28,6 +28,7 @@ #include "PullResultExt.hpp" #include "SendCallbackWrap.h" #include "TcpRemotingClient.h" +#include "protocol/body/LockBatchResponseBody.hpp" namespace rocketmq { @@ -595,7 +596,7 @@ void MQClientAPIImpl::lockBatchMQ(const std::string& addr, auto requestBody = response->body(); if (requestBody != nullptr && requestBody->size() > 0) { std::unique_ptr body(LockBatchResponseBody::Decode(*requestBody)); - mqs = body->getLockOKMQSet(); + mqs = std::move(body->lock_ok_mq_set()); } else { mqs.clear(); } diff --git a/src/MQClientAPIImpl.h b/src/MQClientAPIImpl.h index c94769286..b105ffefe 100644 --- a/src/MQClientAPIImpl.h +++ b/src/MQClientAPIImpl.h @@ -19,7 +19,6 @@ #include "CommunicationMode.h" #include "DefaultMQProducerImpl.h" -#include "HeartbeatData.h" #include "KVTable.h" #include "MQException.h" #include "MQClientInstance.h" @@ -30,9 +29,11 @@ #include "TopicConfig.h" #include "TopicList.h" #include "TopicPublishInfo.hpp" -#include "TopicRouteData.hpp" -#include "protocol/body/LockBatchBody.h" +#include "protocol/body/TopicRouteData.hpp" +#include "protocol/body/LockBatchRequestBody.hpp" +#include "protocol/body/UnlockBatchRequestBody.hpp" #include "protocol/header/CommandHeader.h" +#include "protocol/heartbeat/HeartbeatData.hpp" namespace rocketmq { diff --git a/src/MQClientInstance.cpp b/src/MQClientInstance.cpp index f10f18891..443b7c401 100644 --- a/src/MQClientInstance.cpp +++ b/src/MQClientInstance.cpp @@ -19,7 +19,7 @@ #include #include "ClientRemotingProcessor.h" -#include "ConsumerRunningInfo.h" +#include "protocol/body/ConsumerRunningInfo.h" #include "Logging.h" #include "MQAdminImpl.h" #include "MQClientAPIImpl.h" @@ -375,8 +375,8 @@ void MQClientInstance::persistAllConsumerOffset() { void MQClientInstance::sendHeartbeatToAllBroker() { std::unique_ptr heartbeatData(prepareHeartbeatData()); - bool producerEmpty = heartbeatData->isProducerDataSetEmpty(); - bool consumerEmpty = heartbeatData->isConsumerDataSetEmpty(); + bool producerEmpty = heartbeatData->producer_data_set().empty(); + bool consumerEmpty = heartbeatData->consumer_data_set().empty(); if (producerEmpty && consumerEmpty) { LOG_WARN_NEW("sending heartbeat, but no consumer and no producer"); return; @@ -481,7 +481,7 @@ HeartbeatData* MQClientInstance::prepareHeartbeatData() { HeartbeatData* pHeartbeatData = new HeartbeatData(); // clientID - pHeartbeatData->setClientID(client_id_); + pHeartbeatData->set_client_id(client_id_); // Consumer insertConsumerInfoToHeartBeatData(pHeartbeatData); @@ -492,29 +492,21 @@ HeartbeatData* MQClientInstance::prepareHeartbeatData() { return pHeartbeatData; } -void MQClientInstance::insertConsumerInfoToHeartBeatData(HeartbeatData* pHeartbeatData) { +void MQClientInstance::insertConsumerInfoToHeartBeatData(HeartbeatData* heartbeatData) { std::lock_guard lock(consumer_table_mutex_); for (const auto& it : consumer_table_) { const auto* consumer = it.second; - ConsumerData consumerData; - consumerData.groupName = consumer->groupName(); - consumerData.consumeType = consumer->consumeType(); - consumerData.messageModel = consumer->messageModel(); - consumerData.consumeFromWhere = consumer->consumeFromWhere(); - std::vector result = consumer->subscriptions(); - consumerData.subscriptionDataSet.swap(result); // TODO: unitMode - - pHeartbeatData->insertDataToConsumerDataSet(consumerData); + heartbeatData->consumer_data_set().emplace_back(consumer->groupName(), consumer->consumeType(), + consumer->messageModel(), consumer->consumeFromWhere(), + consumer->subscriptions()); } } -void MQClientInstance::insertProducerInfoToHeartBeatData(HeartbeatData* pHeartbeatData) { +void MQClientInstance::insertProducerInfoToHeartBeatData(HeartbeatData* heartbeatData) { std::lock_guard lock(producer_table_mutex_); for (const auto& it : producer_table_) { - ProducerData producerData; - producerData.groupName = it.first; - pHeartbeatData->insertDataToProducerDataSet(producerData); + heartbeatData->producer_data_set().emplace_back(it.first); } } diff --git a/src/MQClientInstance.h b/src/MQClientInstance.h index dc583efd4..5a589aaf2 100644 --- a/src/MQClientInstance.h +++ b/src/MQClientInstance.h @@ -22,9 +22,8 @@ #include #include -#include "ConsumerRunningInfo.h" +#include "protocol/body/ConsumerRunningInfo.h" #include "FindBrokerResult.hpp" -#include "HeartbeatData.h" #include "MQClientConfig.h" #include "MQException.h" #include "MQConsumerInner.h" @@ -32,7 +31,8 @@ #include "MQProducerInner.h" #include "ServiceState.h" #include "TopicPublishInfo.hpp" -#include "TopicRouteData.hpp" +#include "protocol/body/TopicRouteData.hpp" +#include "protocol/heartbeat/HeartbeatData.hpp" #include "concurrent/executor.hpp" namespace rocketmq { diff --git a/src/common/FilterAPI.hpp b/src/common/FilterAPI.hpp index aa40eb5bc..9bb18bb84 100644 --- a/src/common/FilterAPI.hpp +++ b/src/common/FilterAPI.hpp @@ -20,30 +20,30 @@ #include // std::string #include "MQException.h" -#include "SubscriptionData.h" +#include "protocol/heartbeat/SubscriptionData.hpp" #include "UtilAll.h" namespace rocketmq { class FilterAPI { public: - static SubscriptionData* buildSubscriptionData(const std::string& topic, const std::string& subString) { + static SubscriptionData* buildSubscriptionData(const std::string& topic, const std::string& sub_string) { // delete in Rebalance - std::unique_ptr subscriptionData(new SubscriptionData(topic, subString)); + std::unique_ptr subscription_data(new SubscriptionData(topic, sub_string)); - if (subString.empty() || SUB_ALL == subString) { - subscriptionData->set_sub_string(SUB_ALL); + if (sub_string.empty() || SUB_ALL == sub_string) { + subscription_data->set_sub_string(SUB_ALL); } else { std::vector tags; - UtilAll::Split(tags, subString, "||"); + UtilAll::Split(tags, sub_string, "||"); if (!tags.empty()) { for (auto tag : tags) { if (!tag.empty()) { UtilAll::Trim(tag); if (!tag.empty()) { - subscriptionData->put_tag(tag); - subscriptionData->put_code(UtilAll::hash_code(tag)); + subscription_data->code_set().push_back(UtilAll::hash_code(tag)); + subscription_data->tags_set().push_back(std::move(tag)); } } } @@ -52,7 +52,7 @@ class FilterAPI { } } - return subscriptionData.release(); + return subscription_data.release(); } }; diff --git a/src/common/UtilAll.cpp b/src/common/UtilAll.cpp index f326d959b..658695f19 100644 --- a/src/common/UtilAll.cpp +++ b/src/common/UtilAll.cpp @@ -18,6 +18,7 @@ #include #include +#include #ifndef WIN32 #include // gethostbyname diff --git a/src/consumer/DefaultMQPushConsumerImpl.cpp b/src/consumer/DefaultMQPushConsumerImpl.cpp index de90889e5..740e18b6e 100644 --- a/src/consumer/DefaultMQPushConsumerImpl.cpp +++ b/src/consumer/DefaultMQPushConsumerImpl.cpp @@ -22,7 +22,7 @@ #include "CommunicationMode.h" #include "ConsumeMsgService.h" -#include "ConsumerRunningInfo.h" +#include "protocol/body/ConsumerRunningInfo.h" #include "FilterAPI.hpp" #include "Logging.h" #include "MQAdminImpl.h" @@ -579,7 +579,7 @@ int DefaultMQPushConsumerImpl::getMaxReconsumeTimes() { } } -std::string DefaultMQPushConsumerImpl::groupName() const { +const std::string& DefaultMQPushConsumerImpl::groupName() const { return client_config_->group_name(); } diff --git a/src/consumer/DefaultMQPushConsumerImpl.h b/src/consumer/DefaultMQPushConsumerImpl.h index e6bee6947..1e3fdc7b5 100755 --- a/src/consumer/DefaultMQPushConsumerImpl.h +++ b/src/consumer/DefaultMQPushConsumerImpl.h @@ -85,7 +85,7 @@ class DefaultMQPushConsumerImpl : public std::enable_shared_from_this #include "ConsumeType.h" -#include "SubscriptionData.h" +#include "protocol/heartbeat/SubscriptionData.hpp" namespace rocketmq { @@ -32,7 +32,7 @@ class MQConsumerInner { virtual ~MQConsumerInner() = default; public: // MQConsumerInner in Java Client - virtual std::string groupName() const = 0; + virtual const std::string& groupName() const = 0; virtual MessageModel messageModel() const = 0; virtual ConsumeType consumeType() const = 0; virtual ConsumeFromWhere consumeFromWhere() const = 0; diff --git a/src/consumer/ProcessQueue.cpp b/src/consumer/ProcessQueue.cpp index bc6f29d89..e2d3a3910 100644 --- a/src/consumer/ProcessQueue.cpp +++ b/src/consumer/ProcessQueue.cpp @@ -17,7 +17,7 @@ #include "ProcessQueue.h" #include "Logging.h" -#include "ProcessQueueInfo.h" +#include "protocol/body/ProcessQueueInfo.hpp" #include "UtilAll.h" static const uint64_t PULL_MAX_IDLE_TIME = 120000; // ms diff --git a/src/consumer/PullAPIWrapper.cpp b/src/consumer/PullAPIWrapper.cpp index 54a551214..e67111828 100644 --- a/src/consumer/PullAPIWrapper.cpp +++ b/src/consumer/PullAPIWrapper.cpp @@ -70,7 +70,7 @@ PullResult PullAPIWrapper::processPullResult(const MQMessageQueue& mq, msgListFilterAgain.reserve(msgList.size()); for (const auto& msg : msgList) { const auto& msgTag = msg->tags(); - if (subscriptionData->contain_tag(msgTag)) { + if (subscriptionData->containsTag(msgTag)) { msgListFilterAgain.push_back(msg); } } diff --git a/src/consumer/PullAPIWrapper.h b/src/consumer/PullAPIWrapper.h index 02055d02c..7edc227e7 100644 --- a/src/consumer/PullAPIWrapper.h +++ b/src/consumer/PullAPIWrapper.h @@ -23,7 +23,7 @@ #include "MQClientInstance.h" #include "MQMessageQueue.h" #include "PullCallback.h" -#include "SubscriptionData.h" +#include "protocol/heartbeat/SubscriptionData.hpp" namespace rocketmq { diff --git a/src/consumer/RebalanceImpl.cpp b/src/consumer/RebalanceImpl.cpp index 9459d5e2d..a3988cd48 100644 --- a/src/consumer/RebalanceImpl.cpp +++ b/src/consumer/RebalanceImpl.cpp @@ -18,7 +18,6 @@ #include "MQClientAPIImpl.h" #include "MQClientInstance.h" -#include "protocol/body/LockBatchBody.h" namespace rocketmq { @@ -42,9 +41,9 @@ void RebalanceImpl::unlock(MQMessageQueue mq, const bool oneway) { client_instance_->findBrokerAddressInSubscribe(mq.broker_name(), MASTER_ID, true)); if (findBrokerResult) { std::unique_ptr unlockBatchRequest(new UnlockBatchRequestBody()); - unlockBatchRequest->setConsumerGroup(consumer_group_); - unlockBatchRequest->setClientId(client_instance_->getClientId()); - unlockBatchRequest->getMqSet().push_back(mq); + unlockBatchRequest->set_consumer_group(consumer_group_); + unlockBatchRequest->set_client_id(client_instance_->getClientId()); + unlockBatchRequest->mq_set().push_back(mq); try { client_instance_->getMQClientAPIImpl()->unlockBatchMQ(findBrokerResult->broker_addr(), unlockBatchRequest.get(), @@ -81,9 +80,9 @@ void RebalanceImpl::unlockAll(const bool oneway) { client_instance_->findBrokerAddressInSubscribe(brokerName, MASTER_ID, true)); if (findBrokerResult) { std::unique_ptr unlockBatchRequest(new UnlockBatchRequestBody()); - unlockBatchRequest->setConsumerGroup(consumer_group_); - unlockBatchRequest->setClientId(client_instance_->getClientId()); - unlockBatchRequest->setMqSet(mqs); + unlockBatchRequest->set_consumer_group(consumer_group_); + unlockBatchRequest->set_client_id(client_instance_->getClientId()); + unlockBatchRequest->set_mq_set(mqs); try { client_instance_->getMQClientAPIImpl()->unlockBatchMQ(findBrokerResult->broker_addr(), unlockBatchRequest.get(), @@ -125,9 +124,9 @@ bool RebalanceImpl::lock(MQMessageQueue mq) { client_instance_->findBrokerAddressInSubscribe(mq.broker_name(), MASTER_ID, true)); if (findBrokerResult) { std::unique_ptr lockBatchRequest(new LockBatchRequestBody()); - lockBatchRequest->setConsumerGroup(consumer_group_); - lockBatchRequest->setClientId(client_instance_->getClientId()); - lockBatchRequest->getMqSet().push_back(mq); + lockBatchRequest->set_consumer_group(consumer_group_); + lockBatchRequest->set_client_id(client_instance_->getClientId()); + lockBatchRequest->mq_set().push_back(mq); try { LOG_DEBUG("try to lock mq:%s", mq.toString().c_str()); @@ -182,9 +181,9 @@ void RebalanceImpl::lockAll() { client_instance_->findBrokerAddressInSubscribe(brokerName, MASTER_ID, true)); if (findBrokerResult) { std::unique_ptr lockBatchRequest(new LockBatchRequestBody()); - lockBatchRequest->setConsumerGroup(consumer_group_); - lockBatchRequest->setClientId(client_instance_->getClientId()); - lockBatchRequest->setMqSet(mqs); + lockBatchRequest->set_consumer_group(consumer_group_); + lockBatchRequest->set_client_id(client_instance_->getClientId()); + lockBatchRequest->set_mq_set(mqs); LOG_INFO("try to lock:" SIZET_FMT " mqs of broker:%s", mqs.size(), brokerName.c_str()); try { diff --git a/src/consumer/RebalanceImpl.h b/src/consumer/RebalanceImpl.h index 8648aa2c5..0ef1a9a97 100755 --- a/src/consumer/RebalanceImpl.h +++ b/src/consumer/RebalanceImpl.h @@ -26,7 +26,7 @@ #include "MQMessageQueue.h" #include "ProcessQueue.h" #include "PullRequest.h" -#include "SubscriptionData.h" +#include "protocol/heartbeat/SubscriptionData.hpp" namespace rocketmq { diff --git a/src/consumer/RemoteBrokerOffsetStore.cpp b/src/consumer/RemoteBrokerOffsetStore.cpp index 8754d8b7a..537cf7f71 100644 --- a/src/consumer/RemoteBrokerOffsetStore.cpp +++ b/src/consumer/RemoteBrokerOffsetStore.cpp @@ -19,7 +19,7 @@ #include "Logging.h" #include "MQClientAPIImpl.h" #include "MQClientInstance.h" -#include "MessageQueue.h" +#include "MessageQueue.hpp" #include "UtilAll.h" namespace rocketmq { diff --git a/src/consumer/SubscriptionData.cpp b/src/consumer/SubscriptionData.cpp deleted file mode 100644 index ad1f21f4d..000000000 --- a/src/consumer/SubscriptionData.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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 -#include -#include - -#include "Logging.h" -#include "UtilAll.h" - -namespace rocketmq { - -SubscriptionData::SubscriptionData() { - sub_version_ = UtilAll::currentTimeMillis(); -} - -SubscriptionData::SubscriptionData(const std::string& topic, const std::string& subString) - : topic_(topic), sub_string_(subString) { - sub_version_ = UtilAll::currentTimeMillis(); -} - -SubscriptionData::SubscriptionData(const SubscriptionData& other) { - sub_string_ = other.sub_string_; - sub_version_ = other.sub_version_; - tag_set_ = other.tag_set_; - topic_ = other.topic_; - code_set_ = other.code_set_; -} - -bool SubscriptionData::operator==(const SubscriptionData& other) const { - if (topic_ != other.topic_) { - return false; - } - if (sub_string_ != other.sub_string_) { - return false; - } - if (sub_version_ != other.sub_version_) { - return false; - } - if (tag_set_.size() != other.tag_set_.size()) { - return false; - } - return true; -} - -bool SubscriptionData::operator<(const SubscriptionData& other) const { - int ret = topic_.compare(other.topic_); - if (ret == 0) { - return sub_string_.compare(other.sub_string_) < 0; - } else { - return ret < 0; - } -} - -Json::Value SubscriptionData::toJson() const { - Json::Value outJson; - outJson["topic"] = topic_; - outJson["subString"] = sub_string_; - outJson["subVersion"] = UtilAll::to_string(sub_version_); - - for (const auto& tag : tag_set_) { - outJson["tagsSet"].append(tag); - } - - for (const auto& code : code_set_) { - outJson["codeSet"].append(code); - } - - return outJson; -} - -} // namespace rocketmq diff --git a/src/log/Logging.h b/src/log/Logging.h index 6c361e577..5afcc5673 100644 --- a/src/log/Logging.h +++ b/src/log/Logging.h @@ -23,7 +23,11 @@ // clang-format off #include +#if !defined(SPDLOG_FMT_EXTERNAL) #include +#else +#include +#endif // clang-format on namespace rocketmq { diff --git a/src/producer/TopicPublishInfo.hpp b/src/producer/TopicPublishInfo.hpp index 341e06616..94c537552 100644 --- a/src/producer/TopicPublishInfo.hpp +++ b/src/producer/TopicPublishInfo.hpp @@ -23,7 +23,7 @@ #include "MQException.h" #include "MQMessageQueue.h" -#include "TopicRouteData.hpp" +#include "protocol/body/TopicRouteData.hpp" namespace rocketmq { diff --git a/src/protocol/HeartbeatData.h b/src/protocol/HeartbeatData.h deleted file mode 100644 index 1453b63bd..000000000 --- a/src/protocol/HeartbeatData.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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 __HEARTBEAT_DATA_H__ -#define __HEARTBEAT_DATA_H__ - -#include -#include - -#include "ConsumeType.h" -#include "RemotingSerializable.h" -#include "SubscriptionData.h" - -namespace rocketmq { - -class ProducerData { - public: - bool operator<(const ProducerData& pd) const { return groupName < pd.groupName; } - - Json::Value toJson() const { - Json::Value outJson; - outJson["groupName"] = groupName; - return outJson; - } - - public: - std::string groupName; -}; - -class ConsumerData { - public: - bool operator<(const ConsumerData& cd) const { return groupName < cd.groupName; } - - Json::Value toJson() const { - Json::Value outJson; - outJson["groupName"] = groupName; - outJson["consumeFromWhere"] = consumeFromWhere; - outJson["consumeType"] = consumeType; - outJson["messageModel"] = messageModel; - - for (const auto& sd : subscriptionDataSet) { - outJson["subscriptionDataSet"].append(sd.toJson()); - } - - return outJson; - } - - public: - std::string groupName; - ConsumeType consumeType; - MessageModel messageModel; - ConsumeFromWhere consumeFromWhere; - std::vector subscriptionDataSet; -}; - -class HeartbeatData : public RemotingSerializable { - public: - std::string encode() { - Json::Value root; - - // id - root["clientID"] = m_clientID; - - // consumer - for (const auto& cd : m_consumerDataSet) { - root["consumerDataSet"].append(cd.toJson()); - } - - // producer - for (const auto& pd : m_producerDataSet) { - root["producerDataSet"].append(pd.toJson()); - } - - // output - return RemotingSerializable::toJson(root); - } - - void setClientID(const std::string& clientID) { m_clientID = clientID; } - - bool isProducerDataSetEmpty() { return m_producerDataSet.empty(); } - - void insertDataToProducerDataSet(ProducerData& producerData) { m_producerDataSet.push_back(producerData); } - - bool isConsumerDataSetEmpty() { return m_consumerDataSet.empty(); } - - void insertDataToConsumerDataSet(ConsumerData& consumerData) { m_consumerDataSet.push_back(consumerData); } - - private: - std::string m_clientID; - std::vector m_producerDataSet; - std::vector m_consumerDataSet; -}; - -} // namespace rocketmq - -#endif // __HEARTBEAT_DATA_H__ diff --git a/src/protocol/MessageQueue.cpp b/src/protocol/MessageQueue.cpp deleted file mode 100644 index ab9af65cf..000000000 --- a/src/protocol/MessageQueue.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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 "MessageQueue.h" - -namespace rocketmq { - -Json::Value toJson(const MQMessageQueue& mq) { - Json::Value outJson; - outJson["topic"] = mq.topic(); - outJson["brokerName"] = mq.broker_name(); - outJson["queueId"] = mq.queue_id(); - return outJson; -} - -} // namespace rocketmq diff --git a/src/protocol/MessageQueue.h b/src/protocol/MessageQueue.hpp similarity index 73% rename from src/protocol/MessageQueue.h rename to src/protocol/MessageQueue.hpp index 50ce54678..9f6af197f 100644 --- a/src/protocol/MessageQueue.h +++ b/src/protocol/MessageQueue.hpp @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MESSAGE_QUEUE_H__ -#define __MESSAGE_QUEUE_H__ +#ifndef ROCKETMQ_PROTOCOL_MESSAGEQUEUE_H_ +#define ROCKETMQ_PROTOCOL_MESSAGEQUEUE_H_ #include @@ -23,8 +23,14 @@ namespace rocketmq { -Json::Value toJson(const MQMessageQueue& mq); +inline Json::Value toJson(const MQMessageQueue& mq) { + Json::Value root; + root["topic"] = mq.topic(); + root["brokerName"] = mq.broker_name(); + root["queueId"] = mq.queue_id(); + return root; +} } // namespace rocketmq -#endif // __MESSAGE_QUEUE_H__ +#endif // ROCKETMQ_PROTOCOL_MESSAGEQUEUE_H_ diff --git a/src/protocol/TopicList.h b/src/protocol/TopicList.h index 450e6b2da..bbcb7ccf6 100644 --- a/src/protocol/TopicList.h +++ b/src/protocol/TopicList.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __TOPIC_LIST_H__ -#define __TOPIC_LIST_H__ +#ifndef ROCKETMQ_PROTOCOL_TOPICLIST_H_ +#define ROCKETMQ_PROTOCOL_TOPICLIST_H_ #include // std::string #include // std::vector @@ -34,4 +34,4 @@ class TopicList { } // namespace rocketmq -#endif // __TOPIC_LIST_H__ +#endif // ROCKETMQ_PROTOCOL_TOPICLIST_H_ diff --git a/src/protocol/ConsumerRunningInfo.cpp b/src/protocol/body/ConsumerRunningInfo.cpp similarity index 100% rename from src/protocol/ConsumerRunningInfo.cpp rename to src/protocol/body/ConsumerRunningInfo.cpp diff --git a/src/protocol/ConsumerRunningInfo.h b/src/protocol/body/ConsumerRunningInfo.h similarity index 96% rename from src/protocol/ConsumerRunningInfo.h rename to src/protocol/body/ConsumerRunningInfo.h index 63d4c5d23..5bfb8865a 100644 --- a/src/protocol/ConsumerRunningInfo.h +++ b/src/protocol/body/ConsumerRunningInfo.h @@ -17,9 +17,9 @@ #ifndef ROCKETMQ_PROTOCOL_CONSUMERRUNNINGINFO_H_ #define ROCKETMQ_PROTOCOL_CONSUMERRUNNINGINFO_H_ -#include "MessageQueue.h" -#include "ProcessQueueInfo.h" -#include "SubscriptionData.h" +#include "MessageQueue.hpp" +#include "ProcessQueueInfo.hpp" +#include "protocol/heartbeat/SubscriptionData.hpp" namespace rocketmq { diff --git a/src/protocol/body/LockBatchBody.cpp b/src/protocol/body/LockBatchBody.cpp deleted file mode 100644 index fde8dcb1a..000000000 --- a/src/protocol/body/LockBatchBody.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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 "LockBatchBody.h" - -#include "Logging.h" -#include "MessageQueue.h" - -namespace rocketmq { - -std::string LockBatchRequestBody::getConsumerGroup() { - return m_consumerGroup; -} - -void LockBatchRequestBody::setConsumerGroup(std::string consumerGroup) { - m_consumerGroup = consumerGroup; -} - -std::string LockBatchRequestBody::getClientId() { - return m_clientId; -} - -void LockBatchRequestBody::setClientId(std::string clientId) { - m_clientId = clientId; -} - -std::vector& LockBatchRequestBody::getMqSet() { - return m_mqSet; -} - -void LockBatchRequestBody::setMqSet(std::vector mqSet) { - m_mqSet.swap(mqSet); -} - -std::string LockBatchRequestBody::encode() { - Json::Value root; - root["consumerGroup"] = m_consumerGroup; - root["clientId"] = m_clientId; - - for (const auto& mq : m_mqSet) { - root["mqSet"].append(rocketmq::toJson(mq)); - } - - return RemotingSerializable::toJson(root); -} - -const std::vector& LockBatchResponseBody::getLockOKMQSet() { - return m_lockOKMQSet; -} - -void LockBatchResponseBody::setLockOKMQSet(std::vector lockOKMQSet) { - m_lockOKMQSet.swap(lockOKMQSet); -} - -LockBatchResponseBody* LockBatchResponseBody::Decode(const ByteArray& bodyData) { - Json::Value root = RemotingSerializable::fromJson(bodyData); - auto& mqs = root["lockOKMQSet"]; - std::unique_ptr body(new LockBatchResponseBody()); - for (const auto& qd : mqs) { - MQMessageQueue mq(qd["topic"].asString(), qd["brokerName"].asString(), qd["queueId"].asInt()); - LOG_INFO("LockBatchResponseBody MQ:%s", mq.toString().c_str()); - body->m_lockOKMQSet.push_back(std::move(mq)); - } - return body.release(); -} - -std::string UnlockBatchRequestBody::getConsumerGroup() { - return m_consumerGroup; -} - -void UnlockBatchRequestBody::setConsumerGroup(std::string consumerGroup) { - m_consumerGroup = consumerGroup; -} - -std::string UnlockBatchRequestBody::getClientId() { - return m_clientId; -} - -void UnlockBatchRequestBody::setClientId(std::string clientId) { - m_clientId = clientId; -} - -std::vector& UnlockBatchRequestBody::getMqSet() { - return m_mqSet; -} - -void UnlockBatchRequestBody::setMqSet(std::vector mqSet) { - m_mqSet.swap(mqSet); -} - -std::string UnlockBatchRequestBody::encode() { - Json::Value root; - root["consumerGroup"] = m_consumerGroup; - root["clientId"] = m_clientId; - - for (const auto& mq : m_mqSet) { - root["mqSet"].append(rocketmq::toJson(mq)); - } - - return RemotingSerializable::toJson(root); -} - -} // namespace rocketmq diff --git a/src/protocol/body/LockBatchBody.h b/src/protocol/body/LockBatchBody.h deleted file mode 100644 index ce38974df..000000000 --- a/src/protocol/body/LockBatchBody.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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 __LOCK_BATCH_BODY_H__ -#define __LOCK_BATCH_BODY_H__ - -#include -#include - -#include "MQMessageQueue.h" -#include "RemotingSerializable.h" -#include "UtilAll.h" - -namespace rocketmq { - -class LockBatchRequestBody : public RemotingSerializable { - public: - std::string getConsumerGroup(); - void setConsumerGroup(std::string consumerGroup); - - std::string getClientId(); - void setClientId(std::string clientId); - - std::vector& getMqSet(); - void setMqSet(std::vector mqSet); - - std::string encode() override; - - private: - std::string m_consumerGroup; - std::string m_clientId; - std::vector m_mqSet; -}; - -class LockBatchResponseBody { - public: - static LockBatchResponseBody* Decode(const ByteArray& bodyData); - - const std::vector& getLockOKMQSet(); - void setLockOKMQSet(std::vector lockOKMQSet); - - private: - std::vector m_lockOKMQSet; -}; - -class UnlockBatchRequestBody : public RemotingSerializable { - public: - std::string getConsumerGroup(); - void setConsumerGroup(std::string consumerGroup); - - std::string getClientId(); - void setClientId(std::string clientId); - - std::vector& getMqSet(); - void setMqSet(std::vector mqSet); - - std::string encode() override; - - private: - std::string m_consumerGroup; - std::string m_clientId; - std::vector m_mqSet; -}; - -} // namespace rocketmq - -#endif // __LOCK_BATCH_BODY_H__ diff --git a/src/protocol/body/LockBatchRequestBody.hpp b/src/protocol/body/LockBatchRequestBody.hpp new file mode 100644 index 000000000..6b75be4f6 --- /dev/null +++ b/src/protocol/body/LockBatchRequestBody.hpp @@ -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 ROCKETMQ_PROTOCOL_BODY_LOCKBATCHREQUESTBODY_HPP_ +#define ROCKETMQ_PROTOCOL_BODY_LOCKBATCHREQUESTBODY_HPP_ + +#include // std::move +#include // std::vector + +#include "MessageQueue.hpp" +#include "RemotingSerializable.h" + +namespace rocketmq { + +class LockBatchRequestBody : public RemotingSerializable { + public: + std::string encode() override { + Json::Value root; + root["consumerGroup"] = consumer_group_; + root["clientId"] = client_id_; + + for (const auto& mq : mq_set_) { + root["mqSet"].append(rocketmq::toJson(mq)); + } + + return RemotingSerializable::toJson(root); + } + + public: + inline const std::string& consumer_group() { return consumer_group_; } + inline void set_consumer_group(const std::string& consumerGroup) { consumer_group_ = consumerGroup; } + + inline const std::string& client_id() { return client_id_; } + inline void set_client_id(const std::string& clientId) { client_id_ = clientId; } + + inline std::vector& mq_set() { return mq_set_; } + inline void set_mq_set(const std::vector& mq_set) { mq_set_ = mq_set; } + inline void set_mq_set(std::vector&& mq_set) { mq_set_ = std::move(mq_set); } + + private: + std::string consumer_group_; + std::string client_id_; + std::vector mq_set_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_PROTOCOL_BODY_LOCKBATCHREQUESTBODY_HPP_ diff --git a/src/protocol/body/LockBatchResponseBody.hpp b/src/protocol/body/LockBatchResponseBody.hpp new file mode 100644 index 000000000..af16bf2e4 --- /dev/null +++ b/src/protocol/body/LockBatchResponseBody.hpp @@ -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. + */ +#ifndef ROCKETMQ_PROTOCOL_BODY_LOCKBATCHRESPONSEBODY_HPP_ +#define ROCKETMQ_PROTOCOL_BODY_LOCKBATCHRESPONSEBODY_HPP_ + +#include // std::move +#include // std::vector + +#include "Logging.h" +#include "MQMessageQueue.h" +#include "RemotingSerializable.h" + +namespace rocketmq { + +class LockBatchResponseBody { + public: + static LockBatchResponseBody* Decode(const ByteArray& bodyData) { + Json::Value root = RemotingSerializable::fromJson(bodyData); + auto& mqs = root["lockOKMQSet"]; + std::unique_ptr body(new LockBatchResponseBody()); + for (const auto& qd : mqs) { + MQMessageQueue mq(qd["topic"].asString(), qd["brokerName"].asString(), qd["queueId"].asInt()); + LOG_INFO_NEW("LockBatchResponseBody MQ:{}", mq.toString()); + body->lock_ok_mq_set().push_back(std::move(mq)); + } + return body.release(); + } + + public: + inline const std::vector& lock_ok_mq_set() const { return lock_ok_mq_set_; } + inline std::vector& lock_ok_mq_set() { return lock_ok_mq_set_; } + inline void set_lock_ok_mq_set(const std::vector& lockOKMQSet) { lock_ok_mq_set_ = lockOKMQSet; } + inline void set_lock_ok_mq_set(std::vector&& lockOKMQSet) { + lock_ok_mq_set_ = std::move(lockOKMQSet); + } + + private: + std::vector lock_ok_mq_set_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_PROTOCOL_BODY_LOCKBATCHRESPONSEBODY_HPP_ diff --git a/src/protocol/ProcessQueueInfo.h b/src/protocol/body/ProcessQueueInfo.hpp similarity index 94% rename from src/protocol/ProcessQueueInfo.h rename to src/protocol/body/ProcessQueueInfo.hpp index 3d2ea6da0..64c66c2d2 100644 --- a/src/protocol/ProcessQueueInfo.h +++ b/src/protocol/body/ProcessQueueInfo.hpp @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __PROCESS_QUEUE_INFO_H__ -#define __PROCESS_QUEUE_INFO_H__ +#ifndef ROCKETMQ_PROTOCOL_BODY_PROCESS_QUEUE_INFO_HPP_ +#define ROCKETMQ_PROTOCOL_BODY_PROCESS_QUEUE_INFO_HPP_ #include @@ -92,4 +92,4 @@ class ProcessQueueInfo { } // namespace rocketmq -#endif // __PROCESS_QUEUE_INFO_H__ +#endif // ROCKETMQ_PROTOCOL_BODY_PROCESS_QUEUE_INFO_HPP_ diff --git a/src/protocol/body/ResetOffsetBody.cpp b/src/protocol/body/ResetOffsetBody.cpp deleted file mode 100644 index 497f5915b..000000000 --- a/src/protocol/body/ResetOffsetBody.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 "ResetOffsetBody.h" - -#include "RemotingSerializable.h" - -namespace rocketmq { - -ResetOffsetBody* ResetOffsetBody::Decode(const ByteArray& bodyData) { - // FIXME: object as key - Json::Value root = RemotingSerializable::fromJson(bodyData); - Json::Value qds = root["offsetTable"]; - std::unique_ptr body(new ResetOffsetBody()); - for (unsigned int i = 0; i < qds.size(); i++) { - Json::Value qd = qds[i]; - MQMessageQueue mq(qd["brokerName"].asString(), qd["topic"].asString(), qd["queueId"].asInt()); - int64_t offset = qd["offset"].asInt64(); - body->setOffsetTable(mq, offset); - } - return body.release(); -} - -std::map ResetOffsetBody::getOffsetTable() { - return offset_table_; -} - -void ResetOffsetBody::setOffsetTable(const MQMessageQueue& mq, int64_t offset) { - offset_table_[mq] = offset; -} - -} // namespace rocketmq diff --git a/src/protocol/body/ResetOffsetBody.hpp b/src/protocol/body/ResetOffsetBody.hpp new file mode 100644 index 000000000..157e567f5 --- /dev/null +++ b/src/protocol/body/ResetOffsetBody.hpp @@ -0,0 +1,53 @@ +/* + * 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_PROTOCOL_BODY_RESETOFFSETBODY_HPP_ +#define ROCKETMQ_PROTOCOL_BODY_RESETOFFSETBODY_HPP_ + +#include // std::map + +#include "MQMessageQueue.h" +#include "RemotingSerializable.h" + +namespace rocketmq { + +class ResetOffsetBody { + public: + static ResetOffsetBody* Decode(const ByteArray& bodyData) { + // FIXME: object as key + Json::Value root = RemotingSerializable::fromJson(bodyData); + auto& qds = root["offsetTable"]; + std::unique_ptr body(new ResetOffsetBody()); + Json::Value::Members members = qds.getMemberNames(); + for (const auto& member : members) { + Json::Value key = RemotingSerializable::fromJson(member); + MQMessageQueue mq(key["topic"].asString(), key["brokerName"].asString(), key["queueId"].asInt()); + int64_t offset = qds[member].asInt64(); + body->offset_table_.emplace(std::move(mq), offset); + } + return body.release(); + } + + public: + std::map& offset_table() { return offset_table_; } + + private: + std::map offset_table_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_PROTOCOL_BODY_RESETOFFSETBODY_HPP_ diff --git a/src/protocol/TopicRouteData.hpp b/src/protocol/body/TopicRouteData.hpp similarity index 96% rename from src/protocol/TopicRouteData.hpp rename to src/protocol/body/TopicRouteData.hpp index 6d4b64c5b..38e188975 100644 --- a/src/protocol/TopicRouteData.hpp +++ b/src/protocol/body/TopicRouteData.hpp @@ -123,12 +123,12 @@ class TopicRouteData { for (auto bd : bds) { std::string broker_name = bd["brokerName"].asString(); LOG_DEBUG_NEW("brokerName:{}", broker_name); + auto& bas = bd["brokerAddrs"]; + Json::Value::Members members = bas.getMemberNames(); std::map broker_addrs; - Json::Value bas = bd["brokerAddrs"]; - Json::Value::Members mbs = bas.getMemberNames(); - for (const auto& key : mbs) { - int id = std::stoi(key); - std::string addr = bas[key].asString(); + for (const auto& member : members) { + int id = std::stoi(member); + std::string addr = bas[member].asString(); broker_addrs.emplace(id, std::move(addr)); LOG_DEBUG_NEW("brokerId:{}, brokerAddr:{}", id, addr); } diff --git a/src/protocol/body/UnlockBatchRequestBody.hpp b/src/protocol/body/UnlockBatchRequestBody.hpp new file mode 100644 index 000000000..ffee533fc --- /dev/null +++ b/src/protocol/body/UnlockBatchRequestBody.hpp @@ -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 ROCKETMQ_PROTOCOL_BODY_UNLOCKBATCHREQUESTBODY_HPP_ +#define ROCKETMQ_PROTOCOL_BODY_UNLOCKBATCHREQUESTBODY_HPP_ + +#include // std::move +#include // std::vector + +#include "MessageQueue.hpp" +#include "RemotingSerializable.h" + +namespace rocketmq { + +class UnlockBatchRequestBody : public RemotingSerializable { + public: + std::string encode() override { + Json::Value root; + root["consumerGroup"] = consumer_group_; + root["clientId"] = client_id_; + + for (const auto& mq : mq_set_) { + root["mqSet"].append(rocketmq::toJson(mq)); + } + + return RemotingSerializable::toJson(root); + } + + public: + inline const std::string& consumer_group() { return consumer_group_; } + inline void set_consumer_group(const std::string& consumerGroup) { consumer_group_ = consumerGroup; } + + inline const std::string& client_id() { return client_id_; } + inline void set_client_id(const std::string& clientId) { client_id_ = clientId; } + + inline std::vector& mq_set() { return mq_set_; } + inline void set_mq_set(const std::vector& mq_set) { mq_set_ = mq_set; } + inline void set_mq_set(std::vector&& mq_set) { mq_set_ = std::move(mq_set); } + + private: + std::string consumer_group_; + std::string client_id_; + std::vector mq_set_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_PROTOCOL_BODY_UNLOCKBATCHREQUESTBODY_HPP_ diff --git a/src/protocol/header/ReplyMessageRequestHeader.cpp b/src/protocol/header/ReplyMessageRequestHeader.cpp deleted file mode 100644 index 7fd362526..000000000 --- a/src/protocol/header/ReplyMessageRequestHeader.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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 "ReplyMessageRequestHeader.h" - -#include - -#include "UtilAll.h" - -namespace rocketmq { - -ReplyMessageRequestHeader* ReplyMessageRequestHeader::Decode(std::map& extFields) { - std::unique_ptr header(new ReplyMessageRequestHeader()); - - header->producerGroup = extFields.at("producerGroup"); - header->topic = extFields.at("topic"); - header->defaultTopic = extFields.at("defaultTopic"); - header->defaultTopicQueueNums = std::stoi(extFields.at("defaultTopicQueueNums")); - header->queueId = std::stoi(extFields.at("queueId")); - header->sysFlag = std::stoi(extFields.at("sysFlag")); - header->bornTimestamp = std::stoll(extFields.at("bornTimestamp")); - header->flag = std::stoi(extFields.at("flag")); - - auto it = extFields.find("properties"); - if (it != extFields.end()) { - header->properties = it->second; - } - - it = extFields.find("reconsumeTimes"); - if (it != extFields.end()) { - header->reconsumeTimes = std::stoi(it->second); - } else { - header->reconsumeTimes = 0; - } - - it = extFields.find("unitMode"); - if (it != extFields.end()) { - header->unitMode = UtilAll::stob(it->second); - } else { - header->unitMode = false; - } - - header->bornHost = extFields.at("bornHost"); - header->storeHost = extFields.at("storeHost"); - header->storeTimestamp = std::stoll(extFields.at("storeTimestamp")); - - return header.release(); -} - -const std::string& ReplyMessageRequestHeader::getProducerGroup() const { - return this->producerGroup; -} - -void ReplyMessageRequestHeader::setProducerGroup(const std::string& producerGroup) { - this->producerGroup = producerGroup; -} - -const std::string& ReplyMessageRequestHeader::getTopic() const { - return this->topic; -} - -void ReplyMessageRequestHeader::setTopic(const std::string& topic) { - this->topic = topic; -} - -const std::string& ReplyMessageRequestHeader::getDefaultTopic() const { - return this->defaultTopic; -} - -void ReplyMessageRequestHeader::setDefaultTopic(const std::string& defaultTopic) { - this->defaultTopic = defaultTopic; -} - -int32_t ReplyMessageRequestHeader::getDefaultTopicQueueNums() const { - return this->defaultTopicQueueNums; -} - -void ReplyMessageRequestHeader::setDefaultTopicQueueNums(int32_t defaultTopicQueueNums) { - this->defaultTopicQueueNums = defaultTopicQueueNums; -} - -int32_t ReplyMessageRequestHeader::getQueueId() const { - return this->queueId; -} - -void ReplyMessageRequestHeader::setQueueId(int32_t queueId) { - this->queueId = queueId; -} - -int32_t ReplyMessageRequestHeader::getSysFlag() const { - return this->sysFlag; -} - -void ReplyMessageRequestHeader::setSysFlag(int32_t sysFlag) { - this->sysFlag = sysFlag; -} - -int64_t ReplyMessageRequestHeader::getBornTimestamp() const { - return this->bornTimestamp; -} - -void ReplyMessageRequestHeader::setBornTimestamp(int64_t bornTimestamp) { - this->bornTimestamp = bornTimestamp; -} - -int32_t ReplyMessageRequestHeader::getFlag() const { - return this->flag; -} - -void ReplyMessageRequestHeader::setFlag(int32_t flag) { - this->flag = flag; -} - -const std::string& ReplyMessageRequestHeader::getProperties() const { - return this->properties; -} - -void ReplyMessageRequestHeader::setProperties(const std::string& properties) { - this->properties = properties; -} - -int32_t ReplyMessageRequestHeader::getReconsumeTimes() const { - return this->reconsumeTimes; -} - -void ReplyMessageRequestHeader::setReconsumeTimes(int32_t reconsumeTimes) { - this->reconsumeTimes = reconsumeTimes; -} - -bool ReplyMessageRequestHeader::getUnitMode() const { - return this->unitMode; -} - -void ReplyMessageRequestHeader::setUnitMode(bool unitMode) { - this->unitMode = unitMode; -} - -const std::string& ReplyMessageRequestHeader::getBornHost() const { - return this->bornHost; -} - -void ReplyMessageRequestHeader::setBornHost(const std::string& bornHost) { - this->bornHost = bornHost; -} - -const std::string& ReplyMessageRequestHeader::getStoreHost() const { - return this->storeHost; -} - -void ReplyMessageRequestHeader::setStoreHost(const std::string& storeHost) { - this->storeHost = storeHost; -} - -int64_t ReplyMessageRequestHeader::getStoreTimestamp() const { - return this->storeTimestamp; -} - -void ReplyMessageRequestHeader::setStoreTimestamp(int64_t storeTimestamp) { - this->storeTimestamp = storeTimestamp; -} - -} // namespace rocketmq diff --git a/src/protocol/header/ReplyMessageRequestHeader.h b/src/protocol/header/ReplyMessageRequestHeader.h deleted file mode 100644 index 5fd341e5e..000000000 --- a/src/protocol/header/ReplyMessageRequestHeader.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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 __REPLY_MESSAGE_REQUEST_HEADER_H__ -#define __REPLY_MESSAGE_REQUEST_HEADER_H__ - -#include - -#include "CommandCustomHeader.h" - -namespace rocketmq { - -class ReplyMessageRequestHeader : public CommandCustomHeader { - public: - static ReplyMessageRequestHeader* Decode(std::map& extFields); - - const std::string& getProducerGroup() const; - void setProducerGroup(const std::string& producerGroup); - - const std::string& getTopic() const; - void setTopic(const std::string& topic); - - const std::string& getDefaultTopic() const; - void setDefaultTopic(const std::string& defaultTopic); - - int32_t getDefaultTopicQueueNums() const; - void setDefaultTopicQueueNums(int32_t defaultTopicQueueNums); - - int32_t getQueueId() const; - void setQueueId(int32_t queueId); - - int32_t getSysFlag() const; - void setSysFlag(int32_t sysFlag); - - int64_t getBornTimestamp() const; - void setBornTimestamp(int64_t bornTimestamp); - - int32_t getFlag() const; - void setFlag(int32_t flag); - - const std::string& getProperties() const; - void setProperties(const std::string& properties); - - int32_t getReconsumeTimes() const; - void setReconsumeTimes(int32_t reconsumeTimes); - - bool getUnitMode() const; - void setUnitMode(bool unitMode); - - const std::string& getBornHost() const; - void setBornHost(const std::string& bornHost); - - const std::string& getStoreHost() const; - void setStoreHost(const std::string& storeHost); - - int64_t getStoreTimestamp() const; - void setStoreTimestamp(int64_t stroeTimestamp); - - private: - std::string producerGroup; - std::string topic; - std::string defaultTopic; - int32_t defaultTopicQueueNums; - int32_t queueId; - int32_t sysFlag; - int64_t bornTimestamp; - int32_t flag; - std::string properties; // nullable - int32_t reconsumeTimes; // nullable - bool unitMode; // nullable - - std::string bornHost; - std::string storeHost; - int64_t storeTimestamp; -}; - -} // namespace rocketmq - -#endif // __REPLY_MESSAGE_REQUEST_HEADER_H__ diff --git a/src/protocol/header/ReplyMessageRequestHeader.hpp b/src/protocol/header/ReplyMessageRequestHeader.hpp new file mode 100644 index 000000000..3aaab7ba5 --- /dev/null +++ b/src/protocol/header/ReplyMessageRequestHeader.hpp @@ -0,0 +1,132 @@ +/* + * 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_PROTOCOL_HEADER_REPLY_MESSAGE_REQUEST_HEADER_HPP_ +#define ROCKETMQ_PROTOCOL_HEADER_REPLY_MESSAGE_REQUEST_HEADER_HPP_ + +#include + +#include "CommandCustomHeader.h" +#include "UtilAll.h" + +namespace rocketmq { + +class ReplyMessageRequestHeader : public CommandCustomHeader { + public: + static ReplyMessageRequestHeader* Decode(std::map& extFields) { + std::unique_ptr header(new ReplyMessageRequestHeader()); + + header->producer_group_ = extFields.at("producerGroup"); + header->topic_ = extFields.at("topic"); + header->default_topic_ = extFields.at("defaultTopic"); + header->default_topic_queue_nums_ = std::stoi(extFields.at("defaultTopicQueueNums")); + header->queue_id_ = std::stoi(extFields.at("queueId")); + header->sys_flag_ = std::stoi(extFields.at("sysFlag")); + header->born_timestamp_ = std::stoll(extFields.at("bornTimestamp")); + header->flag_ = std::stoi(extFields.at("flag")); + + auto it = extFields.find("properties"); + if (it != extFields.end()) { + header->properties_ = it->second; + } + + it = extFields.find("reconsumeTimes"); + if (it != extFields.end()) { + header->reconsume_times_ = std::stoi(it->second); + } else { + header->reconsume_times_ = 0; + } + + it = extFields.find("unitMode"); + if (it != extFields.end()) { + header->unit_mode_ = UtilAll::stob(it->second); + } else { + header->unit_mode_ = false; + } + + header->born_host_ = extFields.at("bornHost"); + header->store_host_ = extFields.at("storeHost"); + header->store_timestamp_ = std::stoll(extFields.at("storeTimestamp")); + + return header.release(); + } + + public: + inline const std::string& producer_group() const { return this->producer_group_; } + inline void set_producer_group(const std::string& producerGroup) { this->producer_group_ = producerGroup; } + + inline const std::string& topic() const { return this->topic_; } + inline void set_topic(const std::string& topic) { this->topic_ = topic; } + + inline const std::string& default_topic() const { return this->default_topic_; } + inline void set_default_topic(const std::string& defaultTopic) { this->default_topic_ = defaultTopic; } + + inline int32_t default_topic_queue_nums() const { return this->default_topic_queue_nums_; } + inline void set_default_topic_queue_nums(int32_t defaultTopicQueueNums) { + this->default_topic_queue_nums_ = defaultTopicQueueNums; + } + + inline int32_t queue_id() const { return this->queue_id_; } + inline void set_queue_id(int32_t queueId) { this->queue_id_ = queueId; } + + inline int32_t sys_flag() const { return this->sys_flag_; } + inline void set_sys_flag(int32_t sysFlag) { this->sys_flag_ = sysFlag; } + + inline int64_t born_timestamp() const { return this->born_timestamp_; } + inline void set_born_timestamp(int64_t bornTimestamp) { this->born_timestamp_ = bornTimestamp; } + + inline int32_t flag() const { return this->flag_; } + inline void set_flag(int32_t flag) { this->flag_ = flag; } + + inline const std::string& properties() const { return this->properties_; } + inline void set_properties(const std::string& properties) { this->properties_ = properties; } + + inline int32_t reconsume_times() const { return this->reconsume_times_; } + inline void set_reconsume_times(int32_t reconsumeTimes) { this->reconsume_times_ = reconsumeTimes; } + + inline bool unit_mode() const { return this->unit_mode_; } + inline void set_unit_mode(bool unitMode) { this->unit_mode_ = unitMode; } + + inline const std::string& born_host() const { return this->born_host_; } + inline void set_born_host(const std::string& bornHost) { this->born_host_ = bornHost; } + + inline const std::string& store_host() const { return this->store_host_; } + inline void set_store_host(const std::string& storeHost) { this->store_host_ = storeHost; } + + inline int64_t store_timestamp() const { return this->store_timestamp_; } + inline void set_store_timestamp(int64_t storeTimestamp) { this->store_timestamp_ = storeTimestamp; } + + private: + std::string producer_group_; + std::string topic_; + std::string default_topic_; + int32_t default_topic_queue_nums_; + int32_t queue_id_; + int32_t sys_flag_; + int64_t born_timestamp_; + int32_t flag_; + std::string properties_; // nullable + int32_t reconsume_times_; // nullable + bool unit_mode_; // nullable + + std::string born_host_; + std::string store_host_; + int64_t store_timestamp_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_PROTOCOL_HEADER_REPLY_MESSAGE_REQUEST_HEADER_HPP_ diff --git a/src/protocol/heartbeat/ConsumerData.hpp b/src/protocol/heartbeat/ConsumerData.hpp new file mode 100644 index 000000000..470d78be3 --- /dev/null +++ b/src/protocol/heartbeat/ConsumerData.hpp @@ -0,0 +1,83 @@ +/* + * 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_PROTOCOL_HEARTBEAT_CONSUMERDATA_H_ +#define ROCKETMQ_PROTOCOL_HEARTBEAT_CONSUMERDATA_H_ + +#include // std::move +#include // std::string +#include // std::vector + +#include + +#include "ConsumeType.h" +#include "SubscriptionData.hpp" + +namespace rocketmq { + +class ConsumerData { + public: + ConsumerData(const std::string& group_name, + ConsumeType consume_type, + MessageModel message_model, + ConsumeFromWhere consume_from_where, + std::vector&& subscription_data_set) + : group_name_(group_name), + consume_type_(consume_type), + message_model_(message_model), + consume_from_where_(consume_from_where), + subscription_data_set_(std::move(subscription_data_set)) {} + + bool operator<(const ConsumerData& other) const { return group_name_ < other.group_name_; } + + Json::Value toJson() const { + Json::Value root; + root["groupName"] = group_name_; + root["consumeType"] = consume_type_; + root["messageModel"] = message_model_; + root["consumeFromWhere"] = consume_from_where_; + + for (const auto& sd : subscription_data_set_) { + root["subscriptionDataSet"].append(sd.toJson()); + } + + return root; + } + + public: + inline const std::string& group_name() const { return group_name_; } + inline void set_group_name(const std::string& group_name) { group_name_ = group_name; } + + inline ConsumeType consume_type() const { return consume_type_; } + inline void set_consume_type(ConsumeType consume_type) { consume_type_ = consume_type; } + + inline MessageModel message_model() const { return message_model_; } + + inline ConsumeFromWhere consume_from_where() const { return consume_from_where_; } + + inline std::vector subscription_data_set() { return subscription_data_set_; } + + private: + std::string group_name_; + ConsumeType consume_type_; + MessageModel message_model_; + ConsumeFromWhere consume_from_where_; + std::vector subscription_data_set_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_PROTOCOL_HEARTBEAT_CONSUMERDATA_H_ diff --git a/src/protocol/heartbeat/HeartbeatData.hpp b/src/protocol/heartbeat/HeartbeatData.hpp new file mode 100644 index 000000000..f4af3caca --- /dev/null +++ b/src/protocol/heartbeat/HeartbeatData.hpp @@ -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 ROCKETMQ_PROTOCOL_HEARTBEAT_HEARTBEATDATA_H_ +#define ROCKETMQ_PROTOCOL_HEARTBEAT_HEARTBEATDATA_H_ + +#include // std::string +#include // std::vector + +#include "RemotingSerializable.h" +#include "ConsumerData.hpp" +#include "ProducerData.hpp" + +namespace rocketmq { + +class HeartbeatData : public RemotingSerializable { + public: + std::string encode() { + Json::Value root; + + // id + root["clientID"] = client_id_; + + // consumer + for (const auto& cd : consumer_data_set_) { + root["consumerDataSet"].append(cd.toJson()); + } + + // producer + for (const auto& pd : producer_data_set_) { + root["producerDataSet"].append(pd.toJson()); + } + + // output + return RemotingSerializable::toJson(root); + } + + public: + inline void set_client_id(const std::string& clientID) { client_id_ = clientID; } + + inline std::vector& consumer_data_set() { return consumer_data_set_; } + + inline std::vector& producer_data_set() { return producer_data_set_; } + + private: + std::string client_id_; + std::vector consumer_data_set_; + std::vector producer_data_set_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_PROTOCOL_HEARTBEAT_HEARTBEATDATA_H_ diff --git a/src/protocol/body/ResetOffsetBody.h b/src/protocol/heartbeat/ProducerData.hpp similarity index 55% rename from src/protocol/body/ResetOffsetBody.h rename to src/protocol/heartbeat/ProducerData.hpp index f1024b9e5..751a87fb0 100644 --- a/src/protocol/body/ResetOffsetBody.h +++ b/src/protocol/heartbeat/ProducerData.hpp @@ -14,27 +14,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __RESET_OFFSET_BODY__ -#define __RESET_OFFSET_BODY__ +#ifndef ROCKETMQ_PROTOCOL_HEARTBEAT_PRODUCERDATA_H_ +#define ROCKETMQ_PROTOCOL_HEARTBEAT_PRODUCERDATA_H_ -#include // std::map +#include // std::string -#include "ByteArray.h" -#include "MQMessageQueue.h" +#include namespace rocketmq { -class ResetOffsetBody { +class ProducerData { public: - static ResetOffsetBody* Decode(const ByteArray& bodyData); + ProducerData(const std::string& group_name) : group_name_(group_name) {} - std::map getOffsetTable(); - void setOffsetTable(const MQMessageQueue& mq, int64_t offset); + bool operator<(const ProducerData& other) const { return group_name_ < other.group_name_; } + + Json::Value toJson() const { + Json::Value root; + root["groupName"] = group_name_; + return root; + } + + public: + inline const std::string& group_name() const { return group_name_; } + inline void group_name(const std::string& group_name) { group_name_ = group_name; } private: - std::map offset_table_; + std::string group_name_; }; } // namespace rocketmq -#endif // __RESET_OFFSET_BODY__ +#endif // ROCKETMQ_PROTOCOL_HEARTBEAT_PRODUCERDATA_H_ diff --git a/src/common/SubscriptionData.h b/src/protocol/heartbeat/SubscriptionData.hpp similarity index 50% rename from src/common/SubscriptionData.h rename to src/protocol/heartbeat/SubscriptionData.hpp index 277403c02..82f8334c8 100644 --- a/src/common/SubscriptionData.h +++ b/src/protocol/heartbeat/SubscriptionData.hpp @@ -14,32 +14,72 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef ROCKETMQ_SUBSCRIPTIONDATA_H_ -#define ROCKETMQ_SUBSCRIPTIONDATA_H_ +#ifndef ROCKETMQ_PROTOCOL_HEARTBEAT_SUBSCRIPTIONDATA_HPP_ +#define ROCKETMQ_PROTOCOL_HEARTBEAT_SUBSCRIPTIONDATA_HPP_ -#include +#include // int64_t + +#include // std::string +#include // std::vector -#include -#include +#include -#include "RocketMQClient.h" +#include "UtilAll.h" namespace rocketmq { -class ROCKETMQCLIENT_API SubscriptionData { +class SubscriptionData { public: - SubscriptionData(); - SubscriptionData(const std::string& topic, const std::string& subString); - SubscriptionData(const SubscriptionData& other); + SubscriptionData() : sub_version_(UtilAll::currentTimeMillis()) {} + SubscriptionData(const std::string& topic, const std::string& subString) + : topic_(topic), sub_string_(subString), sub_version_(UtilAll::currentTimeMillis()) {} + + SubscriptionData(const SubscriptionData& other) { + sub_string_ = other.sub_string_; + sub_version_ = other.sub_version_; + tag_set_ = other.tag_set_; + topic_ = other.topic_; + code_set_ = other.code_set_; + } virtual ~SubscriptionData() = default; - bool operator==(const SubscriptionData& other) const; + bool operator==(const SubscriptionData& other) const { + // FIXME: tags + return topic_ == other.topic_ && sub_string_ == other.sub_string_ && sub_version_ == other.sub_version_ && + tag_set_.size() == other.tag_set_.size(); + } bool operator!=(const SubscriptionData& other) const { return !operator==(other); } - bool operator<(const SubscriptionData& other) const; + bool operator<(const SubscriptionData& other) const { + int ret = topic_.compare(other.topic_); + if (ret == 0) { + return sub_string_.compare(other.sub_string_) < 0; + } else { + return ret < 0; + } + } + + inline bool containsTag(const std::string& tag) const { + return std::find(tag_set_.begin(), tag_set_.end(), tag) != tag_set_.end(); + } - Json::Value toJson() const; + Json::Value toJson() const { + Json::Value root; + root["topic"] = topic_; + root["subString"] = sub_string_; + root["subVersion"] = UtilAll::to_string(sub_version_); + + for (const auto& tag : tag_set_) { + root["tagsSet"].append(tag); + } + + for (const auto& code : code_set_) { + root["codeSet"].append(code); + } + + return root; + } public: inline const std::string& topic() const { return topic_; } @@ -51,13 +91,7 @@ class ROCKETMQCLIENT_API SubscriptionData { inline std::vector& tags_set() { return tag_set_; } - inline void put_tag(const std::string& tag) { tag_set_.push_back(tag); } - - inline bool contain_tag(const std::string& tag) const { - return std::find(tag_set_.begin(), tag_set_.end(), tag) != tag_set_.end(); - } - - inline void put_code(int32_t code) { code_set_.push_back(code); } + inline std::vector& code_set() { return code_set_; } private: std::string topic_; @@ -69,4 +103,4 @@ class ROCKETMQCLIENT_API SubscriptionData { } // namespace rocketmq -#endif // ROCKETMQ_SUBSCRIPTIONDATA_H_ +#endif // ROCKETMQ_PROTOCOL_HEARTBEAT_SUBSCRIPTIONDATA_HPP_ diff --git a/test/src/protocol/ConsumerRunningInfoTest.cpp b/test/src/protocol/ConsumerRunningInfoTest.cpp index 7c427fd26..7c3dc8f12 100644 --- a/test/src/protocol/ConsumerRunningInfoTest.cpp +++ b/test/src/protocol/ConsumerRunningInfoTest.cpp @@ -24,9 +24,6 @@ #include #include "ConsumerRunningInfo.h" -#include "MessageQueue.h" -#include "ProcessQueueInfo.h" -#include "SubscriptionData.h" using std::map; using std::string; diff --git a/test/src/protocol/HeartbeatDataTest.cpp b/test/src/protocol/HeartbeatDataTest.cpp index a1e5393a9..87f76b23d 100644 --- a/test/src/protocol/HeartbeatDataTest.cpp +++ b/test/src/protocol/HeartbeatDataTest.cpp @@ -19,11 +19,7 @@ #include -#include "ConsumeType.h" -#include "HeartbeatData.h" -#include "SubscriptionData.h" - -using std::vector; +#include "protocol/heartbeat/HeartbeatData.hpp" using testing::InitGoogleMock; using testing::InitGoogleTest; @@ -38,24 +34,16 @@ using rocketmq::ProducerData; using rocketmq::SubscriptionData; TEST(HeartbeatDataTest, ProducerData) { - ProducerData producerData; - producerData.groupName = "testGroup"; + ProducerData producerData("testGroup"); Json::Value outJson = producerData.toJson(); EXPECT_EQ(outJson["groupName"], "testGroup"); } TEST(HeartbeatDataTest, ConsumerData) { - ConsumerData consumerData; - consumerData.groupName = "testGroup"; - consumerData.consumeType = ConsumeType::CONSUME_ACTIVELY; - consumerData.messageModel = MessageModel::BROADCASTING; - consumerData.consumeFromWhere = ConsumeFromWhere::CONSUME_FROM_TIMESTAMP; - - vector subs; - subs.push_back(SubscriptionData("testTopic", "sub")); - - consumerData.subscriptionDataSet = subs; + ConsumerData consumerData("testGroup", ConsumeType::CONSUME_ACTIVELY, MessageModel::BROADCASTING, + ConsumeFromWhere::CONSUME_FROM_TIMESTAMP, + std::vector{SubscriptionData("testTopic", "sub")}); Json::Value outJson = consumerData.toJson(); @@ -72,28 +60,17 @@ TEST(HeartbeatDataTest, ConsumerData) { TEST(HeartbeatDataTest, HeartbeatData) { HeartbeatData heartbeatData; - heartbeatData.setClientID("testClientId"); - - ProducerData producerData; - producerData.groupName = "testGroup"; - - EXPECT_TRUE(heartbeatData.isProducerDataSetEmpty()); - heartbeatData.insertDataToProducerDataSet(producerData); - EXPECT_FALSE(heartbeatData.isProducerDataSetEmpty()); - - ConsumerData consumerData; - consumerData.groupName = "testGroup"; - consumerData.consumeType = ConsumeType::CONSUME_ACTIVELY; - consumerData.messageModel = MessageModel::BROADCASTING; - consumerData.consumeFromWhere = ConsumeFromWhere::CONSUME_FROM_TIMESTAMP; + heartbeatData.set_client_id("testClientId"); - vector subs; - subs.push_back(SubscriptionData("testTopic", "sub")); + EXPECT_TRUE(heartbeatData.producer_data_set().empty()); + heartbeatData.producer_data_set().emplace_back("testGroup"); + EXPECT_FALSE(heartbeatData.producer_data_set().empty()); - consumerData.subscriptionDataSet = subs; - EXPECT_TRUE(heartbeatData.isConsumerDataSetEmpty()); - heartbeatData.insertDataToConsumerDataSet(consumerData); - EXPECT_FALSE(heartbeatData.isConsumerDataSetEmpty()); + EXPECT_TRUE(heartbeatData.consumer_data_set().empty()); + heartbeatData.consumer_data_set().emplace_back("testGroup", ConsumeType::CONSUME_ACTIVELY, MessageModel::BROADCASTING, + ConsumeFromWhere::CONSUME_FROM_TIMESTAMP, + std::vector{SubscriptionData("testTopic", "sub")}); + EXPECT_FALSE(heartbeatData.consumer_data_set().empty()); std::string outData = heartbeatData.encode(); diff --git a/test/src/protocol/LockBatchBodyTest.cpp b/test/src/protocol/LockBatchBodyTest.cpp index 64da9fb0c..853648974 100644 --- a/test/src/protocol/LockBatchBodyTest.cpp +++ b/test/src/protocol/LockBatchBodyTest.cpp @@ -21,7 +21,9 @@ #include "ByteArray.h" #include "MQMessageQueue.h" -#include "protocol/body/LockBatchBody.h" +#include "protocol/body/LockBatchRequestBody.hpp" +#include "protocol/body/LockBatchResponseBody.hpp" +#include "protocol/body/UnlockBatchRequestBody.hpp" using testing::InitGoogleMock; using testing::InitGoogleTest; @@ -36,18 +38,18 @@ using rocketmq::UnlockBatchRequestBody; TEST(LockBatchBodyTest, LockBatchRequestBody) { LockBatchRequestBody lockBatchRequestBody; - lockBatchRequestBody.setClientId("testClientId"); - EXPECT_EQ(lockBatchRequestBody.getClientId(), "testClientId"); + lockBatchRequestBody.set_client_id("testClientId"); + EXPECT_EQ(lockBatchRequestBody.client_id(), "testClientId"); - lockBatchRequestBody.setConsumerGroup("testGroup"); - EXPECT_EQ(lockBatchRequestBody.getConsumerGroup(), "testGroup"); + lockBatchRequestBody.set_consumer_group("testGroup"); + EXPECT_EQ(lockBatchRequestBody.consumer_group(), "testGroup"); std::vector messageQueueList; messageQueueList.push_back(MQMessageQueue("testTopic", "testBroker", 1)); messageQueueList.push_back(MQMessageQueue("testTopic", "testBroker", 2)); - lockBatchRequestBody.setMqSet(messageQueueList); - EXPECT_EQ(lockBatchRequestBody.getMqSet(), messageQueueList); + lockBatchRequestBody.set_mq_set(messageQueueList); + EXPECT_EQ(lockBatchRequestBody.mq_set(), messageQueueList); std::string outData = lockBatchRequestBody.encode(); @@ -81,7 +83,7 @@ TEST(LockBatchBodyTest, LockBatchResponseBody) { std::unique_ptr lockBatchResponseBody(LockBatchResponseBody::Decode(bodyData)); MQMessageQueue messageQueue("testTopic", "testBroker", 1); - EXPECT_EQ(messageQueue, lockBatchResponseBody->getLockOKMQSet()[0]); + EXPECT_EQ(messageQueue, lockBatchResponseBody->lock_ok_mq_set()[0]); } int main(int argc, char* argv[]) { diff --git a/test/src/protocol/MessageQueueTest.cpp b/test/src/protocol/MessageQueueTest.cpp index 0f6f5fcf8..072b4f2db 100644 --- a/test/src/protocol/MessageQueueTest.cpp +++ b/test/src/protocol/MessageQueueTest.cpp @@ -17,7 +17,7 @@ #include #include -#include "MessageQueue.h" +#include "MessageQueue.hpp" using testing::InitGoogleMock; using testing::InitGoogleTest; diff --git a/test/src/protocol/TopicRouteDataTest.cpp b/test/src/protocol/TopicRouteDataTest.cpp index cb70c100c..ef94cdbbb 100644 --- a/test/src/protocol/TopicRouteDataTest.cpp +++ b/test/src/protocol/TopicRouteDataTest.cpp @@ -20,7 +20,7 @@ #include #include "ByteArray.h" -#include "TopicRouteData.hpp" +#include "protocol/body/TopicRouteData.hpp" using testing::InitGoogleMock; using testing::InitGoogleTest; diff --git a/test/src/transport/ClientRemotingProcessorTest.cpp b/test/src/transport/ClientRemotingProcessorTest.cpp index 34f7c6acb..1a840d939 100644 --- a/test/src/transport/ClientRemotingProcessorTest.cpp +++ b/test/src/transport/ClientRemotingProcessorTest.cpp @@ -34,7 +34,7 @@ #include "SessionCredentials.h" #include "TcpTransport.h" #include "UtilAll.h" -#include "protocol/body/ResetOffsetBody.h" +#include "protocol/body/ResetOffsetBody.hpp" #include "protocol/header/CommandHeader.h" using testing::_; From a281df90ef3c3656b75b294627c4c60f4aae6dfc Mon Sep 17 00:00:00 2001 From: James Yin Date: Mon, 21 Sep 2020 15:27:31 +0800 Subject: [PATCH 19/62] refactor: MQMessageExt::from_list --- include/MQMessageExt.h | 3 +++ src/consumer/ConsumeMessageConcurrentlyService.cpp | 6 +----- src/consumer/ConsumeMessageOrderlyService.cpp | 6 +----- src/message/MQMessageExt.cpp | 9 +++++++++ 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/MQMessageExt.h b/include/MQMessageExt.h index d00ea94b1..0599c0621 100644 --- a/include/MQMessageExt.h +++ b/include/MQMessageExt.h @@ -28,6 +28,9 @@ namespace rocketmq { class ROCKETMQCLIENT_API MQMessageExt : public MQMessage, // base virtual public MessageExt // interface { + public: + static std::vector from_list(std::vector& msg_list); + public: MQMessageExt(); MQMessageExt(int queueId, diff --git a/src/consumer/ConsumeMessageConcurrentlyService.cpp b/src/consumer/ConsumeMessageConcurrentlyService.cpp index 16d725bfb..ffbf8928f 100755 --- a/src/consumer/ConsumeMessageConcurrentlyService.cpp +++ b/src/consumer/ConsumeMessageConcurrentlyService.cpp @@ -88,11 +88,7 @@ void ConsumeMessageConcurrentlyService::ConsumeRequest(std::vector message_list; - message_list.reserve(msgs.size()); - for (const auto& msg : msgs) { - message_list.emplace_back(msg); - } + auto message_list = MQMessageExt::from_list(msgs); status = message_listener_->consumeMessage(message_list); } catch (const std::exception& e) { LOG_WARN_NEW("encounter unexpected exception when consume messages.\n{}", e.what()); diff --git a/src/consumer/ConsumeMessageOrderlyService.cpp b/src/consumer/ConsumeMessageOrderlyService.cpp index 0dd2c16c6..a14431e6c 100755 --- a/src/consumer/ConsumeMessageOrderlyService.cpp +++ b/src/consumer/ConsumeMessageOrderlyService.cpp @@ -158,11 +158,7 @@ void ConsumeMessageOrderlyService::ConsumeRequest(ProcessQueuePtr processQueue, messageQueue.toString()); break; } - std::vector message_list; - message_list.reserve(msgs.size()); - for (const auto& msg : msgs) { - message_list.emplace_back(msg); - } + auto message_list = MQMessageExt::from_list(msgs); status = message_listener_->consumeMessage(message_list); } catch (const std::exception& e) { LOG_WARN_NEW("encounter unexpected exception when consume messages.\n{}", e.what()); diff --git a/src/message/MQMessageExt.cpp b/src/message/MQMessageExt.cpp index a58d0352c..92e8b8e6b 100644 --- a/src/message/MQMessageExt.cpp +++ b/src/message/MQMessageExt.cpp @@ -21,6 +21,15 @@ namespace rocketmq { +std::vector MQMessageExt::from_list(std::vector& msg_list) { + std::vector message_list; + message_list.reserve(msg_list.size()); + for (const auto& msg : msg_list) { + message_list.emplace_back(msg); + } + return message_list; +} + MQMessageExt::MQMessageExt() : MQMessageExt(0, 0, nullptr, 0, nullptr, null) {} MQMessageExt::MQMessageExt(int queueId, From a5aa61ea98f20153131f6410c16fe4d933e7a093 Mon Sep 17 00:00:00 2001 From: James Yin Date: Mon, 21 Sep 2020 15:29:02 +0800 Subject: [PATCH 20/62] refactor: concurrent_queue --- src/concurrent/concurrent_queue.hpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/concurrent/concurrent_queue.hpp b/src/concurrent/concurrent_queue.hpp index d826f3053..7fed592a4 100644 --- a/src/concurrent/concurrent_queue.hpp +++ b/src/concurrent/concurrent_queue.hpp @@ -45,7 +45,7 @@ class concurrent_queue_node { explicit concurrent_queue_node(E v) : value_(v) {} value_type* value_; - type* volatile next_; + std::atomic next_; friend concurrent_queue; }; @@ -69,17 +69,20 @@ class concurrent_queue { } concurrent_queue(bool clear_when_destruct = true) - : sentinel((node_type*)new char[sizeof(node_type)]), _clear_when_destruct(clear_when_destruct) { - sentinel->next_ = sentinel; + : sentinel((node_type*)new char[sizeof(node_type)]), size_(0), _clear_when_destruct(clear_when_destruct) { + sentinel->next_.store(sentinel); head_ = tail_ = sentinel; } bool empty() { return sentinel == tail_.load(); } + size_t size() { return size_.load(); } + template void push_back(E&& v) { auto* node = new node_type(std::forward(v)); push_back_impl(node); + size_.fetch_add(1); } std::unique_ptr pop_front() { @@ -87,6 +90,7 @@ class concurrent_queue { if (node == sentinel) { return std::unique_ptr(); } else { + size_.fetch_sub(1); auto val = node->value_; delete node; return std::unique_ptr(val); @@ -95,13 +99,13 @@ class concurrent_queue { private: void push_back_impl(node_type* node) noexcept { - node->next_ = sentinel; + node->next_.store(sentinel); auto tail = tail_.exchange(node); if (tail == sentinel) { head_.store(node); } else { // guarantee: tail is not released - tail->next_ = node; + tail->next_.store(node); } } @@ -114,7 +118,7 @@ class concurrent_queue { } if (head != nullptr) { if (head_.compare_exchange_weak(head, nullptr)) { - auto next = head->next_; + auto next = head->next_.load(); if (next == sentinel) { auto t = head; // only one element @@ -126,10 +130,10 @@ class concurrent_queue { size_t j = 0; do { // push-pop conflict, spin - if (0 == j++ % 10) { + if (0 == ++j % 10) { std::this_thread::yield(); } - next = head->next_; + next = head->next_.load(); } while (next == sentinel); } head_.store(next); @@ -147,6 +151,7 @@ class concurrent_queue { std::atomic head_, tail_; node_type* const sentinel; + std::atomic size_; bool _clear_when_destruct; }; From 505ea47e46439cbb273bd7dc38e4bda895a4265f Mon Sep 17 00:00:00 2001 From: James Yin Date: Mon, 21 Sep 2020 15:32:28 +0800 Subject: [PATCH 21/62] refactor: NamespaceUtil --- include/MQClientConfig.h | 5 +- include/MQClientConfigProxy.h | 5 +- src/MQClientConfigImpl.hpp | 10 +- src/common/NameSpaceUtil.cpp | 40 ------ src/common/NamespaceUtil.cpp | 119 ++++++++++++++++++ .../{NameSpaceUtil.h => NamespaceUtil.h} | 18 ++- src/common/UtilAll.cpp | 12 +- src/common/UtilAll.h | 6 +- 8 files changed, 161 insertions(+), 54 deletions(-) delete mode 100644 src/common/NameSpaceUtil.cpp create mode 100644 src/common/NamespaceUtil.cpp rename src/common/{NameSpaceUtil.h => NamespaceUtil.h} (62%) diff --git a/include/MQClientConfig.h b/include/MQClientConfig.h index ade13f01f..645fc05fe 100644 --- a/include/MQClientConfig.h +++ b/include/MQClientConfig.h @@ -50,7 +50,10 @@ class ROCKETMQCLIENT_API MQClientConfig { virtual void set_instance_name(const std::string& instanceName) = 0; virtual const std::string& unit_name() const = 0; - virtual void set_unit_name(std::string unitName) = 0; + virtual void set_unit_name(const std::string& unitName) = 0; + + virtual const std::string& name_space() const = 0; + virtual void set_name_space(const std::string& name_space) = 0; /** * the num of threads to distribute network data diff --git a/include/MQClientConfigProxy.h b/include/MQClientConfigProxy.h index 8cea1bbc8..981fc7f32 100644 --- a/include/MQClientConfigProxy.h +++ b/include/MQClientConfigProxy.h @@ -44,7 +44,10 @@ class ROCKETMQCLIENT_API MQClientConfigProxy : virtual public MQClientConfig // void set_instance_name(const std::string& instanceName) override { client_config_->set_instance_name(instanceName); } const std::string& unit_name() const override { return client_config_->unit_name(); } - void set_unit_name(std::string unitName) override { client_config_->set_unit_name(unitName); } + void set_unit_name(const std::string& unitName) override { client_config_->set_unit_name(unitName); } + + const std::string& name_space() const override { return client_config_->name_space(); } + void set_name_space(const std::string& name_space) override { client_config_->set_name_space(name_space); } int tcp_transport_worker_thread_nums() const override { return client_config_->tcp_transport_worker_thread_nums(); } void set_tcp_transport_worker_thread_nums(int num) override { diff --git a/src/MQClientConfigImpl.hpp b/src/MQClientConfigImpl.hpp index c0aa341f0..59b46018a 100644 --- a/src/MQClientConfigImpl.hpp +++ b/src/MQClientConfigImpl.hpp @@ -21,7 +21,7 @@ #include // std::thread::hardware_concurrency #include "MQClientConfig.h" -#include "NameSpaceUtil.h" +#include "NamespaceUtil.h" #include "UtilAll.h" namespace rocketmq { @@ -67,14 +67,17 @@ class MQClientConfigImpl : virtual public MQClientConfig { const std::string& namesrv_addr() const override { return namesrv_addr_; } void set_namesrv_addr(const std::string& namesrvAddr) override { - namesrv_addr_ = NameSpaceUtil::formatNameServerURL(namesrvAddr); + namesrv_addr_ = NamespaceUtil::formatNameServerURL(namesrvAddr); } const std::string& instance_name() const override { return instance_name_; } void set_instance_name(const std::string& instanceName) override { instance_name_ = instanceName; } const std::string& unit_name() const override { return unit_name_; } - void set_unit_name(std::string unitName) override { unit_name_ = unitName; } + void set_unit_name(const std::string& unitName) override { unit_name_ = unitName; } + + const std::string& name_space() const override { return name_space_; } + void set_name_space(const std::string& name_space) override { name_space_ = name_space; } int tcp_transport_worker_thread_nums() const override { return tcp_worker_thread_nums_; } void set_tcp_transport_worker_thread_nums(int num) override { @@ -96,6 +99,7 @@ class MQClientConfigImpl : virtual public MQClientConfig { std::string instance_name_; std::string group_name_; std::string unit_name_; + std::string name_space_; int tcp_worker_thread_nums_; uint64_t tcp_connect_timeout; // ms diff --git a/src/common/NameSpaceUtil.cpp b/src/common/NameSpaceUtil.cpp deleted file mode 100644 index f7ceec7de..000000000 --- a/src/common/NameSpaceUtil.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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" - -namespace rocketmq { - -bool NameSpaceUtil::isEndPointURL(std::string nameServerAddr) { - if (nameServerAddr.length() >= ENDPOINT_PREFIX_LENGTH && nameServerAddr.find(ENDPOINT_PREFIX) != std::string::npos) { - return true; - } - return false; -} - -std::string NameSpaceUtil::formatNameServerURL(std::string nameServerAddr) { - auto index = nameServerAddr.find(ENDPOINT_PREFIX); - if (index != std::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; -} - -} // namespace rocketmq diff --git a/src/common/NamespaceUtil.cpp b/src/common/NamespaceUtil.cpp new file mode 100644 index 000000000..96391c5df --- /dev/null +++ b/src/common/NamespaceUtil.cpp @@ -0,0 +1,119 @@ +/* + * 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 "UtilAll.h" + +namespace rocketmq { + +static const char NAMESPACE_SEPARATOR = '%'; +static const std::string STRING_BLANK = ""; +static const size_t RETRY_PREFIX_LENGTH = RETRY_GROUP_TOPIC_PREFIX.length(); +static const size_t DLQ_PREFIX_LENGTH = DLQ_GROUP_TOPIC_PREFIX.length(); + +static const std::string ENDPOINT_PREFIX = "http://"; +static const size_t ENDPOINT_PREFIX_LENGTH = ENDPOINT_PREFIX.length(); + +std::string NamespaceUtil::withoutNamespace(const std::string& resourceWithNamespace) { + if (resourceWithNamespace.empty() || isSystemResource(resourceWithNamespace)) { + return resourceWithNamespace; + } + + auto resourceWithoutRetryAndDLQ = withoutRetryAndDLQ(resourceWithNamespace); + auto index = resourceWithoutRetryAndDLQ.find(NAMESPACE_SEPARATOR); + if (index > 0) { + auto resourceWithoutNamespace = resourceWithoutRetryAndDLQ.substr(index + 1); + if (UtilAll::isRetryTopic(resourceWithNamespace)) { + return UtilAll::getRetryTopic(resourceWithoutNamespace); + } else if (UtilAll::isDLQTopic(resourceWithNamespace)) { + return UtilAll::getDLQTopic(resourceWithoutNamespace); + } else { + return resourceWithoutNamespace; + } + } + + return resourceWithNamespace; +} + +std::string NamespaceUtil::withoutNamespace(const std::string& resourceWithNamespace, const std::string& name_space) { + if (resourceWithNamespace.empty() || name_space.empty()) { + return resourceWithNamespace; + } + + auto resourceWithoutRetryAndDLQ = withoutRetryAndDLQ(resourceWithNamespace); + if (resourceWithoutRetryAndDLQ.find(name_space + NAMESPACE_SEPARATOR) == 0) { + return withoutNamespace(resourceWithNamespace); + } + + return resourceWithNamespace; +} + +std::string NamespaceUtil::wrapNamespace(const std::string& name_space, const std::string& resourceWithoutNamespace) { + if (name_space.empty() || resourceWithoutNamespace.empty()) { + return resourceWithoutNamespace; + } + + // if (isSystemResource(resourceWithoutNamespace) || isAlreadyWithNamespace(resourceWithoutNamespace, namespace)) { + // return resourceWithoutNamespace; + // } + + auto resourceWithoutRetryAndDLQ = withoutRetryAndDLQ(resourceWithoutNamespace); + + std::string resourceWithNamespace; + + if (UtilAll::isRetryTopic(resourceWithoutNamespace)) { + resourceWithNamespace.append(RETRY_GROUP_TOPIC_PREFIX); + } + + if (UtilAll::isDLQTopic(resourceWithoutNamespace)) { + resourceWithNamespace.append(DLQ_GROUP_TOPIC_PREFIX); + } + + resourceWithNamespace.append(name_space); + resourceWithNamespace.push_back(NAMESPACE_SEPARATOR); + resourceWithNamespace.append(resourceWithoutRetryAndDLQ); + + return resourceWithNamespace; +} + +std::string NamespaceUtil::withoutRetryAndDLQ(const std::string& originalResource) { + if (UtilAll::isRetryTopic(originalResource)) { + return originalResource.substr(RETRY_PREFIX_LENGTH); + } else if (UtilAll::isDLQTopic(originalResource)) { + return originalResource.substr(DLQ_PREFIX_LENGTH); + } else { + return originalResource; + } +} + +bool NamespaceUtil::isSystemResource(const std::string& resource) { + return false; +} + +bool NamespaceUtil::isEndPointURL(const std::string& nameServerAddr) { + return nameServerAddr.find(ENDPOINT_PREFIX) == 0; +} + +std::string NamespaceUtil::formatNameServerURL(const std::string& nameServerAddr) { + if (nameServerAddr.find(ENDPOINT_PREFIX) == 0) { + return nameServerAddr.substr(ENDPOINT_PREFIX_LENGTH); + } + return nameServerAddr; +} + +} // namespace rocketmq diff --git a/src/common/NameSpaceUtil.h b/src/common/NamespaceUtil.h similarity index 62% rename from src/common/NameSpaceUtil.h rename to src/common/NamespaceUtil.h index 2e19c0a07..6255d5f8d 100644 --- a/src/common/NameSpaceUtil.h +++ b/src/common/NamespaceUtil.h @@ -21,14 +21,20 @@ namespace rocketmq { -static const std::string ENDPOINT_PREFIX = "http://"; -static const unsigned int ENDPOINT_PREFIX_LENGTH = ENDPOINT_PREFIX.length(); - -class NameSpaceUtil { +class NamespaceUtil { public: - static bool isEndPointURL(std::string nameServerAddr); + static std::string withoutNamespace(const std::string& resourceWithNamespace); + static std::string withoutNamespace(const std::string& resourceWithNamespace, const std::string& name_space); + + static std::string wrapNamespace(const std::string& name_space, const std::string& resourceWithoutNamespace); + + static std::string withoutRetryAndDLQ(const std::string& originalResource); + + static bool isSystemResource(const std::string& resource); + + static bool isEndPointURL(const std::string& nameServerAddr); - static std::string formatNameServerURL(std::string nameServerAddr); + static std::string formatNameServerURL(const std::string& nameServerAddr); }; } // namespace rocketmq diff --git a/src/common/UtilAll.cpp b/src/common/UtilAll.cpp index 658695f19..90dec5b8f 100644 --- a/src/common/UtilAll.cpp +++ b/src/common/UtilAll.cpp @@ -117,14 +117,22 @@ void UtilAll::string2bytes(char* dest, const std::string& src) { } } -bool UtilAll::isRetryTopic(const std::string& topic) { - return topic.find(RETRY_GROUP_TOPIC_PREFIX) == 0; +bool UtilAll::isRetryTopic(const std::string& resource) { + return resource.find(RETRY_GROUP_TOPIC_PREFIX) == 0; +} + +bool UtilAll::isDLQTopic(const std::string& resource) { + return resource.find(DLQ_GROUP_TOPIC_PREFIX) == 0; } std::string UtilAll::getRetryTopic(const std::string& consumerGroup) { return RETRY_GROUP_TOPIC_PREFIX + consumerGroup; } +std::string UtilAll::getDLQTopic(const std::string& consumerGroup) { + return DLQ_GROUP_TOPIC_PREFIX + consumerGroup; +} + std::string UtilAll::getReplyTopic(const std::string& clusterName) { return clusterName + "_" + REPLY_TOPIC_POSTFIX; } diff --git a/src/common/UtilAll.h b/src/common/UtilAll.h index 51937142b..8ad49b00f 100644 --- a/src/common/UtilAll.h +++ b/src/common/UtilAll.h @@ -97,8 +97,12 @@ class UtilAll { static std::string bytes2string(const char* bytes, size_t len); static void string2bytes(char* dest, const std::string& src); - static bool isRetryTopic(const std::string& topic); + static bool isRetryTopic(const std::string& resource); + static bool isDLQTopic(const std::string& resource); + static std::string getRetryTopic(const std::string& consumerGroup); + static std::string getDLQTopic(const std::string& consumerGroup); + static std::string getReplyTopic(const std::string& clusterName); static void Trim(std::string& str); From 444dc1419e14f68699ff249a95630db9f26aed36 Mon Sep 17 00:00:00 2001 From: James Yin Date: Mon, 21 Sep 2020 15:39:27 +0800 Subject: [PATCH 22/62] refactor: DefaultMQPushConsumer --- example/RequestReply.cpp | 2 +- include/DefaultMQPushConsumer.h | 18 +- include/DefaultMQPushConsumerConfig.h | 22 +- include/DefaultMQPushConsumerConfigProxy.h | 32 +- include/MQConsumer.h | 42 -- include/MQPushConsumer.h | 21 +- .../ConsumeMessageConcurrentlyService.cpp | 3 +- src/consumer/ConsumeMessageOrderlyService.cpp | 2 +- src/consumer/DefaultMQPushConsumer.cpp | 28 +- .../DefaultMQPushConsumerConfigImpl.hpp | 38 +- src/consumer/DefaultMQPushConsumerImpl.cpp | 418 +++++++++--------- src/consumer/DefaultMQPushConsumerImpl.h | 73 +-- src/consumer/MQConsumerInner.h | 8 +- src/consumer/RebalanceImpl.cpp | 1 - src/extern/CPushConsumer.cpp | 2 +- 15 files changed, 322 insertions(+), 388 deletions(-) delete mode 100755 include/MQConsumer.h diff --git a/example/RequestReply.cpp b/example/RequestReply.cpp index 79b4212e9..c69e3195d 100644 --- a/example/RequestReply.cpp +++ b/example/RequestReply.cpp @@ -77,7 +77,7 @@ int main(int argc, char* argv[]) { consumer.set_consume_from_where(CONSUME_FROM_LAST_OFFSET); // recommend client configs - consumer.set_pull_time_delay_mills_when_exception(0L); + consumer.set_pull_time_delay_millis_when_exception(0L); consumer.subscribe(info.topic, "*"); diff --git a/include/DefaultMQPushConsumer.h b/include/DefaultMQPushConsumer.h index b6276b452..e27ae678b 100755 --- a/include/DefaultMQPushConsumer.h +++ b/include/DefaultMQPushConsumer.h @@ -29,27 +29,25 @@ class ROCKETMQCLIENT_API DefaultMQPushConsumer : public DefaultMQPushConsumerCon public: DefaultMQPushConsumer(const std::string& groupname); DefaultMQPushConsumer(const std::string& groupname, RPCHookPtr rpcHook); + virtual ~DefaultMQPushConsumer(); - public: // MQConsumer + public: // MQPushConsumer void start() override; void shutdown() override; - bool sendMessageBack(MessageExtPtr msg, int delayLevel) override; - bool sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) override; - void fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) override; + void suspend() override; + void resume() override; + + MQMessageListener* getMessageListener() const override; - public: // MQPushConsumer - void registerMessageListener(MQMessageListener* messageListener) override; void registerMessageListener(MessageListenerConcurrently* messageListener) override; void registerMessageListener(MessageListenerOrderly* messageListener) override; - MQMessageListener* getMessageListener() const override; - void subscribe(const std::string& topic, const std::string& subExpression) override; - void suspend() override; - void resume() override; + bool sendMessageBack(MessageExtPtr msg, int delayLevel) override; + bool sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) override; public: void setRPCHook(RPCHookPtr rpcHook); diff --git a/include/DefaultMQPushConsumerConfig.h b/include/DefaultMQPushConsumerConfig.h index ee3988e97..5c894b4ad 100644 --- a/include/DefaultMQPushConsumerConfig.h +++ b/include/DefaultMQPushConsumerConfig.h @@ -50,26 +50,26 @@ class ROCKETMQCLIENT_API DefaultMQPushConsumerConfig : virtual public MQClientCo virtual void set_consume_thread_nums(int threadNum) = 0; /** - * the pull number of message size by each pullMsg for orderly consume, default value is 1 + * max cache msg size per Queue in memory if consumer could not consume msgs immediately, + * default maxCacheMsgSize per Queue is 1000, set range is:1~65535 */ - virtual int consume_message_batch_max_size() const = 0; - virtual void set_consume_message_batch_max_size(int consumeMessageBatchMaxSize) = 0; + virtual int pull_threshold_for_queue() const = 0; + virtual void set_pull_threshold_for_queue(int maxCacheSize) = 0; /** - * max cache msg size per Queue in memory if consumer could not consume msgs immediately, - * default maxCacheMsgSize per Queue is 1000, set range is:1~65535 + * the pull number of message size by each pullMsg for orderly consume, default value is 1 */ - virtual int max_cache_msg_size_per_queue() const = 0; - virtual void set_max_cache_msg_size_per_queue(int maxCacheSize) = 0; + virtual int consume_message_batch_max_size() const = 0; + virtual void set_consume_message_batch_max_size(int consumeMessageBatchMaxSize) = 0; - virtual int async_pull_timeout() const = 0; - virtual void set_async_pull_timeout(int asyncPullTimeout) = 0; + virtual int pull_batch_size() const = 0; + virtual void set_pull_batch_size(int pull_batch_size) = 0; virtual int max_reconsume_times() const = 0; virtual void set_max_reconsume_times(int maxReconsumeTimes) = 0; - virtual long pull_time_delay_mills_when_exception() const = 0; - virtual void set_pull_time_delay_mills_when_exception(long pullTimeDelayMillsWhenException) = 0; + virtual long pull_time_delay_millis_when_exception() const = 0; + virtual void set_pull_time_delay_millis_when_exception(long pull_time_delay_millis_when_exception) = 0; virtual AllocateMQStrategy* allocate_mq_strategy() const = 0; virtual void set_allocate_mq_strategy(AllocateMQStrategy* strategy) = 0; diff --git a/include/DefaultMQPushConsumerConfigProxy.h b/include/DefaultMQPushConsumerConfigProxy.h index 4a0c22fcc..e7b6895b3 100644 --- a/include/DefaultMQPushConsumerConfigProxy.h +++ b/include/DefaultMQPushConsumerConfigProxy.h @@ -62,6 +62,14 @@ class ROCKETMQCLIENT_API DefaultMQPushConsumerConfigProxy : public MQClientConfi dynamic_cast(client_config_.get())->set_consume_thread_nums(threadNum); } + int pull_threshold_for_queue() const override { + return dynamic_cast(client_config_.get())->pull_threshold_for_queue(); + } + + void set_pull_threshold_for_queue(int maxCacheSize) override { + dynamic_cast(client_config_.get())->set_pull_threshold_for_queue(maxCacheSize); + } + int consume_message_batch_max_size() const override { return dynamic_cast(client_config_.get())->consume_message_batch_max_size(); } @@ -71,20 +79,12 @@ class ROCKETMQCLIENT_API DefaultMQPushConsumerConfigProxy : public MQClientConfi ->set_consume_message_batch_max_size(consumeMessageBatchMaxSize); } - int max_cache_msg_size_per_queue() const override { - return dynamic_cast(client_config_.get())->max_cache_msg_size_per_queue(); - } - - void set_max_cache_msg_size_per_queue(int maxCacheSize) override { - dynamic_cast(client_config_.get())->set_max_cache_msg_size_per_queue(maxCacheSize); - } - - int async_pull_timeout() const override { - return dynamic_cast(client_config_.get())->async_pull_timeout(); + int pull_batch_size() const override { + return dynamic_cast(client_config_.get())->pull_batch_size(); } - void set_async_pull_timeout(int asyncPullTimeout) override { - dynamic_cast(client_config_.get())->set_async_pull_timeout(asyncPullTimeout); + void set_pull_batch_size(int pull_batch_size) override { + dynamic_cast(client_config_.get())->set_pull_batch_size(pull_batch_size); } int max_reconsume_times() const override { @@ -95,13 +95,13 @@ class ROCKETMQCLIENT_API DefaultMQPushConsumerConfigProxy : public MQClientConfi dynamic_cast(client_config_.get())->set_max_reconsume_times(maxReconsumeTimes); } - long pull_time_delay_mills_when_exception() const override { - return dynamic_cast(client_config_.get())->pull_time_delay_mills_when_exception(); + long pull_time_delay_millis_when_exception() const override { + return dynamic_cast(client_config_.get())->pull_time_delay_millis_when_exception(); } - void set_pull_time_delay_mills_when_exception(long pullTimeDelayMillsWhenException) override { + void set_pull_time_delay_millis_when_exception(long pull_time_delay_millis_when_exception) override { dynamic_cast(client_config_.get()) - ->set_pull_time_delay_mills_when_exception(pullTimeDelayMillsWhenException); + ->set_pull_time_delay_millis_when_exception(pull_time_delay_millis_when_exception); } AllocateMQStrategy* allocate_mq_strategy() const override { diff --git a/include/MQConsumer.h b/include/MQConsumer.h deleted file mode 100755 index 49c0b4837..000000000 --- a/include/MQConsumer.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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_MQCONSUMER_H_ -#define ROCKETMQ_MQCONSUMER_H_ - -#include "MQMessageExt.h" - -namespace rocketmq { - -/** - * MQConsumer - interface for consumer - */ -class ROCKETMQCLIENT_API MQConsumer { - public: - virtual ~MQConsumer() = default; - - public: // MQConsumer in Java - virtual void start() = 0; - virtual void shutdown() = 0; - - virtual bool sendMessageBack(MessageExtPtr msg, int delayLevel) = 0; - virtual bool sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) = 0; - virtual void fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) = 0; -}; - -} // namespace rocketmq - -#endif // ROCKETMQ_MQCONSUMER_H_ diff --git a/include/MQPushConsumer.h b/include/MQPushConsumer.h index 0ee8aaa7e..f9ac0da07 100644 --- a/include/MQPushConsumer.h +++ b/include/MQPushConsumer.h @@ -17,7 +17,7 @@ #ifndef ROCKETMQ_MQPUSHCONSUMER_H_ #define ROCKETMQ_MQPUSHCONSUMER_H_ -#include "MQConsumer.h" +#include "MQMessageExt.h" #include "MQMessageListener.h" namespace rocketmq { @@ -25,21 +25,24 @@ namespace rocketmq { /** * MQPushConsumer - interface for push consumer */ -class ROCKETMQCLIENT_API MQPushConsumer : public MQConsumer // base interface -{ +class ROCKETMQCLIENT_API MQPushConsumer { public: // MQPushConsumer in Java - // [[deprecated]] - virtual void registerMessageListener(MQMessageListener* messageListener) = 0; - virtual void registerMessageListener(MessageListenerConcurrently* messageListener) = 0; - virtual void registerMessageListener(MessageListenerOrderly* messageListener) = 0; + virtual void start() = 0; + virtual void shutdown() = 0; + + virtual void suspend() = 0; + virtual void resume() = 0; virtual MQMessageListener* getMessageListener() const = 0; + virtual void registerMessageListener(MessageListenerConcurrently* messageListener) = 0; + virtual void registerMessageListener(MessageListenerOrderly* messageListener) = 0; + virtual void subscribe(const std::string& topic, const std::string& subExpression) = 0; // virtual void subscribe(const std::string& topic, MessageSelector* selector) = 0; - virtual void suspend() = 0; - virtual void resume() = 0; + virtual bool sendMessageBack(MessageExtPtr msg, int delay_level) = 0; + virtual bool sendMessageBack(MessageExtPtr msg, int delay_level, const std::string& broker_name) = 0; }; } // namespace rocketmq diff --git a/src/consumer/ConsumeMessageConcurrentlyService.cpp b/src/consumer/ConsumeMessageConcurrentlyService.cpp index ffbf8928f..ed0d89bee 100755 --- a/src/consumer/ConsumeMessageConcurrentlyService.cpp +++ b/src/consumer/ConsumeMessageConcurrentlyService.cpp @@ -75,8 +75,7 @@ void ConsumeMessageConcurrentlyService::ConsumeRequest(std::vectorresetRetryTopic( - msgs, consumer_->getDefaultMQPushConsumerConfig()->group_name()); // set where to sendMessageBack + consumer_->resetRetryAndNamespace(msgs); // set where to sendMessageBack ConsumeStatus status = RECONSUME_LATER; try { diff --git a/src/consumer/ConsumeMessageOrderlyService.cpp b/src/consumer/ConsumeMessageOrderlyService.cpp index a14431e6c..aa81707f4 100755 --- a/src/consumer/ConsumeMessageOrderlyService.cpp +++ b/src/consumer/ConsumeMessageOrderlyService.cpp @@ -148,7 +148,7 @@ void ConsumeMessageOrderlyService::ConsumeRequest(ProcessQueuePtr processQueue, std::vector msgs; processQueue->takeMessages(msgs, consumeBatchSize); - consumer_->resetRetryTopic(msgs, consumer_->getDefaultMQPushConsumerConfig()->group_name()); + consumer_->resetRetryAndNamespace(msgs); if (!msgs.empty()) { ConsumeStatus status = RECONSUME_LATER; try { diff --git a/src/consumer/DefaultMQPushConsumer.cpp b/src/consumer/DefaultMQPushConsumer.cpp index 894e9656a..7d45f75d4 100644 --- a/src/consumer/DefaultMQPushConsumer.cpp +++ b/src/consumer/DefaultMQPushConsumer.cpp @@ -49,20 +49,16 @@ void DefaultMQPushConsumer::shutdown() { push_consumer_impl_->shutdown(); } -bool DefaultMQPushConsumer::sendMessageBack(MessageExtPtr msg, int delayLevel) { - return push_consumer_impl_->sendMessageBack(msg, delayLevel); -} - -bool DefaultMQPushConsumer::sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) { - return push_consumer_impl_->sendMessageBack(msg, delayLevel, brokerName); +void DefaultMQPushConsumer::suspend() { + push_consumer_impl_->suspend(); } -void DefaultMQPushConsumer::fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) { - push_consumer_impl_->fetchSubscribeMessageQueues(topic, mqs); +void DefaultMQPushConsumer::resume() { + push_consumer_impl_->resume(); } -void DefaultMQPushConsumer::registerMessageListener(MQMessageListener* messageListener) { - push_consumer_impl_->registerMessageListener(messageListener); +MQMessageListener* DefaultMQPushConsumer::getMessageListener() const { + return push_consumer_impl_->getMessageListener(); } void DefaultMQPushConsumer::registerMessageListener(MessageListenerConcurrently* messageListener) { @@ -73,20 +69,16 @@ void DefaultMQPushConsumer::registerMessageListener(MessageListenerOrderly* mess push_consumer_impl_->registerMessageListener(messageListener); } -MQMessageListener* DefaultMQPushConsumer::getMessageListener() const { - return push_consumer_impl_->getMessageListener(); -} - void DefaultMQPushConsumer::subscribe(const std::string& topic, const std::string& subExpression) { push_consumer_impl_->subscribe(topic, subExpression); } -void DefaultMQPushConsumer::suspend() { - push_consumer_impl_->suspend(); +bool DefaultMQPushConsumer::sendMessageBack(MessageExtPtr msg, int delayLevel) { + return push_consumer_impl_->sendMessageBack(msg, delayLevel); } -void DefaultMQPushConsumer::resume() { - push_consumer_impl_->resume(); +bool DefaultMQPushConsumer::sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) { + return push_consumer_impl_->sendMessageBack(msg, delayLevel, brokerName); } void DefaultMQPushConsumer::setRPCHook(RPCHookPtr rpcHook) { diff --git a/src/consumer/DefaultMQPushConsumerConfigImpl.hpp b/src/consumer/DefaultMQPushConsumerConfigImpl.hpp index e2ba06d13..870dfcd80 100644 --- a/src/consumer/DefaultMQPushConsumerConfigImpl.hpp +++ b/src/consumer/DefaultMQPushConsumerConfigImpl.hpp @@ -37,11 +37,11 @@ class DefaultMQPushConsumerConfigImpl : virtual public DefaultMQPushConsumerConf consume_from_where_(ConsumeFromWhere::CONSUME_FROM_LAST_OFFSET), consume_timestamp_("0"), consume_thread_nums_(std::min(8, (int)std::thread::hardware_concurrency())), + pull_threshold_for_queue_(1000), consume_message_batch_max_size_(1), - max_msg_cache_size_(1000), - async_pull_timeout_(30 * 1000), - max_reconsume_times_(-1), - pull_time_delay_mills_when_exception_(3000), + pull_batch_size_(32), + max_reconsume_times_(16), + pull_time_delay_millis_when_exception_(3000), allocate_mq_strategy_(new AllocateMQAveragely()) {} virtual ~DefaultMQPushConsumerConfigImpl() = default; @@ -61,6 +61,9 @@ class DefaultMQPushConsumerConfigImpl : virtual public DefaultMQPushConsumerConf } } + int pull_threshold_for_queue() const override { return pull_threshold_for_queue_; } + void set_pull_threshold_for_queue(int maxCacheSize) override { pull_threshold_for_queue_ = maxCacheSize; } + int consume_message_batch_max_size() const override { return consume_message_batch_max_size_; } void set_consume_message_batch_max_size(int consumeMessageBatchMaxSize) override { if (consumeMessageBatchMaxSize >= 1) { @@ -68,22 +71,15 @@ class DefaultMQPushConsumerConfigImpl : virtual public DefaultMQPushConsumerConf } } - int max_cache_msg_size_per_queue() const override { return max_msg_cache_size_; } - void set_max_cache_msg_size_per_queue(int maxCacheSize) override { - if (maxCacheSize > 0 && maxCacheSize < 65535) { - max_msg_cache_size_ = maxCacheSize; - } - } - - int async_pull_timeout() const override { return async_pull_timeout_; } - void set_async_pull_timeout(int asyncPullTimeout) override { async_pull_timeout_ = asyncPullTimeout; } + int pull_batch_size() const override { return pull_batch_size_; } + void set_pull_batch_size(int pull_batch_size) override { pull_batch_size_ = pull_batch_size; } int max_reconsume_times() const override { return max_reconsume_times_; } void set_max_reconsume_times(int maxReconsumeTimes) override { max_reconsume_times_ = maxReconsumeTimes; } - long pull_time_delay_mills_when_exception() const override { return pull_time_delay_mills_when_exception_; } - void set_pull_time_delay_mills_when_exception(long pullTimeDelayMillsWhenException) override { - pull_time_delay_mills_when_exception_ = pullTimeDelayMillsWhenException; + long pull_time_delay_millis_when_exception() const override { return pull_time_delay_millis_when_exception_; } + void set_pull_time_delay_millis_when_exception(long pull_time_delay_millis_when_exception) override { + pull_time_delay_millis_when_exception_ = pull_time_delay_millis_when_exception; } AllocateMQStrategy* allocate_mq_strategy() const override { return allocate_mq_strategy_.get(); } @@ -96,13 +92,15 @@ class DefaultMQPushConsumerConfigImpl : virtual public DefaultMQPushConsumerConf std::string consume_timestamp_; int consume_thread_nums_; - int consume_message_batch_max_size_; - int max_msg_cache_size_; - int async_pull_timeout_; // 30s + int pull_threshold_for_queue_; + + int consume_message_batch_max_size_; // 1 + int pull_batch_size_; // 32 + int max_reconsume_times_; - long pull_time_delay_mills_when_exception_; // 3000 + long pull_time_delay_millis_when_exception_; // 3000 std::unique_ptr allocate_mq_strategy_; }; diff --git a/src/consumer/DefaultMQPushConsumerImpl.cpp b/src/consumer/DefaultMQPushConsumerImpl.cpp index 740e18b6e..841d4ee16 100644 --- a/src/consumer/DefaultMQPushConsumerImpl.cpp +++ b/src/consumer/DefaultMQPushConsumerImpl.cpp @@ -30,6 +30,7 @@ #include "MQClientInstance.h" #include "MQClientManager.h" #include "MQProtos.h" +#include "NamespaceUtil.h" #include "LocalFileOffsetStore.h" #include "PullAPIWrapper.h" #include "PullMessageService.hpp" @@ -40,9 +41,12 @@ #include "UtilAll.h" #include "Validators.h" +static const long BROKER_SUSPEND_MAX_TIME_MILLIS = 1000 * 15; +static const long CONSUMER_TIMEOUT_MILLIS_WHEN_SUSPEND = 1000 * 30; + namespace rocketmq { -class AsyncPullCallback : public AutoDeletePullCallback { +class DefaultMQPushConsumerImpl::AsyncPullCallback : public AutoDeletePullCallback { public: AsyncPullCallback(DefaultMQPushConsumerImplPtr pushConsumer, PullRequestPtr request, @@ -52,51 +56,47 @@ class AsyncPullCallback : public AutoDeletePullCallback { ~AsyncPullCallback() = default; void onSuccess(PullResult& pullResult) override { - auto defaultMQPushConsumer = default_mq_push_consumer_.lock(); - if (nullptr == defaultMQPushConsumer) { + auto consumer = default_mq_push_consumer_.lock(); + if (nullptr == consumer) { LOG_WARN_NEW("AsyncPullCallback::onSuccess: DefaultMQPushConsumerImpl is released."); return; } - PullResult result = defaultMQPushConsumer->getPullAPIWrapper()->processPullResult(pull_request_->message_queue(), - pullResult, subscription_data_); + PullResult result = + consumer->pull_api_wrapper_->processPullResult(pull_request_->message_queue(), pullResult, subscription_data_); switch (result.pull_status()) { case FOUND: { - int64_t prevRequestOffset = pull_request_->next_offset(); + int64_t prev_request_offset = pull_request_->next_offset(); pull_request_->set_next_offset(result.next_begin_offset()); - int64_t firstMsgOffset = (std::numeric_limits::max)(); - if (result.msg_found_list().empty()) { - defaultMQPushConsumer->executePullRequestImmediately(pull_request_); - } else { - firstMsgOffset = result.msg_found_list()[0]->queue_offset(); + int64_t first_msg_offset = (std::numeric_limits::max)(); + if (!result.msg_found_list().empty()) { + first_msg_offset = result.msg_found_list()[0]->queue_offset(); pull_request_->process_queue()->putMessage(result.msg_found_list()); - defaultMQPushConsumer->getConsumerMsgService()->submitConsumeRequest( - result.msg_found_list(), pull_request_->process_queue(), pull_request_->message_queue(), true); - - defaultMQPushConsumer->executePullRequestImmediately(pull_request_); + consumer->consume_service_->submitConsumeRequest(result.msg_found_list(), pull_request_->process_queue(), + pull_request_->message_queue(), true); } - if (result.next_begin_offset() < prevRequestOffset || firstMsgOffset < prevRequestOffset) { + consumer->executePullRequestImmediately(pull_request_); + + if (result.next_begin_offset() < prev_request_offset || first_msg_offset < prev_request_offset) { LOG_WARN_NEW( "[BUG] pull message result maybe data wrong, nextBeginOffset:{} firstMsgOffset:{} prevRequestOffset:{}", - result.next_begin_offset(), firstMsgOffset, prevRequestOffset); + result.next_begin_offset(), first_msg_offset, prev_request_offset); } - } break; case NO_NEW_MSG: case NO_MATCHED_MSG: pull_request_->set_next_offset(result.next_begin_offset()); - defaultMQPushConsumer->correctTagsOffset(pull_request_); - defaultMQPushConsumer->executePullRequestImmediately(pull_request_); + consumer->correctTagsOffset(pull_request_); + consumer->executePullRequestImmediately(pull_request_); break; case NO_LATEST_MSG: pull_request_->set_next_offset(result.next_begin_offset()); - defaultMQPushConsumer->correctTagsOffset(pull_request_); - defaultMQPushConsumer->executePullRequestLater( - pull_request_, - defaultMQPushConsumer->getDefaultMQPushConsumerConfig()->pull_time_delay_mills_when_exception()); + consumer->correctTagsOffset(pull_request_); + consumer->executePullRequestLater( + pull_request_, consumer->getDefaultMQPushConsumerConfig()->pull_time_delay_mills_when_exception()); break; case OFFSET_ILLEGAL: { LOG_WARN_NEW("the pull request offset illegal, {} {}", pull_request_->toString(), result.toString()); @@ -105,16 +105,16 @@ class AsyncPullCallback : public AutoDeletePullCallback { pull_request_->process_queue()->set_dropped(true); // update and persist offset, then removeProcessQueue - auto pullRequest = pull_request_; - defaultMQPushConsumer->executeTaskLater( - [defaultMQPushConsumer, pullRequest]() { + auto pull_request = pull_request_; + consumer->executeTaskLater( + [consumer, pull_request]() { try { - defaultMQPushConsumer->getOffsetStore()->updateOffset(pullRequest->message_queue(), - pullRequest->next_offset(), false); - defaultMQPushConsumer->getOffsetStore()->persist(pullRequest->message_queue()); - defaultMQPushConsumer->getRebalanceImpl()->removeProcessQueue(pullRequest->message_queue()); + consumer->getOffsetStore()->updateOffset(pull_request->message_queue(), pull_request->next_offset(), + false); + consumer->getOffsetStore()->persist(pull_request->message_queue()); + consumer->getRebalanceImpl()->removeProcessQueue(pull_request->message_queue()); - LOG_WARN_NEW("fix the pull request offset, {}", pullRequest->toString()); + LOG_WARN_NEW("fix the pull request offset, {}", pull_request->toString()); } catch (std::exception& e) { LOG_ERROR_NEW("executeTaskLater Exception: {}", e.what()); } @@ -127,8 +127,8 @@ class AsyncPullCallback : public AutoDeletePullCallback { } void onException(MQException& e) noexcept override { - auto defaultMQPushConsumer = default_mq_push_consumer_.lock(); - if (nullptr == defaultMQPushConsumer) { + auto consumer = default_mq_push_consumer_.lock(); + if (nullptr == consumer) { LOG_WARN_NEW("AsyncPullCallback::onException: DefaultMQPushConsumerImpl is released."); return; } @@ -138,8 +138,8 @@ class AsyncPullCallback : public AutoDeletePullCallback { } // TODO - defaultMQPushConsumer->executePullRequestLater( - pull_request_, defaultMQPushConsumer->getDefaultMQPushConsumerConfig()->pull_time_delay_mills_when_exception()); + consumer->executePullRequestLater( + pull_request_, consumer->getDefaultMQPushConsumerConfig()->pull_time_delay_millis_when_exception()); } private: @@ -156,11 +156,11 @@ DefaultMQPushConsumerImpl::DefaultMQPushConsumerImpl(DefaultMQPushConsumerConfig start_time_(UtilAll::currentTimeMillis()), pause_(false), consume_orderly_(false), + message_listener_(nullptr), + consume_service_(nullptr), rebalance_impl_(new RebalancePushImpl(this)), pull_api_wrapper_(nullptr), - offset_store_(nullptr), - consume_service_(nullptr), - message_listener_(nullptr) {} + offset_store_(nullptr) {} DefaultMQPushConsumerImpl::~DefaultMQPushConsumerImpl() = default; @@ -176,6 +176,10 @@ void DefaultMQPushConsumerImpl::start() { switch (service_state_) { case CREATE_JUST: { + // wrap namespace + client_config_->set_group_name( + NamespaceUtil::wrapNamespace(client_config_->name_space(), client_config_->group_name())); + LOG_INFO_NEW("the consumer [{}] start beginning.", client_config_->group_name()); service_state_ = START_FAILED; @@ -193,10 +197,8 @@ void DefaultMQPushConsumerImpl::start() { // init rebalance_impl_ rebalance_impl_->set_consumer_group(client_config_->group_name()); - rebalance_impl_->set_message_model( - dynamic_cast(client_config_.get())->message_model()); - rebalance_impl_->set_allocate_mq_strategy( - dynamic_cast(client_config_.get())->allocate_mq_strategy()); + rebalance_impl_->set_message_model(getDefaultMQPushConsumerConfig()->message_model()); + rebalance_impl_->set_allocate_mq_strategy(getDefaultMQPushConsumerConfig()->allocate_mq_strategy()); rebalance_impl_->set_client_instance(client_instance_.get()); // init pull_api_wrapper_ @@ -204,7 +206,7 @@ void DefaultMQPushConsumerImpl::start() { // TODO: registerFilterMessageHook // init offset_store_ - switch (dynamic_cast(client_config_.get())->message_model()) { + switch (getDefaultMQPushConsumerConfig()->message_model()) { case MessageModel::BROADCASTING: offset_store_.reset(new LocalFileOffsetStore(client_instance_.get(), client_config_->group_name())); break; @@ -219,16 +221,14 @@ void DefaultMQPushConsumerImpl::start() { LOG_INFO_NEW("start orderly consume service: {}", client_config_->group_name()); consume_orderly_ = true; consume_service_.reset(new ConsumeMessageOrderlyService( - this, dynamic_cast(client_config_.get())->consume_thread_nums(), - message_listener_)); + this, getDefaultMQPushConsumerConfig()->consume_thread_nums(), message_listener_)); } else { // for backward compatible, defaultly and concurrently listeners are allocating // ConsumeMessageConcurrentlyService LOG_INFO_NEW("start concurrently consume service: {}", client_config_->group_name()); consume_orderly_ = false; consume_service_.reset(new ConsumeMessageConcurrentlyService( - this, dynamic_cast(client_config_.get())->consume_thread_nums(), - message_listener_)); + this, getDefaultMQPushConsumerConfig()->consume_thread_nums(), message_listener_)); } consume_service_->start(); @@ -274,13 +274,13 @@ void DefaultMQPushConsumerImpl::checkConfig() { "consumerGroup can not equal " + DEFAULT_CONSUMER_GROUP + ", please specify another one.", -1); } - if (dynamic_cast(client_config_.get())->message_model() != BROADCASTING && - dynamic_cast(client_config_.get())->message_model() != CLUSTERING) { + if (getDefaultMQPushConsumerConfig()->message_model() != BROADCASTING && + getDefaultMQPushConsumerConfig()->message_model() != CLUSTERING) { THROW_MQEXCEPTION(MQClientException, "messageModel is valid", -1); } // allocateMessageQueueStrategy - if (nullptr == dynamic_cast(client_config_.get())->allocate_mq_strategy()) { + if (nullptr == getDefaultMQPushConsumerConfig()->allocate_mq_strategy()) { THROW_MQEXCEPTION(MQClientException, "allocateMessageQueueStrategy is null", -1); } @@ -302,7 +302,7 @@ void DefaultMQPushConsumerImpl::copySubscription() { rebalance_impl_->setSubscriptionData(it.first, subscriptionData); } - switch (dynamic_cast(client_config_.get())->message_model()) { + switch (getDefaultMQPushConsumerConfig()->message_model()) { case BROADCASTING: break; case CLUSTERING: { @@ -335,9 +335,9 @@ void DefaultMQPushConsumerImpl::shutdown() { persistConsumerOffset(); client_instance_->unregisterConsumer(client_config_->group_name()); client_instance_->shutdown(); - LOG_INFO_NEW("the consumer [{}] shutdown OK", client_config_->group_name()); rebalance_impl_->destroy(); service_state_ = SHUTDOWN_ALREADY; + LOG_INFO_NEW("the consumer [{}] shutdown OK", client_config_->group_name()); break; } case CREATE_JUST: @@ -348,53 +348,31 @@ void DefaultMQPushConsumerImpl::shutdown() { } } -bool DefaultMQPushConsumerImpl::sendMessageBack(MessageExtPtr msg, int delayLevel) { - return sendMessageBack(msg, delayLevel, null); +void DefaultMQPushConsumerImpl::suspend() { + pause_ = true; + LOG_INFO_NEW("suspend this consumer, {}", client_config_->group_name()); } -bool DefaultMQPushConsumerImpl::sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) { - try { - std::string brokerAddr = brokerName.empty() ? socketAddress2String(msg->store_host()) - : client_instance_->findBrokerAddressInPublish(brokerName); - - client_instance_->getMQClientAPIImpl()->consumerSendMessageBack( - brokerAddr, msg, dynamic_cast(client_config_.get())->group_name(), delayLevel, - 5000, getMaxReconsumeTimes()); - return true; - } catch (const std::exception& e) { - LOG_ERROR_NEW("sendMessageBack exception, group: {}, msg: {}. {}", - dynamic_cast(client_config_.get())->group_name(), msg->toString(), - e.what()); - } - return false; +void DefaultMQPushConsumerImpl::resume() { + pause_ = false; + doRebalance(); + LOG_INFO_NEW("resume this consumer, {}", client_config_->group_name()); } -void DefaultMQPushConsumerImpl::fetchSubscribeMessageQueues(const std::string& topic, - std::vector& mqs) { - mqs.clear(); - try { - client_instance_->getMQAdminImpl()->fetchSubscribeMessageQueues(topic, mqs); - } catch (MQException& e) { - LOG_ERROR_NEW("{}", e.what()); - } +MQMessageListener* DefaultMQPushConsumerImpl::getMessageListener() const { + return message_listener_; } -void DefaultMQPushConsumerImpl::registerMessageListener(MQMessageListener* messageListener) { - if (nullptr != messageListener) { - message_listener_ = messageListener; +void DefaultMQPushConsumerImpl::registerMessageListener(MessageListenerConcurrently* message_listener) { + if (nullptr != message_listener) { + message_listener_ = message_listener; } } -void DefaultMQPushConsumerImpl::registerMessageListener(MessageListenerConcurrently* messageListener) { - registerMessageListener(static_cast(messageListener)); -} - -void DefaultMQPushConsumerImpl::registerMessageListener(MessageListenerOrderly* messageListener) { - registerMessageListener(static_cast(messageListener)); -} - -MQMessageListener* DefaultMQPushConsumerImpl::getMessageListener() const { - return message_listener_; +void DefaultMQPushConsumerImpl::registerMessageListener(MessageListenerOrderly* message_listener) { + if (nullptr != message_listener) { + message_listener_ = message_listener; + } } void DefaultMQPushConsumerImpl::subscribe(const std::string& topic, const std::string& subExpression) { @@ -402,51 +380,22 @@ void DefaultMQPushConsumerImpl::subscribe(const std::string& topic, const std::s subscription_[topic] = subExpression; } -void DefaultMQPushConsumerImpl::suspend() { - pause_ = true; - LOG_INFO_NEW("suspend this consumer, {}", client_config_->group_name()); -} - -void DefaultMQPushConsumerImpl::resume() { - pause_ = false; - doRebalance(); - LOG_INFO_NEW("resume this consumer, {}", client_config_->group_name()); -} - -void DefaultMQPushConsumerImpl::doRebalance() { - if (!pause_) { - rebalance_impl_->doRebalance(isConsumeOrderly()); - } -} - -void DefaultMQPushConsumerImpl::persistConsumerOffset() { - if (isServiceStateOk()) { - std::vector mqs = rebalance_impl_->getAllocatedMQ(); - if (dynamic_cast(client_config_.get())->message_model() == BROADCASTING) { - offset_store_->persistAll(mqs); - } else { - for (const auto& mq : mqs) { - offset_store_->persist(mq); - } - } +std::vector DefaultMQPushConsumerImpl::subscriptions() const { + std::vector result; + auto& subTable = rebalance_impl_->getSubscriptionInner(); + for (const auto& it : subTable) { + result.push_back(*(it.second)); } + return result; } void DefaultMQPushConsumerImpl::updateTopicSubscribeInfo(const std::string& topic, std::vector& info) { rebalance_impl_->setTopicSubscribeInfo(topic, info); } -void DefaultMQPushConsumerImpl::updateConsumeOffset(const MQMessageQueue& mq, int64_t offset) { - if (offset >= 0) { - offset_store_->updateOffset(mq, offset, false); - } else { - LOG_ERROR_NEW("updateConsumeOffset of mq:{} error", mq.toString()); - } -} - -void DefaultMQPushConsumerImpl::correctTagsOffset(PullRequestPtr pullRequest) { - if (0L == pullRequest->process_queue()->getCacheMsgCount()) { - offset_store_->updateOffset(pullRequest->message_queue(), pullRequest->next_offset(), true); +void DefaultMQPushConsumerImpl::doRebalance() { + if (!pause_) { + rebalance_impl_->doRebalance(consume_orderly()); } } @@ -458,79 +407,70 @@ void DefaultMQPushConsumerImpl::executePullRequestImmediately(PullRequestPtr pul client_instance_->getPullMessageService()->executePullRequestImmediately(pullRequest); } -void DefaultMQPushConsumerImpl::executeTaskLater(const handler_type& task, long timeDelay) { - client_instance_->getPullMessageService()->executeTaskLater(task, timeDelay); -} - -void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pullRequest) { - if (nullptr == pullRequest) { +void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pull_request) { + if (nullptr == pull_request) { LOG_ERROR("PullRequest is NULL, return"); return; } - auto processQueue = pullRequest->process_queue(); - if (processQueue->dropped()) { - LOG_WARN_NEW("the pull request[{}] is dropped.", pullRequest->toString()); + auto process_queue = pull_request->process_queue(); + if (process_queue->dropped()) { + LOG_WARN_NEW("the pull request[{}] is dropped.", pull_request->toString()); return; } - processQueue->set_last_pull_timestamp(UtilAll::currentTimeMillis()); + process_queue->set_last_pull_timestamp(UtilAll::currentTimeMillis()); - int cachedMessageCount = processQueue->getCacheMsgCount(); - if (cachedMessageCount > - dynamic_cast(client_config_.get())->max_cache_msg_size_per_queue()) { + int cachedMessageCount = process_queue->getCacheMsgCount(); + if (cachedMessageCount > getDefaultMQPushConsumerConfig()->pull_threshold_for_queue()) { // too many message in cache, wait to process - executePullRequestLater(pullRequest, 1000); + executePullRequestLater(pull_request, 1000); return; } - if (isConsumeOrderly()) { - if (processQueue->locked()) { - if (!pullRequest->locked_first()) { - const auto offset = rebalance_impl_->computePullFromWhere(pullRequest->message_queue()); - bool brokerBusy = offset < pullRequest->next_offset(); + if (consume_orderly()) { + if (process_queue->locked()) { + if (!pull_request->locked_first()) { + const auto offset = rebalance_impl_->computePullFromWhere(pull_request->message_queue()); + bool brokerBusy = offset < pull_request->next_offset(); LOG_INFO_NEW( "the first time to pull message, so fix offset from broker. pullRequest: {} NewOffset: {} brokerBusy: {}", - pullRequest->toString(), offset, UtilAll::to_string(brokerBusy)); + pull_request->toString(), offset, UtilAll::to_string(brokerBusy)); if (brokerBusy) { LOG_INFO_NEW( "[NOTIFYME] the first time to pull message, but pull request offset larger than broker consume offset. " "pullRequest: {} NewOffset: {}", - pullRequest->toString(), offset); + pull_request->toString(), offset); } - pullRequest->set_locked_first(true); - pullRequest->set_next_offset(offset); + pull_request->set_locked_first(true); + pull_request->set_next_offset(offset); } } else { - executePullRequestLater( - pullRequest, - dynamic_cast(client_config_.get())->pull_time_delay_mills_when_exception()); - LOG_INFO_NEW("pull message later because not locked in broker, {}", pullRequest->toString()); + executePullRequestLater(pull_request, getDefaultMQPushConsumerConfig()->pull_time_delay_millis_when_exception()); + LOG_INFO_NEW("pull message later because not locked in broker, {}", pull_request->toString()); return; } } - const auto& messageQueue = pullRequest->message_queue(); - SubscriptionData* subscriptionData = rebalance_impl_->getSubscriptionData(messageQueue.topic()); - if (nullptr == subscriptionData) { - executePullRequestLater( - pullRequest, - dynamic_cast(client_config_.get())->pull_time_delay_mills_when_exception()); - LOG_WARN_NEW("find the consumer's subscription failed, {}", pullRequest->toString()); + const auto& message_queue = pull_request->message_queue(); + SubscriptionData* subscription_data = rebalance_impl_->getSubscriptionData(message_queue.topic()); + if (nullptr == subscription_data) { + executePullRequestLater(pull_request, getDefaultMQPushConsumerConfig()->pull_time_delay_millis_when_exception()); + LOG_WARN_NEW("find the consumer's subscription failed, {}", pull_request->toString()); return; } bool commitOffsetEnable = false; int64_t commitOffsetValue = 0; - if (CLUSTERING == dynamic_cast(client_config_.get())->message_model()) { - commitOffsetValue = offset_store_->readOffset(messageQueue, READ_FROM_MEMORY); + if (CLUSTERING == getDefaultMQPushConsumerConfig()->message_model()) { + commitOffsetValue = offset_store_->readOffset(message_queue, READ_FROM_MEMORY); if (commitOffsetValue > 0) { commitOffsetEnable = true; } } - const auto& subExpression = subscriptionData->sub_string(); + const auto& subExpression = subscription_data->sub_string(); int sysFlag = PullSysFlag::buildSysFlag(commitOffsetEnable, // commitOffset true, // suspend @@ -538,97 +478,135 @@ void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pullRequest) { false); // class filter try { - auto* callback = new AsyncPullCallback(shared_from_this(), pullRequest, subscriptionData); - pull_api_wrapper_->pullKernelImpl( - messageQueue, // 1 - subExpression, // 2 - subscriptionData->sub_version(), // 3 - pullRequest->next_offset(), // 4 - 32, // 5 - sysFlag, // 6 - commitOffsetValue, // 7 - 1000 * 15, // 8 - dynamic_cast(client_config_.get())->async_pull_timeout(), // 9 - CommunicationMode::ASYNC, // 10 - callback); // 11 + auto* callback = new AsyncPullCallback(shared_from_this(), pull_request, subscription_data); + pull_api_wrapper_->pullKernelImpl(message_queue, // mq + subExpression, // subExpression + subscription_data->sub_version(), // subVersion + pull_request->next_offset(), // offset + getDefaultMQPushConsumerConfig()->pull_batch_size(), // maxNums + sysFlag, // sysFlag + commitOffsetValue, // commitOffset + BROKER_SUSPEND_MAX_TIME_MILLIS, // brokerSuspendMaxTimeMillis + CONSUMER_TIMEOUT_MILLIS_WHEN_SUSPEND, // timeoutMillis + CommunicationMode::ASYNC, // communicationMode + callback); // pullCallback } catch (MQException& e) { LOG_ERROR_NEW("pullKernelImpl exception: {}", e.what()); - executePullRequestLater( - pullRequest, - dynamic_cast(client_config_.get())->pull_time_delay_mills_when_exception()); + executePullRequestLater(pull_request, getDefaultMQPushConsumerConfig()->pull_time_delay_millis_when_exception()); } } -void DefaultMQPushConsumerImpl::resetRetryTopic(const std::vector& msgs, - const std::string& consumerGroup) { - std::string groupTopic = UtilAll::getRetryTopic(consumerGroup); +void DefaultMQPushConsumerImpl::correctTagsOffset(PullRequestPtr pullRequest) { + if (0L == pullRequest->process_queue()->getCacheMsgCount()) { + offset_store_->updateOffset(pullRequest->message_queue(), pullRequest->next_offset(), true); + } +} + +void DefaultMQPushConsumerImpl::executeTaskLater(const handler_type& task, long timeDelay) { + client_instance_->getPullMessageService()->executeTaskLater(task, timeDelay); +} + +void DefaultMQPushConsumerImpl::resetRetryAndNamespace(const std::vector& msgs) { + std::string retry_topic = UtilAll::getRetryTopic(groupName()); for (auto& msg : msgs) { - std::string retryTopic = msg->getProperty(MQMessageConst::PROPERTY_RETRY_TOPIC); - if (!retryTopic.empty() && groupTopic == msg->topic()) { - msg->set_topic(retryTopic); + std::string group_topic = msg->getProperty(MQMessageConst::PROPERTY_RETRY_TOPIC); + if (!group_topic.empty() && retry_topic == msg->topic()) { + msg->set_topic(group_topic); } } -} -int DefaultMQPushConsumerImpl::getMaxReconsumeTimes() { - // default reconsume times: 16 - if (dynamic_cast(client_config_.get())->max_reconsume_times() == -1) { - return 16; - } else { - return dynamic_cast(client_config_.get())->max_reconsume_times(); + const auto& name_space = client_config_->name_space(); + if (!name_space.empty()) { + for (auto& msg : msgs) { + msg->set_topic(NamespaceUtil::withoutNamespace(msg->topic(), name_space)); + } } } -const std::string& DefaultMQPushConsumerImpl::groupName() const { - return client_config_->group_name(); +bool DefaultMQPushConsumerImpl::sendMessageBack(MessageExtPtr msg, int delay_level) { + return sendMessageBack(msg, delay_level, null); } -MessageModel DefaultMQPushConsumerImpl::messageModel() const { - return dynamic_cast(client_config_.get())->message_model(); -}; +bool DefaultMQPushConsumerImpl::sendMessageBack(MessageExtPtr msg, int delay_level, const std::string& brokerName) { + try { + msg->set_topic(NamespaceUtil::wrapNamespace(client_config_->name_space(), msg->topic())); -ConsumeType DefaultMQPushConsumerImpl::consumeType() const { - return CONSUME_PASSIVELY; + std::string brokerAddr = brokerName.empty() ? socketAddress2String(msg->store_host()) + : client_instance_->findBrokerAddressInPublish(brokerName); + + client_instance_->getMQClientAPIImpl()->consumerSendMessageBack( + brokerAddr, msg, getDefaultMQPushConsumerConfig()->group_name(), delay_level, 5000, + getDefaultMQPushConsumerConfig()->max_reconsume_times()); + return true; + } catch (const std::exception& e) { + LOG_ERROR_NEW("sendMessageBack exception, group: {}, msg: {}. {}", getDefaultMQPushConsumerConfig()->group_name(), + msg->toString(), e.what()); + } + return false; } -ConsumeFromWhere DefaultMQPushConsumerImpl::consumeFromWhere() const { - return dynamic_cast(client_config_.get())->consume_from_where(); +void DefaultMQPushConsumerImpl::persistConsumerOffset() { + if (isServiceStateOk()) { + std::vector mqs = rebalance_impl_->getAllocatedMQ(); + if (getDefaultMQPushConsumerConfig()->message_model() == BROADCASTING) { + offset_store_->persistAll(mqs); + } else { + for (const auto& mq : mqs) { + offset_store_->persist(mq); + } + } + } } -std::vector DefaultMQPushConsumerImpl::subscriptions() const { - std::vector result; - auto& subTable = rebalance_impl_->getSubscriptionInner(); - for (const auto& it : subTable) { - result.push_back(*(it.second)); +void DefaultMQPushConsumerImpl::updateConsumeOffset(const MQMessageQueue& mq, int64_t offset) { + if (offset >= 0) { + offset_store_->updateOffset(mq, offset, false); + } else { + LOG_ERROR_NEW("updateConsumeOffset of mq:{} error", mq.toString()); } - return result; } ConsumerRunningInfo* DefaultMQPushConsumerImpl::consumerRunningInfo() { auto* info = new ConsumerRunningInfo(); info->setProperty(ConsumerRunningInfo::PROP_CONSUME_ORDERLY, UtilAll::to_string(consume_orderly_)); - info->setProperty( - ConsumerRunningInfo::PROP_THREADPOOL_CORE_SIZE, - UtilAll::to_string(dynamic_cast(client_config_.get())->consume_thread_nums())); + info->setProperty(ConsumerRunningInfo::PROP_THREADPOOL_CORE_SIZE, + UtilAll::to_string(getDefaultMQPushConsumerConfig()->consume_thread_nums())); info->setProperty(ConsumerRunningInfo::PROP_CONSUMER_START_TIMESTAMP, UtilAll::to_string(start_time_)); - auto subSet = subscriptions(); - info->setSubscriptionSet(subSet); + auto sub_set = subscriptions(); + info->setSubscriptionSet(sub_set); auto processQueueTable = rebalance_impl_->getProcessQueueTable(); - for (const auto& it : processQueueTable) { const auto& mq = it.first; const auto& pq = it.second; - ProcessQueueInfo pqinfo; - pqinfo.setCommitOffset(offset_store_->readOffset(mq, MEMORY_FIRST_THEN_STORE)); - pq->fillProcessQueueInfo(pqinfo); - info->setMqTable(mq, pqinfo); + ProcessQueueInfo pq_info; + pq_info.setCommitOffset(offset_store_->readOffset(mq, MEMORY_FIRST_THEN_STORE)); + pq->fillProcessQueueInfo(pq_info); + info->setMqTable(mq, pq_info); } + // TODO: ConsumeStatus + return info; } +const std::string& DefaultMQPushConsumerImpl::groupName() const { + return client_config_->group_name(); +} + +MessageModel DefaultMQPushConsumerImpl::messageModel() const { + return getDefaultMQPushConsumerConfig()->message_model(); +}; + +ConsumeType DefaultMQPushConsumerImpl::consumeType() const { + return CONSUME_PASSIVELY; +} + +ConsumeFromWhere DefaultMQPushConsumerImpl::consumeFromWhere() const { + return getDefaultMQPushConsumerConfig()->consume_from_where(); +} + } // namespace rocketmq diff --git a/src/consumer/DefaultMQPushConsumerImpl.h b/src/consumer/DefaultMQPushConsumerImpl.h index 1e3fdc7b5..ecac5868f 100755 --- a/src/consumer/DefaultMQPushConsumerImpl.h +++ b/src/consumer/DefaultMQPushConsumerImpl.h @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef ROCKETMQ_CONXUMER_DEFAULTMQPUSHCONSUMERIMPL_H_ -#define ROCKETMQ_CONXUMER_DEFAULTMQPUSHCONSUMERIMPL_H_ +#ifndef ROCKETMQ_CONSUMER_DEFAULTMQPUSHCONSUMERIMPL_H_ +#define ROCKETMQ_CONSUMER_DEFAULTMQPUSHCONSUMERIMPL_H_ #include #include @@ -43,6 +43,9 @@ class DefaultMQPushConsumerImpl : public std::enable_shared_from_this& mqs) override; + void suspend() override; + void resume() override; + + MQMessageListener* getMessageListener() const override; - public: // MQPushConsumer - void registerMessageListener(MQMessageListener* messageListener) override; void registerMessageListener(MessageListenerConcurrently* messageListener) override; void registerMessageListener(MessageListenerOrderly* messageListener) override; - MQMessageListener* getMessageListener() const override; - void subscribe(const std::string& topic, const std::string& subExpression) override; - void suspend() override; - void resume() override; + bool sendMessageBack(MessageExtPtr msg, int delayLevel) override; + bool sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) override; public: // MQConsumerInner const std::string& groupName() const override; MessageModel messageModel() const override; ConsumeType consumeType() const override; ConsumeFromWhere consumeFromWhere() const override; + std::vector subscriptions() const override; + // service discovery + void updateTopicSubscribeInfo(const std::string& topic, std::vector& info) override; + + // load balancing void doRebalance() override; + + // offset persistence void persistConsumerOffset() override; - void updateTopicSubscribeInfo(const std::string& topic, std::vector& info) override; ConsumerRunningInfo* consumerRunningInfo() override; public: - void updateConsumeOffset(const MQMessageQueue& mq, int64_t offset); - void correctTagsOffset(PullRequestPtr pullRequest); - void executePullRequestLater(PullRequestPtr pullRequest, long timeDelay); void executePullRequestImmediately(PullRequestPtr pullRequest); - void executeTaskLater(const handler_type& task, long timeDelay); void pullMessage(PullRequestPtr pullrequest); - void resetRetryTopic(const std::vector& msgs, const std::string& consumerGroup); + void resetRetryAndNamespace(const std::vector& msgs); + + void updateConsumeOffset(const MQMessageQueue& mq, int64_t offset); private: void checkConfig(); void copySubscription(); void updateTopicSubscribeInfoWhenSubscriptionChanged(); - public: - int getMaxReconsumeTimes(); - - inline bool isPause() const { return pause_; }; - inline void setPause(bool pause) { pause_ = pause; } - - inline bool isConsumeOrderly() { return consume_orderly_; } - - inline RebalanceImpl* getRebalanceImpl() const { return rebalance_impl_.get(); } + void correctTagsOffset(PullRequestPtr pullRequest); - inline PullAPIWrapper* getPullAPIWrapper() const { return pull_api_wrapper_.get(); } + void executeTaskLater(const handler_type& task, long timeDelay); - inline OffsetStore* getOffsetStore() const { return offset_store_.get(); } + public: + inline bool pause() const { return pause_; }; + inline void set_pause(bool pause) { pause_ = pause; } - inline ConsumeMsgService* getConsumerMsgService() const { return consume_service_.get(); } + inline bool consume_orderly() { return consume_orderly_; } inline MessageListenerType getMessageListenerType() const { if (nullptr != message_listener_) { @@ -137,7 +134,11 @@ class DefaultMQPushConsumerImpl : public std::enable_shared_from_this(client_config_.get()); } @@ -148,13 +149,15 @@ class DefaultMQPushConsumerImpl : public std::enable_shared_from_this subscription_; + + MQMessageListener* message_listener_; + std::unique_ptr consume_service_; + std::unique_ptr rebalance_impl_; std::unique_ptr pull_api_wrapper_; std::unique_ptr offset_store_; - std::unique_ptr consume_service_; - MQMessageListener* message_listener_; }; } // namespace rocketmq -#endif // ROCKETMQ_CONXUMER_DEFAULTMQPUSHCONSUMERIMPL_H_ +#endif // ROCKETMQ_CONSUMER_DEFAULTMQPUSHCONSUMERIMPL_H_ diff --git a/src/consumer/MQConsumerInner.h b/src/consumer/MQConsumerInner.h index b851316a9..d38e83979 100644 --- a/src/consumer/MQConsumerInner.h +++ b/src/consumer/MQConsumerInner.h @@ -36,11 +36,17 @@ class MQConsumerInner { virtual MessageModel messageModel() const = 0; virtual ConsumeType consumeType() const = 0; virtual ConsumeFromWhere consumeFromWhere() const = 0; + virtual std::vector subscriptions() const = 0; + // service discovery + virtual void updateTopicSubscribeInfo(const std::string& topic, std::vector& info) = 0; + + // load balancing virtual void doRebalance() = 0; + + // offset persistence virtual void persistConsumerOffset() = 0; - virtual void updateTopicSubscribeInfo(const std::string& topic, std::vector& info) = 0; virtual ConsumerRunningInfo* consumerRunningInfo() = 0; }; diff --git a/src/consumer/RebalanceImpl.cpp b/src/consumer/RebalanceImpl.cpp index a3988cd48..1454584a4 100644 --- a/src/consumer/RebalanceImpl.cpp +++ b/src/consumer/RebalanceImpl.cpp @@ -467,7 +467,6 @@ void RebalanceImpl::destroy() { for (const auto& it : process_queue_table_) { it.second->set_dropped(true); } - process_queue_table_.clear(); } diff --git a/src/extern/CPushConsumer.cpp b/src/extern/CPushConsumer.cpp index feb769391..0ba977ef1 100644 --- a/src/extern/CPushConsumer.cpp +++ b/src/extern/CPushConsumer.cpp @@ -215,7 +215,7 @@ int SetPushConsumerMaxCacheMessageSize(CPushConsumer* consumer, int maxCacheSize if (consumer == NULL || maxCacheSize <= 0) { return NULL_POINTER; } - reinterpret_cast(consumer)->set_max_cache_msg_size_per_queue(maxCacheSize); + reinterpret_cast(consumer)->set_pull_threshold_for_queue(maxCacheSize); return OK; } From 67c55f8374f11004b94eceaf7b7df6e1314a4d36 Mon Sep 17 00:00:00 2001 From: James Yin Date: Mon, 21 Sep 2020 15:43:31 +0800 Subject: [PATCH 23/62] refactor: ExpressionType --- include/ExpressionType.h | 37 +++++++++++++++++++++ src/consumer/DefaultMQPushConsumerImpl.cpp | 1 + src/consumer/ExpressionType.cpp | 28 ++++++++++++++++ src/consumer/PullAPIWrapper.cpp | 21 ++++++------ src/consumer/PullAPIWrapper.h | 21 ++++++------ src/protocol/heartbeat/SubscriptionData.hpp | 16 ++++++--- 6 files changed, 100 insertions(+), 24 deletions(-) create mode 100644 include/ExpressionType.h create mode 100644 src/consumer/ExpressionType.cpp diff --git a/include/ExpressionType.h b/include/ExpressionType.h new file mode 100644 index 000000000..cf243b3c3 --- /dev/null +++ b/include/ExpressionType.h @@ -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. + */ +#ifndef ROCKETMQ_EXPRESSIONTYPE_H_ +#define ROCKETMQ_EXPRESSIONTYPE_H_ + +#include // std::string + +#include "RocketMQClient.h" + +namespace rocketmq { + +class ROCKETMQCLIENT_API ExpressionType { + public: + static const std::string SQL92; + static const std::string TAG; + + public: + static bool isTagType(const std::string& type); +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_EXPRESSIONTYPE_H_ diff --git a/src/consumer/DefaultMQPushConsumerImpl.cpp b/src/consumer/DefaultMQPushConsumerImpl.cpp index 841d4ee16..2b3a7c411 100644 --- a/src/consumer/DefaultMQPushConsumerImpl.cpp +++ b/src/consumer/DefaultMQPushConsumerImpl.cpp @@ -481,6 +481,7 @@ void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pull_request) { auto* callback = new AsyncPullCallback(shared_from_this(), pull_request, subscription_data); pull_api_wrapper_->pullKernelImpl(message_queue, // mq subExpression, // subExpression + subscription_data->expression_type(), // expressionType subscription_data->sub_version(), // subVersion pull_request->next_offset(), // offset getDefaultMQPushConsumerConfig()->pull_batch_size(), // maxNums diff --git a/src/consumer/ExpressionType.cpp b/src/consumer/ExpressionType.cpp new file mode 100644 index 000000000..979412fc7 --- /dev/null +++ b/src/consumer/ExpressionType.cpp @@ -0,0 +1,28 @@ +/* + * 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 "ExpressionType.h" + +namespace rocketmq { + +const std::string ExpressionType::SQL92 = "SQL92"; +const std::string ExpressionType::TAG = "TAG"; + +bool ExpressionType::isTagType(const std::string& type) { + return type.empty() || TAG == type; +} + +} // namespace rocketmq diff --git a/src/consumer/PullAPIWrapper.cpp b/src/consumer/PullAPIWrapper.cpp index e67111828..88e96f62c 100644 --- a/src/consumer/PullAPIWrapper.cpp +++ b/src/consumer/PullAPIWrapper.cpp @@ -94,16 +94,17 @@ PullResult PullAPIWrapper::processPullResult(const MQMessageQueue& mq, pullResultExt.max_offset(), std::move(msgListFilterAgain)); } -PullResult* PullAPIWrapper::pullKernelImpl(const MQMessageQueue& mq, // 1 - const std::string& subExpression, // 2 - int64_t subVersion, // 3 - int64_t offset, // 4 - int maxNums, // 5 - int sysFlag, // 6 - int64_t commitOffset, // 7 - int brokerSuspendMaxTimeMillis, // 8 - int timeoutMillis, // 9 - CommunicationMode communicationMode, // 10 +PullResult* PullAPIWrapper::pullKernelImpl(const MQMessageQueue& mq, + const std::string& subExpression, + const std::string& expressionType, + int64_t subVersion, + int64_t offset, + int maxNums, + int sysFlag, + int64_t commitOffset, + int brokerSuspendMaxTimeMillis, + int timeoutMillis, + CommunicationMode communicationMode, PullCallback* pullCallback) { std::unique_ptr findBrokerResult( client_instance_->findBrokerAddressInSubscribe(mq.broker_name(), recalculatePullFromWhichNode(mq), false)); diff --git a/src/consumer/PullAPIWrapper.h b/src/consumer/PullAPIWrapper.h index 7edc227e7..73d98d958 100644 --- a/src/consumer/PullAPIWrapper.h +++ b/src/consumer/PullAPIWrapper.h @@ -34,16 +34,17 @@ class PullAPIWrapper { PullResult processPullResult(const MQMessageQueue& mq, PullResult& pullResult, SubscriptionData* subscriptionData); - PullResult* pullKernelImpl(const MQMessageQueue& mq, // 1 - const std::string& subExpression, // 2 - int64_t subVersion, // 3 - int64_t offset, // 4 - int maxNums, // 5 - int sysFlag, // 6 - int64_t commitOffset, // 7 - int brokerSuspendMaxTimeMillis, // 8 - int timeoutMillis, // 9 - CommunicationMode communicationMode, // 10 + PullResult* pullKernelImpl(const MQMessageQueue& mq, + const std::string& subExpression, + const std::string& expressionType, + int64_t subVersion, + int64_t offset, + int maxNums, + int sysFlag, + int64_t commitOffset, + int brokerSuspendMaxTimeMillis, + int timeoutMillis, + CommunicationMode communicationMode, PullCallback* pullCallback); private: diff --git a/src/protocol/heartbeat/SubscriptionData.hpp b/src/protocol/heartbeat/SubscriptionData.hpp index 82f8334c8..e7ad68403 100644 --- a/src/protocol/heartbeat/SubscriptionData.hpp +++ b/src/protocol/heartbeat/SubscriptionData.hpp @@ -24,15 +24,19 @@ #include +#include "ExpressionType.h" #include "UtilAll.h" namespace rocketmq { class SubscriptionData { public: - SubscriptionData() : sub_version_(UtilAll::currentTimeMillis()) {} + SubscriptionData() : sub_version_(UtilAll::currentTimeMillis()), expression_type_(ExpressionType::TAG) {} SubscriptionData(const std::string& topic, const std::string& subString) - : topic_(topic), sub_string_(subString), sub_version_(UtilAll::currentTimeMillis()) {} + : topic_(topic), + sub_string_(subString), + sub_version_(UtilAll::currentTimeMillis()), + expression_type_(ExpressionType::TAG) {} SubscriptionData(const SubscriptionData& other) { sub_string_ = other.sub_string_; @@ -40,14 +44,15 @@ class SubscriptionData { tag_set_ = other.tag_set_; topic_ = other.topic_; code_set_ = other.code_set_; + expression_type_ = other.expression_type_; } virtual ~SubscriptionData() = default; bool operator==(const SubscriptionData& other) const { // FIXME: tags - return topic_ == other.topic_ && sub_string_ == other.sub_string_ && sub_version_ == other.sub_version_ && - tag_set_.size() == other.tag_set_.size(); + return expression_type_ == expression_type_ && topic_ == other.topic_ && sub_string_ == other.sub_string_ && + sub_version_ == other.sub_version_ && tag_set_.size() == other.tag_set_.size(); } bool operator!=(const SubscriptionData& other) const { return !operator==(other); } @@ -93,12 +98,15 @@ class SubscriptionData { inline std::vector& code_set() { return code_set_; } + inline const std::string& expression_type() { return expression_type_; } + private: std::string topic_; std::string sub_string_; int64_t sub_version_; std::vector tag_set_; std::vector code_set_; + std::string expression_type_; }; } // namespace rocketmq From 99b18ab1ef4b70808b56befc0efcc914a0b21c16 Mon Sep 17 00:00:00 2001 From: James Yin Date: Mon, 21 Sep 2020 15:46:05 +0800 Subject: [PATCH 24/62] refactor: MessageSelector --- include/MessageSelector.h | 58 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 include/MessageSelector.h diff --git a/include/MessageSelector.h b/include/MessageSelector.h new file mode 100644 index 000000000..4e33acd40 --- /dev/null +++ b/include/MessageSelector.h @@ -0,0 +1,58 @@ +/* + * 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_MESSAGESELECTOR_H_ +#define ROCKETMQ_MESSAGESELECTOR_H_ + +#include // std::move + +#include "ExpressionType.h" + +namespace rocketmq { + +class ROCKETMQCLIENT_API MessageSelector { + private: + MessageSelector(const std::string& type, const std::string& expression) : type_(type), expression_(expression) {} + + public: + virtual ~MessageSelector() = default; + + MessageSelector(const MessageSelector& other) : type_(other.type_), expression_(other.expression_) {} + MessageSelector(MessageSelector&& other) : type_(std::move(other.type_)), expression_(std::move(other.expression_)) {} + + MessageSelector& operator=(const MessageSelector& other) { + if (this != &other) { + type_ = other.type_; + expression_ = other.expression_; + } + return *this; + } + + static inline MessageSelector bySql(const std::string& sql) { return MessageSelector(ExpressionType::SQL92, sql); } + static inline MessageSelector byTag(const std::string& tag) { return MessageSelector(ExpressionType::TAG, tag); } + + public: + const std::string& type() const { return type_; } + const std::string& expression() const { return expression_; } + + private: + std::string type_; + std::string expression_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_MESSAGESELECTOR_H_ From 3a805ec9e6f987c426821a94620f0d7b22d07f74 Mon Sep 17 00:00:00 2001 From: James Yin Date: Wed, 23 Sep 2020 17:40:47 +0800 Subject: [PATCH 25/62] refactor: RemoteBrokerOffsetStore::persistAll --- include/OffsetStore.h | 2 +- src/consumer/DefaultMQPushConsumerImpl.cpp | 8 +-- src/consumer/LocalFileOffsetStore.cpp | 2 +- src/consumer/LocalFileOffsetStore.h | 2 +- src/consumer/RemoteBrokerOffsetStore.cpp | 60 +++++++++++++++++++--- src/consumer/RemoteBrokerOffsetStore.h | 2 +- 6 files changed, 57 insertions(+), 19 deletions(-) diff --git a/include/OffsetStore.h b/include/OffsetStore.h index 05ae0b4fa..4991010d5 100644 --- a/include/OffsetStore.h +++ b/include/OffsetStore.h @@ -40,7 +40,7 @@ class ROCKETMQCLIENT_API OffsetStore { virtual void updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) = 0; virtual int64_t readOffset(const MQMessageQueue& mq, ReadOffsetType type) = 0; virtual void persist(const MQMessageQueue& mq) = 0; - virtual void persistAll(const std::vector& mq) = 0; + virtual void persistAll(std::vector& mqs) = 0; virtual void removeOffset(const MQMessageQueue& mq) = 0; }; diff --git a/src/consumer/DefaultMQPushConsumerImpl.cpp b/src/consumer/DefaultMQPushConsumerImpl.cpp index 2b3a7c411..768b7df14 100644 --- a/src/consumer/DefaultMQPushConsumerImpl.cpp +++ b/src/consumer/DefaultMQPushConsumerImpl.cpp @@ -549,13 +549,7 @@ bool DefaultMQPushConsumerImpl::sendMessageBack(MessageExtPtr msg, int delay_lev void DefaultMQPushConsumerImpl::persistConsumerOffset() { if (isServiceStateOk()) { std::vector mqs = rebalance_impl_->getAllocatedMQ(); - if (getDefaultMQPushConsumerConfig()->message_model() == BROADCASTING) { - offset_store_->persistAll(mqs); - } else { - for (const auto& mq : mqs) { - offset_store_->persist(mq); - } - } + offset_store_->persistAll(mqs); } } diff --git a/src/consumer/LocalFileOffsetStore.cpp b/src/consumer/LocalFileOffsetStore.cpp index ac66ecef8..1046c41f9 100644 --- a/src/consumer/LocalFileOffsetStore.cpp +++ b/src/consumer/LocalFileOffsetStore.cpp @@ -105,7 +105,7 @@ int64_t LocalFileOffsetStore::readOffset(const MQMessageQueue& mq, ReadOffsetTyp void LocalFileOffsetStore::persist(const MQMessageQueue& mq) {} -void LocalFileOffsetStore::persistAll(const std::vector& mqs) { +void LocalFileOffsetStore::persistAll(std::vector& mqs) { if (mqs.empty()) { return; } diff --git a/src/consumer/LocalFileOffsetStore.h b/src/consumer/LocalFileOffsetStore.h index c517fb4ca..6453769d9 100644 --- a/src/consumer/LocalFileOffsetStore.h +++ b/src/consumer/LocalFileOffsetStore.h @@ -34,7 +34,7 @@ class LocalFileOffsetStore : public OffsetStore { void updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) override; int64_t readOffset(const MQMessageQueue& mq, ReadOffsetType type) override; void persist(const MQMessageQueue& mq) override; - void persistAll(const std::vector& mq) override; + void persistAll(std::vector& mqs) override; void removeOffset(const MQMessageQueue& mq) override; private: diff --git a/src/consumer/RemoteBrokerOffsetStore.cpp b/src/consumer/RemoteBrokerOffsetStore.cpp index 537cf7f71..ad2e210b3 100644 --- a/src/consumer/RemoteBrokerOffsetStore.cpp +++ b/src/consumer/RemoteBrokerOffsetStore.cpp @@ -76,23 +76,67 @@ int64_t RemoteBrokerOffsetStore::readOffset(const MQMessageQueue& mq, ReadOffset } void RemoteBrokerOffsetStore::persist(const MQMessageQueue& mq) { - std::map offsetTable; + int64_t offset = -1; { std::lock_guard lock(lock_); - offsetTable = offset_table_; + const auto& it = offset_table_.find(mq); + if (it != offset_table_.end()) { + offset = it->second; + } } - const auto& it = offsetTable.find(mq); - if (it != offsetTable.end()) { + if (offset >= 0) { try { - updateConsumeOffsetToBroker(mq, it->second); + updateConsumeOffsetToBroker(mq, offset); + LOG_INFO_NEW("[persist] Group: {} ClientId: {} updateConsumeOffsetToBroker {} {}", group_name_, + client_instance_->getClientId(), mq.toString(), offset); } catch (MQException& e) { LOG_ERROR("updateConsumeOffsetToBroker error"); } } } -void RemoteBrokerOffsetStore::persistAll(const std::vector& mq) {} +void RemoteBrokerOffsetStore::persistAll(std::vector& mqs) { + if (mqs.empty()) { + return; + } + + std::sort(mqs.begin(), mqs.end()); + + std::vector unused_mqs; + + std::map offset_table; + { + std::lock_guard lock(lock_); + offset_table = offset_table_; + } + + for (const auto& it : offset_table) { + const auto& mq = it.first; + auto offset = it.second; + if (offset >= 0) { + if (std::binary_search(mqs.begin(), mqs.end(), mq)) { + try { + updateConsumeOffsetToBroker(mq, offset); + LOG_INFO_NEW("[persistAll] Group: {} ClientId: {} updateConsumeOffsetToBroker {} {}", group_name_, + client_instance_->getClientId(), mq.toString(), offset); + } catch (std::exception& e) { + LOG_ERROR_NEW("updateConsumeOffsetToBroker exception, {} {}", mq.toString(), e.what()); + } + } else { + unused_mqs.push_back(mq); + } + } + } + + if (!unused_mqs.empty()) { + std::lock_guard lock(lock_); + for (const auto& mq : unused_mqs) { + offset_table_.erase(mq); + LOG_INFO_NEW("remove unused mq, {}, {}", mq.toString(), group_name_); + } + } +} void RemoteBrokerOffsetStore::removeOffset(const MQMessageQueue& mq) { std::lock_guard lock(lock_); @@ -118,14 +162,14 @@ void RemoteBrokerOffsetStore::updateConsumeOffsetToBroker(const MQMessageQueue& requestHeader->commitOffset = offset; try { - LOG_INFO("oneway updateConsumeOffsetToBroker of mq:%s, its offset is:%lld", mq.toString().c_str(), offset); return client_instance_->getMQClientAPIImpl()->updateConsumerOffsetOneway(findBrokerResult->broker_addr(), requestHeader, 1000 * 5); } catch (MQException& e) { LOG_ERROR(e.what()); } + } else { + LOG_WARN("The broker not exist"); } - LOG_WARN("The broker not exist"); } int64_t RemoteBrokerOffsetStore::fetchConsumeOffsetFromBroker(const MQMessageQueue& mq) { diff --git a/src/consumer/RemoteBrokerOffsetStore.h b/src/consumer/RemoteBrokerOffsetStore.h index ba6598eeb..e45de954e 100644 --- a/src/consumer/RemoteBrokerOffsetStore.h +++ b/src/consumer/RemoteBrokerOffsetStore.h @@ -34,7 +34,7 @@ class RemoteBrokerOffsetStore : public OffsetStore { void updateOffset(const MQMessageQueue& mq, int64_t offset, bool increaseOnly) override; int64_t readOffset(const MQMessageQueue& mq, ReadOffsetType type) override; void persist(const MQMessageQueue& mq) override; - void persistAll(const std::vector& mq) override; + void persistAll(std::vector& mqs) override; void removeOffset(const MQMessageQueue& mq) override; private: From c1c2eb89b647bb35c5ccd2cea74a2ce2296a8dee Mon Sep 17 00:00:00 2001 From: James Yin Date: Wed, 23 Sep 2020 17:46:48 +0800 Subject: [PATCH 26/62] refactor: PullAPIWrapper::processPullResult --- include/PullCallback.h | 2 +- include/c/CPullResult.h | 1 - src/common/PullCallbackWrap.cpp | 6 +-- src/consumer/DefaultMQPushConsumerImpl.cpp | 34 +++++++------- src/consumer/PullAPIWrapper.cpp | 52 ++++++++++++---------- src/consumer/PullAPIWrapper.h | 4 +- src/consumer/PullResult.cpp | 7 ++- src/consumer/PullResult.h | 15 ++++++- 8 files changed, 68 insertions(+), 53 deletions(-) diff --git a/include/PullCallback.h b/include/PullCallback.h index 2e733e18e..7eb63ef00 100755 --- a/include/PullCallback.h +++ b/include/PullCallback.h @@ -31,7 +31,7 @@ class ROCKETMQCLIENT_API PullCallback { public: virtual ~PullCallback() = default; - virtual void onSuccess(PullResult& pullResult) = 0; + virtual void onSuccess(std::unique_ptr pull_result) = 0; virtual void onException(MQException& e) noexcept = 0; virtual PullCallbackType getPullCallbackType() const { return PULL_CALLBACK_TYPE_SIMPLE; } diff --git a/include/c/CPullResult.h b/include/c/CPullResult.h index 6fc45e9ca..816887f69 100644 --- a/include/c/CPullResult.h +++ b/include/c/CPullResult.h @@ -29,7 +29,6 @@ typedef enum E_CPullStatus { E_NO_NEW_MSG, E_NO_MATCHED_MSG, E_OFFSET_ILLEGAL, - E_BROKER_TIMEOUT // indicate pull request timeout or received NULL response } CPullStatus; typedef struct _CPullResult_ { diff --git a/src/common/PullCallbackWrap.cpp b/src/common/PullCallbackWrap.cpp index 65cf63c79..b23970b0f 100755 --- a/src/common/PullCallbackWrap.cpp +++ b/src/common/PullCallbackWrap.cpp @@ -31,9 +31,9 @@ void PullCallbackWrap::operationComplete(ResponseFuture* responseFuture) noexcep if (response != nullptr) { try { - std::unique_ptr pullResult(client_api_impl_->processPullResponse(response.get())); - assert(pullResult != nullptr); - pull_callback_->onSuccess(*pullResult); + std::unique_ptr pull_result(client_api_impl_->processPullResponse(response.get())); + assert(pull_result != nullptr); + pull_callback_->onSuccess(std::move(pull_result)); } catch (MQException& e) { pull_callback_->onException(e); } diff --git a/src/consumer/DefaultMQPushConsumerImpl.cpp b/src/consumer/DefaultMQPushConsumerImpl.cpp index 768b7df14..79bcdf5cc 100644 --- a/src/consumer/DefaultMQPushConsumerImpl.cpp +++ b/src/consumer/DefaultMQPushConsumerImpl.cpp @@ -55,53 +55,53 @@ class DefaultMQPushConsumerImpl::AsyncPullCallback : public AutoDeletePullCallba ~AsyncPullCallback() = default; - void onSuccess(PullResult& pullResult) override { + void onSuccess(std::unique_ptr pull_result) override { auto consumer = default_mq_push_consumer_.lock(); if (nullptr == consumer) { LOG_WARN_NEW("AsyncPullCallback::onSuccess: DefaultMQPushConsumerImpl is released."); return; } - PullResult result = - consumer->pull_api_wrapper_->processPullResult(pull_request_->message_queue(), pullResult, subscription_data_); - switch (result.pull_status()) { + pull_result.reset(consumer->pull_api_wrapper_->processPullResult(pull_request_->message_queue(), + std::move(pull_result), subscription_data_)); + switch (pull_result->pull_status()) { case FOUND: { int64_t prev_request_offset = pull_request_->next_offset(); - pull_request_->set_next_offset(result.next_begin_offset()); + pull_request_->set_next_offset(pull_result->next_begin_offset()); int64_t first_msg_offset = (std::numeric_limits::max)(); - if (!result.msg_found_list().empty()) { - first_msg_offset = result.msg_found_list()[0]->queue_offset(); + if (!pull_result->msg_found_list().empty()) { + first_msg_offset = pull_result->msg_found_list()[0]->queue_offset(); - pull_request_->process_queue()->putMessage(result.msg_found_list()); - consumer->consume_service_->submitConsumeRequest(result.msg_found_list(), pull_request_->process_queue(), - pull_request_->message_queue(), true); + pull_request_->process_queue()->putMessage(pull_result->msg_found_list()); + consumer->consume_service_->submitConsumeRequest( + pull_result->msg_found_list(), pull_request_->process_queue(), pull_request_->message_queue(), true); } consumer->executePullRequestImmediately(pull_request_); - if (result.next_begin_offset() < prev_request_offset || first_msg_offset < prev_request_offset) { + if (pull_result->next_begin_offset() < prev_request_offset || first_msg_offset < prev_request_offset) { LOG_WARN_NEW( "[BUG] pull message result maybe data wrong, nextBeginOffset:{} firstMsgOffset:{} prevRequestOffset:{}", - result.next_begin_offset(), first_msg_offset, prev_request_offset); + pull_result->next_begin_offset(), first_msg_offset, prev_request_offset); } } break; case NO_NEW_MSG: case NO_MATCHED_MSG: - pull_request_->set_next_offset(result.next_begin_offset()); + pull_request_->set_next_offset(pull_result->next_begin_offset()); consumer->correctTagsOffset(pull_request_); consumer->executePullRequestImmediately(pull_request_); break; case NO_LATEST_MSG: - pull_request_->set_next_offset(result.next_begin_offset()); + pull_request_->set_next_offset(pull_result->next_begin_offset()); consumer->correctTagsOffset(pull_request_); consumer->executePullRequestLater( - pull_request_, consumer->getDefaultMQPushConsumerConfig()->pull_time_delay_mills_when_exception()); + pull_request_, consumer->getDefaultMQPushConsumerConfig()->pull_time_delay_millis_when_exception()); break; case OFFSET_ILLEGAL: { - LOG_WARN_NEW("the pull request offset illegal, {} {}", pull_request_->toString(), result.toString()); + LOG_WARN_NEW("the pull request offset illegal, {} {}", pull_request_->toString(), pull_result->toString()); - pull_request_->set_next_offset(result.next_begin_offset()); + pull_request_->set_next_offset(pull_result->next_begin_offset()); pull_request_->process_queue()->set_dropped(true); // update and persist offset, then removeProcessQueue diff --git a/src/consumer/PullAPIWrapper.cpp b/src/consumer/PullAPIWrapper.cpp index 88e96f62c..e25f423f1 100644 --- a/src/consumer/PullAPIWrapper.cpp +++ b/src/consumer/PullAPIWrapper.cpp @@ -50,48 +50,52 @@ int PullAPIWrapper::recalculatePullFromWhichNode(const MQMessageQueue& mq) { return MASTER_ID; } -PullResult PullAPIWrapper::processPullResult(const MQMessageQueue& mq, - PullResult& pullResult, - SubscriptionData* subscriptionData) { - assert(std::type_index(typeid(pullResult)) == std::type_index(typeid(PullResultExt))); - auto& pullResultExt = dynamic_cast(pullResult); +PullResult* PullAPIWrapper::processPullResult(const MQMessageQueue& mq, + std::unique_ptr pull_result, + SubscriptionData* subscription_data) { + auto* pull_result_ext = dynamic_cast(pull_result.get()); + if (pull_result_ext == nullptr) { + return pull_result.release(); + } // update node - updatePullFromWhichNode(mq, pullResultExt.suggert_which_boker_id()); + updatePullFromWhichNode(mq, pull_result_ext->suggert_which_boker_id()); - std::vector msgListFilterAgain; - if (FOUND == pullResultExt.pull_status()) { + std::vector msg_list_filter_again; + if (FOUND == pull_result_ext->pull_status()) { // decode all msg list - std::unique_ptr byteBuffer(ByteBuffer::wrap(pullResultExt.message_binary())); + std::unique_ptr byteBuffer(ByteBuffer::wrap(pull_result_ext->message_binary())); auto msgList = MessageDecoder::decodes(*byteBuffer); // filter msg list again - if (subscriptionData != nullptr && !subscriptionData->tags_set().empty()) { - msgListFilterAgain.reserve(msgList.size()); + if (subscription_data != nullptr && !subscription_data->tags_set().empty()) { + msg_list_filter_again.reserve(msgList.size()); for (const auto& msg : msgList) { const auto& msgTag = msg->tags(); - if (subscriptionData->containsTag(msgTag)) { - msgListFilterAgain.push_back(msg); + if (subscription_data->containsTag(msgTag)) { + msg_list_filter_again.push_back(msg); } } } else { - msgListFilterAgain.swap(msgList); + msg_list_filter_again.swap(msgList); } - for (auto& msg : msgListFilterAgain) { - const auto& tranMsg = msg->getProperty(MQMessageConst::PROPERTY_TRANSACTION_PREPARED); - if (UtilAll::stob(tranMsg)) { - msg->set_transaction_id(msg->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX)); + if (!msg_list_filter_again.empty()) { + std::string min_offset = UtilAll::to_string(pull_result_ext->min_offset()); + std::string max_offset = UtilAll::to_string(pull_result_ext->max_offset()); + for (auto& msg : msg_list_filter_again) { + const auto& tranMsg = msg->getProperty(MQMessageConst::PROPERTY_TRANSACTION_PREPARED); + if (UtilAll::stob(tranMsg)) { + msg->set_transaction_id(msg->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX)); + } + MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_MIN_OFFSET, min_offset); + MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_MAX_OFFSET, max_offset); } - MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_MIN_OFFSET, - UtilAll::to_string(pullResult.min_offset())); - MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_MAX_OFFSET, - UtilAll::to_string(pullResult.max_offset())); } } - return PullResult(pullResultExt.pull_status(), pullResultExt.next_begin_offset(), pullResultExt.min_offset(), - pullResultExt.max_offset(), std::move(msgListFilterAgain)); + return new PullResult(pull_result_ext->pull_status(), pull_result_ext->next_begin_offset(), + pull_result_ext->min_offset(), pull_result_ext->max_offset(), std::move(msg_list_filter_again)); } PullResult* PullAPIWrapper::pullKernelImpl(const MQMessageQueue& mq, diff --git a/src/consumer/PullAPIWrapper.h b/src/consumer/PullAPIWrapper.h index 73d98d958..7bdbf5bf7 100644 --- a/src/consumer/PullAPIWrapper.h +++ b/src/consumer/PullAPIWrapper.h @@ -32,7 +32,9 @@ class PullAPIWrapper { PullAPIWrapper(MQClientInstance* instance, const std::string& consumerGroup); ~PullAPIWrapper(); - PullResult processPullResult(const MQMessageQueue& mq, PullResult& pullResult, SubscriptionData* subscriptionData); + PullResult* processPullResult(const MQMessageQueue& mq, + std::unique_ptr pull_result, + SubscriptionData* subscriptionData); PullResult* pullKernelImpl(const MQMessageQueue& mq, const std::string& subExpression, diff --git a/src/consumer/PullResult.cpp b/src/consumer/PullResult.cpp index 672f2b35a..3312721ad 100644 --- a/src/consumer/PullResult.cpp +++ b/src/consumer/PullResult.cpp @@ -21,10 +21,9 @@ #include "UtilAll.h" -static const char* kPullStatusStrings[] = {"FOUND", "NO_NEW_MSG", "NO_MATCHED_MSG", - "NO_LATEST_MSG" - "OFFSET_ILLEGAL", - "BROKER_TIMEOUT"}; +static const char* kPullStatusStrings[] = { + "FOUND", "NO_NEW_MSG", "NO_MATCHED_MSG", "NO_LATEST_MSG", "OFFSET_ILLEGAL", +}; namespace rocketmq { diff --git a/src/consumer/PullResult.h b/src/consumer/PullResult.h index 0802fef23..df1f4ba7f 100644 --- a/src/consumer/PullResult.h +++ b/src/consumer/PullResult.h @@ -22,12 +22,23 @@ namespace rocketmq { enum PullStatus { + /** + * Founded + */ FOUND, + /** + * No new message can be pull + */ NO_NEW_MSG, + /** + * Filtering results can not match + */ NO_MATCHED_MSG, NO_LATEST_MSG, - OFFSET_ILLEGAL, - BROKER_TIMEOUT // indicate pull request timeout or received NULL response + /** + * Illegal offset,may be too big or too small + */ + OFFSET_ILLEGAL }; class PullResult { From 03f31cf37deb0d345fdc6f51e1d4392cd73ea20f Mon Sep 17 00:00:00 2001 From: James Yin Date: Wed, 23 Sep 2020 17:47:55 +0800 Subject: [PATCH 27/62] refactor: ConsumerRunningInfo::encode --- src/ClientRemotingProcessor.cpp | 2 +- src/protocol/body/ConsumerRunningInfo.cpp | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/ClientRemotingProcessor.cpp b/src/ClientRemotingProcessor.cpp index cbc83637a..cf973067f 100644 --- a/src/ClientRemotingProcessor.cpp +++ b/src/ClientRemotingProcessor.cpp @@ -116,7 +116,7 @@ RemotingCommand* ClientRemotingProcessor::resetOffset(RemotingCommand* request) RemotingCommand* ClientRemotingProcessor::getConsumerRunningInfo(const std::string& addr, RemotingCommand* request) { auto* requestHeader = request->decodeCommandCustomHeader(); - LOG_INFO("getConsumerRunningInfo, group:{}", requestHeader->getConsumerGroup()); + LOG_INFO_NEW("getConsumerRunningInfo, group:{}", requestHeader->getConsumerGroup()); std::unique_ptr response( new RemotingCommand(MQResponseCode::SYSTEM_ERROR, "not set any response code")); diff --git a/src/protocol/body/ConsumerRunningInfo.cpp b/src/protocol/body/ConsumerRunningInfo.cpp index f1ae14f95..a14febd95 100644 --- a/src/protocol/body/ConsumerRunningInfo.cpp +++ b/src/protocol/body/ConsumerRunningInfo.cpp @@ -37,18 +37,17 @@ void ConsumerRunningInfo::setStatusTable(const std::map Date: Wed, 23 Sep 2020 17:51:18 +0800 Subject: [PATCH 28/62] fix: version of RemotingCommand --- src/common/MQVersion.h | 433 ++++++++++------------------------------- 1 file changed, 105 insertions(+), 328 deletions(-) diff --git a/src/common/MQVersion.h b/src/common/MQVersion.h index ec39c28c4..6ee54181d 100644 --- a/src/common/MQVersion.h +++ b/src/common/MQVersion.h @@ -21,320 +21,97 @@ namespace rocketmq { -static const char* RocketMQCPPClientVersion[] = {"V3_0_0_SNAPSHOT", "V3_0_0_ALPHA1", - "V3_0_0_BETA1", "V3_0_0_BETA2", - "V3_0_0_BETA3", "V3_0_0_BETA4", - "V3_0_0_BETA5", "V3_0_0_BETA6_SNAPSHOT", - "V3_0_0_BETA6", "V3_0_0_BETA7_SNAPSHOT", - "V3_0_0_BETA7", "V3_0_0_BETA8_SNAPSHOT", - "V3_0_0_BETA8", "V3_0_0_BETA9_SNAPSHOT", - "V3_0_0_BETA9", "V3_0_0_FINAL", - "V3_0_1_SNAPSHOT", "V3_0_1", - "V3_0_2_SNAPSHOT", "V3_0_2", - "V3_0_3_SNAPSHOT", "V3_0_3", - "V3_0_4_SNAPSHOT", "V3_0_4", - "V3_0_5_SNAPSHOT", "V3_0_5", - "V3_0_6_SNAPSHOT", "V3_0_6", - "V3_0_7_SNAPSHOT", "V3_0_7", - "V3_0_8_SNAPSHOT", "V3_0_8", - "V3_0_9_SNAPSHOT", "V3_0_9", - "V3_0_10_SNAPSHOT", "V3_0_10", - "V3_0_11_SNAPSHOT", "V3_0_11", - "V3_0_12_SNAPSHOT", "V3_0_12", - "V3_0_13_SNAPSHOT", "V3_0_13", - "V3_0_14_SNAPSHOT", "V3_0_14", - "V3_0_15_SNAPSHOT", "V3_0_15", - "V3_1_0_SNAPSHOT", "V3_1_0", - "V3_1_1_SNAPSHOT", "V3_1_1", - "V3_1_2_SNAPSHOT", "V3_1_2", - "V3_1_3_SNAPSHOT", "V3_1_3", - "V3_1_4_SNAPSHOT", "V3_1_4", - "V3_1_5_SNAPSHOT", "V3_1_5", - "V3_1_6_SNAPSHOT", "V3_1_6", - "V3_1_7_SNAPSHOT", "V3_1_7", - "V3_1_8_SNAPSHOT", "V3_1_8", - "V3_1_9_SNAPSHOT", "V3_1_9", - "V3_2_0_SNAPSHOT", "V3_2_0", - "V3_2_1_SNAPSHOT", "V3_2_1", - "V3_2_2_SNAPSHOT", "V3_2_2", - "V3_2_3_SNAPSHOT", "V3_2_3", - "V3_2_4_SNAPSHOT", "V3_2_4", - "V3_2_5_SNAPSHOT", "V3_2_5", - "V3_2_6_SNAPSHOT", "V3_2_6", - "V3_2_7_SNAPSHOT", "V3_2_7", - "V3_2_8_SNAPSHOT", "V3_2_8", - "V3_2_9_SNAPSHOT", "V3_2_9", - "V3_3_0_SNAPSHOT", "V3_3_0", - "V3_3_1_SNAPSHOT", "V3_3_1", - "V3_3_2_SNAPSHOT", "V3_3_2", - "V3_3_3_SNAPSHOT", "V3_3_3", - "V3_3_4_SNAPSHOT", "V3_3_4", - "V3_3_5_SNAPSHOT", "V3_3_5", - "V3_3_6_SNAPSHOT", "V3_3_6", - "V3_3_7_SNAPSHOT", "V3_3_7", - "V3_3_8_SNAPSHOT", "V3_3_8", - "V3_3_9_SNAPSHOT", "V3_3_9", - "V3_4_0_SNAPSHOT", "V3_4_0", - "V3_4_1_SNAPSHOT", "V3_4_1", - "V3_4_2_SNAPSHOT", "V3_4_2", - "V3_4_3_SNAPSHOT", "V3_4_3", - "V3_4_4_SNAPSHOT", "V3_4_4", - "V3_4_5_SNAPSHOT", "V3_4_5", - "V3_4_6_SNAPSHOT", "V3_4_6", - "V3_4_7_SNAPSHOT", "V3_4_7", - "V3_4_8_SNAPSHOT", "V3_4_8", - "V3_4_9_SNAPSHOT", "V3_4_9", - "V3_5_0_SNAPSHOT", "V3_5_0", - "V3_5_1_SNAPSHOT", "V3_5_1", - "V3_5_2_SNAPSHOT", "V3_5_2", - "V3_5_3_SNAPSHOT", "V3_5_3", - "V3_5_4_SNAPSHOT", "V3_5_4", - "V3_5_5_SNAPSHOT", "V3_5_5", - "V3_5_6_SNAPSHOT", "V3_5_6", - "V3_5_7_SNAPSHOT", "V3_5_7", - "V3_5_8_SNAPSHOT", "V3_5_8", - "V3_5_9_SNAPSHOT", "V3_5_9", - "V3_6_0_SNAPSHOT", "V3_6_0", - "V3_6_1_SNAPSHOT", "V3_6_1", - "V3_6_2_SNAPSHOT", "V3_6_2", - "V3_6_3_SNAPSHOT", "V3_6_3", - "V3_6_4_SNAPSHOT", "V3_6_4", - "V3_6_5_SNAPSHOT", "V3_6_5", - "V3_6_6_SNAPSHOT", "V3_6_6", - "V3_6_7_SNAPSHOT", "V3_6_7", - "V3_6_8_SNAPSHOT", "V3_6_8", - "V3_6_9_SNAPSHOT", "V3_6_9", - "V3_7_0_SNAPSHOT", "V3_7_0", - "V3_7_1_SNAPSHOT", "V3_7_1", - "V3_7_2_SNAPSHOT", "V3_7_2", - "V3_7_3_SNAPSHOT", "V3_7_3", - "V3_7_4_SNAPSHOT", "V3_7_4", - "V3_7_5_SNAPSHOT", "V3_7_5", - "V3_7_6_SNAPSHOT", "V3_7_6", - "V3_7_7_SNAPSHOT", "V3_7_7", - "V3_7_8_SNAPSHOT", "V3_7_8", - "V3_7_9_SNAPSHOT", "V3_7_9", - "V3_8_0_SNAPSHOT", "V3_8_0", - "V3_8_1_SNAPSHOT", "V3_8_1", - "V3_8_2_SNAPSHOT", "V3_8_2", - "V3_8_3_SNAPSHOT", "V3_8_3", - "V3_8_4_SNAPSHOT", "V3_8_4", - "V3_8_5_SNAPSHOT", "V3_8_5", - "V3_8_6_SNAPSHOT", "V3_8_6", - "V3_8_7_SNAPSHOT", "V3_8_7", - "V3_8_8_SNAPSHOT", "V3_8_8", - "V3_8_9_SNAPSHOT", "V3_8_9", - "V3_9_1_SNAPSHOT", "V3_9_1", - "V3_9_0_SNAPSHOT", "V3_9_0", - "V3_9_2_SNAPSHOT", "V3_9_2", - "V3_9_3_SNAPSHOT", "V3_9_3", - "V3_9_4_SNAPSHOT", "V3_9_4", - "V3_9_5_SNAPSHOT", "V3_9_5", - "V3_9_6_SNAPSHOT", "V3_9_6", - "V3_9_7_SNAPSHOT", "V3_9_7", - "V3_9_8_SNAPSHOT", "V3_9_8", - "V3_9_9_SNAPSHOT", "V3_9_9", - "V4_0_0_SNAPSHOT", "V4_0_0", - "V4_0_1_SNAPSHOT", "V4_0_1", - "V4_0_2_SNAPSHOT", "V4_0_2", - "V4_0_3_SNAPSHOT", "V4_0_3", - "V4_0_4_SNAPSHOT", "V4_0_4", - "V4_0_5_SNAPSHOT", "V4_0_5", - "V4_0_6_SNAPSHOT", "V4_0_6", - "V4_0_7_SNAPSHOT", "V4_0_7", - "V4_0_8_SNAPSHOT", "V4_0_8", - "V4_0_9_SNAPSHOT", "V4_0_9", - "V4_1_0_SNAPSHOT", "V4_1_0", - "V4_1_1_SNAPSHOT", "V4_1_1", - "V4_1_2_SNAPSHOT", "V4_1_2", - "V4_1_3_SNAPSHOT", "V4_1_3", - "V4_1_4_SNAPSHOT", "V4_1_4", - "V4_1_5_SNAPSHOT", "V4_1_5", - "V4_1_6_SNAPSHOT", "V4_1_6", - "V4_1_7_SNAPSHOT", "V4_1_7", - "V4_1_8_SNAPSHOT", "V4_1_8", - "V4_1_9_SNAPSHOT", "V4_1_9", - "V4_2_0_SNAPSHOT", "V4_2_0", - "V4_2_1_SNAPSHOT", "V4_2_1", - "V4_2_2_SNAPSHOT", "V4_2_2", - "V4_2_3_SNAPSHOT", "V4_2_3", - "V4_2_4_SNAPSHOT", "V4_2_4", - "V4_2_5_SNAPSHOT", "V4_2_5", - "V4_2_6_SNAPSHOT", "V4_2_6", - "V4_2_7_SNAPSHOT", "V4_2_7", - "V4_2_8_SNAPSHOT", "V4_2_8", - "V4_2_9_SNAPSHOT", "V4_2_9", - "V4_3_0_SNAPSHOT", "V4_3_0", - "V4_3_1_SNAPSHOT", "V4_3_1", - "V4_3_2_SNAPSHOT", "V4_3_2", - "V4_3_3_SNAPSHOT", "V4_3_3", - "V4_3_4_SNAPSHOT", "V4_3_4", - "V4_3_5_SNAPSHOT", "V4_3_5", - "V4_3_6_SNAPSHOT", "V4_3_6", - "V4_3_7_SNAPSHOT", "V4_3_7", - "V4_3_8_SNAPSHOT", "V4_3_8", - "V4_3_9_SNAPSHOT", "V4_3_9", - "V4_4_0_SNAPSHOT", "V4_4_0", - "V4_4_1_SNAPSHOT", "V4_4_1", - "V4_4_2_SNAPSHOT", "V4_4_2", - "V4_4_3_SNAPSHOT", "V4_4_3", - "V4_4_4_SNAPSHOT", "V4_4_4", - "V4_4_5_SNAPSHOT", "V4_4_5", - "V4_4_6_SNAPSHOT", "V4_4_6", - "V4_4_7_SNAPSHOT", "V4_4_7", - "V4_4_8_SNAPSHOT", "V4_4_8", - "V4_4_9_SNAPSHOT", "V4_4_9", - "V4_5_0_SNAPSHOT", "V4_5_0", - "V4_5_1_SNAPSHOT", "V4_5_1", - "V4_5_2_SNAPSHOT", "V4_5_2", - "V4_5_3_SNAPSHOT", "V4_5_3", - "V4_5_4_SNAPSHOT", "V4_5_4", - "V4_5_5_SNAPSHOT", "V4_5_5", - "V4_5_6_SNAPSHOT", "V4_5_6", - "V4_5_7_SNAPSHOT", "V4_5_7", - "V4_5_8_SNAPSHOT", "V4_5_8", - "V4_5_9_SNAPSHOT", "V4_5_9", - "V4_6_0_SNAPSHOT", "V4_6_0", - "V4_6_1_SNAPSHOT", "V4_6_1", - "V4_6_2_SNAPSHOT", "V4_6_2", - "V4_6_3_SNAPSHOT", "V4_6_3", - "V4_6_4_SNAPSHOT", "V4_6_4", - "V4_6_5_SNAPSHOT", "V4_6_5", - "V4_6_6_SNAPSHOT", "V4_6_6", - "V4_6_7_SNAPSHOT", "V4_6_7", - "V4_6_8_SNAPSHOT", "V4_6_8", - "V4_6_9_SNAPSHOT", "V4_6_9", - "V4_7_0_SNAPSHOT", "V4_7_0", - "V4_7_1_SNAPSHOT", "V4_7_1", - "V4_7_2_SNAPSHOT", "V4_7_2", - "V4_7_3_SNAPSHOT", "V4_7_3", - "V4_7_4_SNAPSHOT", "V4_7_4", - "V4_7_5_SNAPSHOT", "V4_7_5", - "V4_7_6_SNAPSHOT", "V4_7_6", - "V4_7_7_SNAPSHOT", "V4_7_7", - "V4_7_8_SNAPSHOT", "V4_7_8", - "V4_7_9_SNAPSHOT", "V4_7_9", - "V4_8_0_SNAPSHOT", "V4_8_0", - "V4_8_1_SNAPSHOT", "V4_8_1", - "V4_8_2_SNAPSHOT", "V4_8_2", - "V4_8_3_SNAPSHOT", "V4_8_3", - "V4_8_4_SNAPSHOT", "V4_8_4", - "V4_8_5_SNAPSHOT", "V4_8_5", - "V4_8_6_SNAPSHOT", "V4_8_6", - "V4_8_7_SNAPSHOT", "V4_8_7", - "V4_8_8_SNAPSHOT", "V4_8_8", - "V4_8_9_SNAPSHOT", "V4_8_9", - "V4_9_0_SNAPSHOT", "V4_9_0", - "V4_9_1_SNAPSHOT", "V4_9_1", - "V4_9_2_SNAPSHOT", "V4_9_2", - "V4_9_3_SNAPSHOT", "V4_9_3", - "V4_9_4_SNAPSHOT", "V4_9_4", - "V4_9_5_SNAPSHOT", "V4_9_5", - "V4_9_6_SNAPSHOT", "V4_9_6", - "V4_9_7_SNAPSHOT", "V4_9_7", - "V4_9_8_SNAPSHOT", "V4_9_8", - "V4_9_9_SNAPSHOT", "V4_9_9", - "V5_0_0_SNAPSHOT", "V5_0_0", - "V5_0_1_SNAPSHOT", "V5_0_1", - "V5_0_2_SNAPSHOT", "V5_0_2", - "V5_0_3_SNAPSHOT", "V5_0_3", - "V5_0_4_SNAPSHOT", "V5_0_4", - "V5_0_5_SNAPSHOT", "V5_0_5", - "V5_0_6_SNAPSHOT", "V5_0_6", - "V5_0_7_SNAPSHOT", "V5_0_7", - "V5_0_8_SNAPSHOT", "V5_0_8", - "V5_0_9_SNAPSHOT", "V5_0_9", - "V5_1_0_SNAPSHOT", "V5_1_0", - "V5_1_1_SNAPSHOT", "V5_1_1", - "V5_1_2_SNAPSHOT", "V5_1_2", - "V5_1_3_SNAPSHOT", "V5_1_3", - "V5_1_4_SNAPSHOT", "V5_1_4", - "V5_1_5_SNAPSHOT", "V5_1_5", - "V5_1_6_SNAPSHOT", "V5_1_6", - "V5_1_7_SNAPSHOT", "V5_1_7", - "V5_1_8_SNAPSHOT", "V5_1_8", - "V5_1_9_SNAPSHOT", "V5_1_9", - "V5_2_0_SNAPSHOT", "V5_2_0", - "V5_2_1_SNAPSHOT", "V5_2_1", - "V5_2_2_SNAPSHOT", "V5_2_2", - "V5_2_3_SNAPSHOT", "V5_2_3", - "V5_2_4_SNAPSHOT", "V5_2_4", - "V5_2_5_SNAPSHOT", "V5_2_5", - "V5_2_6_SNAPSHOT", "V5_2_6", - "V5_2_7_SNAPSHOT", "V5_2_7", - "V5_2_8_SNAPSHOT", "V5_2_8", - "V5_2_9_SNAPSHOT", "V5_2_9", - "V5_3_0_SNAPSHOT", "V5_3_0", - "V5_3_1_SNAPSHOT", "V5_3_1", - "V5_3_2_SNAPSHOT", "V5_3_2", - "V5_3_3_SNAPSHOT", "V5_3_3", - "V5_3_4_SNAPSHOT", "V5_3_4", - "V5_3_5_SNAPSHOT", "V5_3_5", - "V5_3_6_SNAPSHOT", "V5_3_6", - "V5_3_7_SNAPSHOT", "V5_3_7", - "V5_3_8_SNAPSHOT", "V5_3_8", - "V5_3_9_SNAPSHOT", "V5_3_9", - "V5_4_0_SNAPSHOT", "V5_4_0", - "V5_4_1_SNAPSHOT", "V5_4_1", - "V5_4_2_SNAPSHOT", "V5_4_2", - "V5_4_3_SNAPSHOT", "V5_4_3", - "V5_4_4_SNAPSHOT", "V5_4_4", - "V5_4_5_SNAPSHOT", "V5_4_5", - "V5_4_6_SNAPSHOT", "V5_4_6", - "V5_4_7_SNAPSHOT", "V5_4_7", - "V5_4_8_SNAPSHOT", "V5_4_8", - "V5_4_9_SNAPSHOT", "V5_4_9", - "V5_5_0_SNAPSHOT", "V5_5_0", - "V5_5_1_SNAPSHOT", "V5_5_1", - "V5_5_2_SNAPSHOT", "V5_5_2", - "V5_5_3_SNAPSHOT", "V5_5_3", - "V5_5_4_SNAPSHOT", "V5_5_4", - "V5_5_5_SNAPSHOT", "V5_5_5", - "V5_5_6_SNAPSHOT", "V5_5_6", - "V5_5_7_SNAPSHOT", "V5_5_7", - "V5_5_8_SNAPSHOT", "V5_5_8", - "V5_5_9_SNAPSHOT", "V5_5_9", - "V5_6_0_SNAPSHOT", "V5_6_0", - "V5_6_1_SNAPSHOT", "V5_6_1", - "V5_6_2_SNAPSHOT", "V5_6_2", - "V5_6_3_SNAPSHOT", "V5_6_3", - "V5_6_4_SNAPSHOT", "V5_6_4", - "V5_6_5_SNAPSHOT", "V5_6_5", - "V5_6_6_SNAPSHOT", "V5_6_6", - "V5_6_7_SNAPSHOT", "V5_6_7", - "V5_6_8_SNAPSHOT", "V5_6_8", - "V5_6_9_SNAPSHOT", "V5_6_9", - "V5_7_0_SNAPSHOT", "V5_7_0", - "V5_7_1_SNAPSHOT", "V5_7_1", - "V5_7_2_SNAPSHOT", "V5_7_2", - "V5_7_3_SNAPSHOT", "V5_7_3", - "V5_7_4_SNAPSHOT", "V5_7_4", - "V5_7_5_SNAPSHOT", "V5_7_5", - "V5_7_6_SNAPSHOT", "V5_7_6", - "V5_7_7_SNAPSHOT", "V5_7_7", - "V5_7_8_SNAPSHOT", "V5_7_8", - "V5_7_9_SNAPSHOT", "V5_7_9", - "V5_8_0_SNAPSHOT", "V5_8_0", - "V5_8_1_SNAPSHOT", "V5_8_1", - "V5_8_2_SNAPSHOT", "V5_8_2", - "V5_8_3_SNAPSHOT", "V5_8_3", - "V5_8_4_SNAPSHOT", "V5_8_4", - "V5_8_5_SNAPSHOT", "V5_8_5", - "V5_8_6_SNAPSHOT", "V5_8_6", - "V5_8_7_SNAPSHOT", "V5_8_7", - "V5_8_8_SNAPSHOT", "V5_8_8", - "V5_8_9_SNAPSHOT", "V5_8_9", - "V5_9_0_SNAPSHOT", "V5_9_0", - "V5_9_1_SNAPSHOT", "V5_9_1", - "V5_9_2_SNAPSHOT", "V5_9_2", - "V5_9_3_SNAPSHOT", "V5_9_3", - "V5_9_4_SNAPSHOT", "V5_9_4", - "V5_9_5_SNAPSHOT", "V5_9_5", - "V5_9_6_SNAPSHOT", "V5_9_6", - "V5_9_7_SNAPSHOT", "V5_9_7", - "V5_9_8_SNAPSHOT", "V5_9_8", - "V5_9_9_SNAPSHOT", "V5_9_9", - "HIGHER_VERSION"}; +static const char* RocketMQCPPClientVersion[] = { + "V3_0_0_SNAPSHOT", "V3_0_0_ALPHA1", "V3_0_0_BETA1", "V3_0_0_BETA2", "V3_0_0_BETA3", "V3_0_0_BETA4", "V3_0_0_BETA5", + "V3_0_0_BETA6_SNAPSHOT", "V3_0_0_BETA6", "V3_0_0_BETA7_SNAPSHOT", "V3_0_0_BETA7", "V3_0_0_BETA8_SNAPSHOT", + "V3_0_0_BETA8", "V3_0_0_BETA9_SNAPSHOT", "V3_0_0_BETA9", "V3_0_0_FINAL", "V3_0_1_SNAPSHOT", "V3_0_1", + "V3_0_2_SNAPSHOT", "V3_0_2", "V3_0_3_SNAPSHOT", "V3_0_3", "V3_0_4_SNAPSHOT", "V3_0_4", "V3_0_5_SNAPSHOT", "V3_0_5", + "V3_0_6_SNAPSHOT", "V3_0_6", "V3_0_7_SNAPSHOT", "V3_0_7", "V3_0_8_SNAPSHOT", "V3_0_8", "V3_0_9_SNAPSHOT", "V3_0_9", + "V3_0_10_SNAPSHOT", "V3_0_10", "V3_0_11_SNAPSHOT", "V3_0_11", "V3_0_12_SNAPSHOT", "V3_0_12", "V3_0_13_SNAPSHOT", + "V3_0_13", "V3_0_14_SNAPSHOT", "V3_0_14", "V3_0_15_SNAPSHOT", "V3_0_15", "V3_1_0_SNAPSHOT", "V3_1_0", + "V3_1_1_SNAPSHOT", "V3_1_1", "V3_1_2_SNAPSHOT", "V3_1_2", "V3_1_3_SNAPSHOT", "V3_1_3", "V3_1_4_SNAPSHOT", "V3_1_4", + "V3_1_5_SNAPSHOT", "V3_1_5", "V3_1_6_SNAPSHOT", "V3_1_6", "V3_1_7_SNAPSHOT", "V3_1_7", "V3_1_8_SNAPSHOT", "V3_1_8", + "V3_1_9_SNAPSHOT", "V3_1_9", "V3_2_0_SNAPSHOT", "V3_2_0", "V3_2_1_SNAPSHOT", "V3_2_1", "V3_2_2_SNAPSHOT", "V3_2_2", + "V3_2_3_SNAPSHOT", "V3_2_3", "V3_2_4_SNAPSHOT", "V3_2_4", "V3_2_5_SNAPSHOT", "V3_2_5", "V3_2_6_SNAPSHOT", "V3_2_6", + "V3_2_7_SNAPSHOT", "V3_2_7", "V3_2_8_SNAPSHOT", "V3_2_8", "V3_2_9_SNAPSHOT", "V3_2_9", + // "V3_3_0_SNAPSHOT", "V3_3_0", + "V3_3_1_SNAPSHOT", "V3_3_1", "V3_3_2_SNAPSHOT", "V3_3_2", "V3_3_3_SNAPSHOT", "V3_3_3", "V3_3_4_SNAPSHOT", "V3_3_4", + "V3_3_5_SNAPSHOT", "V3_3_5", "V3_3_6_SNAPSHOT", "V3_3_6", "V3_3_7_SNAPSHOT", "V3_3_7", "V3_3_8_SNAPSHOT", "V3_3_8", + "V3_3_9_SNAPSHOT", "V3_3_9", + // "V3_4_0_SNAPSHOT", "V3_4_0", + "V3_4_1_SNAPSHOT", "V3_4_1", "V3_4_2_SNAPSHOT", "V3_4_2", "V3_4_3_SNAPSHOT", "V3_4_3", "V3_4_4_SNAPSHOT", "V3_4_4", + "V3_4_5_SNAPSHOT", "V3_4_5", "V3_4_6_SNAPSHOT", "V3_4_6", "V3_4_7_SNAPSHOT", "V3_4_7", "V3_4_8_SNAPSHOT", "V3_4_8", + "V3_4_9_SNAPSHOT", "V3_4_9", + // "V3_5_0_SNAPSHOT", "V3_5_0", + "V3_5_1_SNAPSHOT", "V3_5_1", "V3_5_2_SNAPSHOT", "V3_5_2", "V3_5_3_SNAPSHOT", "V3_5_3", "V3_5_4_SNAPSHOT", "V3_5_4", + "V3_5_5_SNAPSHOT", "V3_5_5", "V3_5_6_SNAPSHOT", "V3_5_6", "V3_5_7_SNAPSHOT", "V3_5_7", "V3_5_8_SNAPSHOT", "V3_5_8", + "V3_5_9_SNAPSHOT", "V3_5_9", + // "V3_6_0_SNAPSHOT", "V3_6_0", + "V3_6_1_SNAPSHOT", "V3_6_1", "V3_6_2_SNAPSHOT", "V3_6_2", "V3_6_3_SNAPSHOT", "V3_6_3", "V3_6_4_SNAPSHOT", "V3_6_4", + "V3_6_5_SNAPSHOT", "V3_6_5", "V3_6_6_SNAPSHOT", "V3_6_6", "V3_6_7_SNAPSHOT", "V3_6_7", "V3_6_8_SNAPSHOT", "V3_6_8", + "V3_6_9_SNAPSHOT", "V3_6_9", + // "V3_7_0_SNAPSHOT", "V3_7_0", + "V3_7_1_SNAPSHOT", "V3_7_1", "V3_7_2_SNAPSHOT", "V3_7_2", "V3_7_3_SNAPSHOT", "V3_7_3", "V3_7_4_SNAPSHOT", "V3_7_4", + "V3_7_5_SNAPSHOT", "V3_7_5", "V3_7_6_SNAPSHOT", "V3_7_6", "V3_7_7_SNAPSHOT", "V3_7_7", "V3_7_8_SNAPSHOT", "V3_7_8", + "V3_7_9_SNAPSHOT", "V3_7_9", + // "V3_8_0_SNAPSHOT", "V3_8_0", + "V3_8_1_SNAPSHOT", "V3_8_1", "V3_8_2_SNAPSHOT", "V3_8_2", "V3_8_3_SNAPSHOT", "V3_8_3", "V3_8_4_SNAPSHOT", "V3_8_4", + "V3_8_5_SNAPSHOT", "V3_8_5", "V3_8_6_SNAPSHOT", "V3_8_6", "V3_8_7_SNAPSHOT", "V3_8_7", "V3_8_8_SNAPSHOT", "V3_8_8", + "V3_8_9_SNAPSHOT", "V3_8_9", + // "V3_9_0_SNAPSHOT", "V3_9_0", + "V3_9_1_SNAPSHOT", "V3_9_1", "V3_9_2_SNAPSHOT", "V3_9_2", "V3_9_3_SNAPSHOT", "V3_9_3", "V3_9_4_SNAPSHOT", "V3_9_4", + "V3_9_5_SNAPSHOT", "V3_9_5", "V3_9_6_SNAPSHOT", "V3_9_6", "V3_9_7_SNAPSHOT", "V3_9_7", "V3_9_8_SNAPSHOT", "V3_9_8", + "V3_9_9_SNAPSHOT", "V3_9_9", "V4_0_0_SNAPSHOT", "V4_0_0", "V4_0_1_SNAPSHOT", "V4_0_1", "V4_0_2_SNAPSHOT", "V4_0_2", + "V4_0_3_SNAPSHOT", "V4_0_3", "V4_0_4_SNAPSHOT", "V4_0_4", "V4_0_5_SNAPSHOT", "V4_0_5", "V4_0_6_SNAPSHOT", "V4_0_6", + "V4_0_7_SNAPSHOT", "V4_0_7", "V4_0_8_SNAPSHOT", "V4_0_8", "V4_0_9_SNAPSHOT", "V4_0_9", "V4_1_0_SNAPSHOT", "V4_1_0", + "V4_1_1_SNAPSHOT", "V4_1_1", "V4_1_2_SNAPSHOT", "V4_1_2", "V4_1_3_SNAPSHOT", "V4_1_3", "V4_1_4_SNAPSHOT", "V4_1_4", + "V4_1_5_SNAPSHOT", "V4_1_5", "V4_1_6_SNAPSHOT", "V4_1_6", "V4_1_7_SNAPSHOT", "V4_1_7", "V4_1_8_SNAPSHOT", "V4_1_8", + "V4_1_9_SNAPSHOT", "V4_1_9", "V4_2_0_SNAPSHOT", "V4_2_0", "V4_2_1_SNAPSHOT", "V4_2_1", "V4_2_2_SNAPSHOT", "V4_2_2", + "V4_2_3_SNAPSHOT", "V4_2_3", "V4_2_4_SNAPSHOT", "V4_2_4", "V4_2_5_SNAPSHOT", "V4_2_5", "V4_2_6_SNAPSHOT", "V4_2_6", + "V4_2_7_SNAPSHOT", "V4_2_7", "V4_2_8_SNAPSHOT", "V4_2_8", "V4_2_9_SNAPSHOT", "V4_2_9", "V4_3_0_SNAPSHOT", "V4_3_0", + "V4_3_1_SNAPSHOT", "V4_3_1", "V4_3_2_SNAPSHOT", "V4_3_2", "V4_3_3_SNAPSHOT", "V4_3_3", "V4_3_4_SNAPSHOT", "V4_3_4", + "V4_3_5_SNAPSHOT", "V4_3_5", "V4_3_6_SNAPSHOT", "V4_3_6", "V4_3_7_SNAPSHOT", "V4_3_7", "V4_3_8_SNAPSHOT", "V4_3_8", + "V4_3_9_SNAPSHOT", "V4_3_9", "V4_4_0_SNAPSHOT", "V4_4_0", "V4_4_1_SNAPSHOT", "V4_4_1", "V4_4_2_SNAPSHOT", "V4_4_2", + "V4_4_3_SNAPSHOT", "V4_4_3", "V4_4_4_SNAPSHOT", "V4_4_4", "V4_4_5_SNAPSHOT", "V4_4_5", "V4_4_6_SNAPSHOT", "V4_4_6", + "V4_4_7_SNAPSHOT", "V4_4_7", "V4_4_8_SNAPSHOT", "V4_4_8", "V4_4_9_SNAPSHOT", "V4_4_9", "V4_5_0_SNAPSHOT", "V4_5_0", + "V4_5_1_SNAPSHOT", "V4_5_1", "V4_5_2_SNAPSHOT", "V4_5_2", "V4_5_3_SNAPSHOT", "V4_5_3", "V4_5_4_SNAPSHOT", "V4_5_4", + "V4_5_5_SNAPSHOT", "V4_5_5", "V4_5_6_SNAPSHOT", "V4_5_6", "V4_5_7_SNAPSHOT", "V4_5_7", "V4_5_8_SNAPSHOT", "V4_5_8", + "V4_5_9_SNAPSHOT", "V4_5_9", "V4_6_0_SNAPSHOT", "V4_6_0", "V4_6_1_SNAPSHOT", "V4_6_1", "V4_6_2_SNAPSHOT", "V4_6_2", + "V4_6_3_SNAPSHOT", "V4_6_3", "V4_6_4_SNAPSHOT", "V4_6_4", "V4_6_5_SNAPSHOT", "V4_6_5", "V4_6_6_SNAPSHOT", "V4_6_6", + "V4_6_7_SNAPSHOT", "V4_6_7", "V4_6_8_SNAPSHOT", "V4_6_8", "V4_6_9_SNAPSHOT", "V4_6_9", "V4_7_0_SNAPSHOT", "V4_7_0", + "V4_7_1_SNAPSHOT", "V4_7_1", "V4_7_2_SNAPSHOT", "V4_7_2", "V4_7_3_SNAPSHOT", "V4_7_3", "V4_7_4_SNAPSHOT", "V4_7_4", + "V4_7_5_SNAPSHOT", "V4_7_5", "V4_7_6_SNAPSHOT", "V4_7_6", "V4_7_7_SNAPSHOT", "V4_7_7", "V4_7_8_SNAPSHOT", "V4_7_8", + "V4_7_9_SNAPSHOT", "V4_7_9", "V4_8_0_SNAPSHOT", "V4_8_0", "V4_8_1_SNAPSHOT", "V4_8_1", "V4_8_2_SNAPSHOT", "V4_8_2", + "V4_8_3_SNAPSHOT", "V4_8_3", "V4_8_4_SNAPSHOT", "V4_8_4", "V4_8_5_SNAPSHOT", "V4_8_5", "V4_8_6_SNAPSHOT", "V4_8_6", + "V4_8_7_SNAPSHOT", "V4_8_7", "V4_8_8_SNAPSHOT", "V4_8_8", "V4_8_9_SNAPSHOT", "V4_8_9", "V4_9_0_SNAPSHOT", "V4_9_0", + "V4_9_1_SNAPSHOT", "V4_9_1", "V4_9_2_SNAPSHOT", "V4_9_2", "V4_9_3_SNAPSHOT", "V4_9_3", "V4_9_4_SNAPSHOT", "V4_9_4", + "V4_9_5_SNAPSHOT", "V4_9_5", "V4_9_6_SNAPSHOT", "V4_9_6", "V4_9_7_SNAPSHOT", "V4_9_7", "V4_9_8_SNAPSHOT", "V4_9_8", + "V4_9_9_SNAPSHOT", "V4_9_9", "V5_0_0_SNAPSHOT", "V5_0_0", "V5_0_1_SNAPSHOT", "V5_0_1", "V5_0_2_SNAPSHOT", "V5_0_2", + "V5_0_3_SNAPSHOT", "V5_0_3", "V5_0_4_SNAPSHOT", "V5_0_4", "V5_0_5_SNAPSHOT", "V5_0_5", "V5_0_6_SNAPSHOT", "V5_0_6", + "V5_0_7_SNAPSHOT", "V5_0_7", "V5_0_8_SNAPSHOT", "V5_0_8", "V5_0_9_SNAPSHOT", "V5_0_9", "V5_1_0_SNAPSHOT", "V5_1_0", + "V5_1_1_SNAPSHOT", "V5_1_1", "V5_1_2_SNAPSHOT", "V5_1_2", "V5_1_3_SNAPSHOT", "V5_1_3", "V5_1_4_SNAPSHOT", "V5_1_4", + "V5_1_5_SNAPSHOT", "V5_1_5", "V5_1_6_SNAPSHOT", "V5_1_6", "V5_1_7_SNAPSHOT", "V5_1_7", "V5_1_8_SNAPSHOT", "V5_1_8", + "V5_1_9_SNAPSHOT", "V5_1_9", "V5_2_0_SNAPSHOT", "V5_2_0", "V5_2_1_SNAPSHOT", "V5_2_1", "V5_2_2_SNAPSHOT", "V5_2_2", + "V5_2_3_SNAPSHOT", "V5_2_3", "V5_2_4_SNAPSHOT", "V5_2_4", "V5_2_5_SNAPSHOT", "V5_2_5", "V5_2_6_SNAPSHOT", "V5_2_6", + "V5_2_7_SNAPSHOT", "V5_2_7", "V5_2_8_SNAPSHOT", "V5_2_8", "V5_2_9_SNAPSHOT", "V5_2_9", "V5_3_0_SNAPSHOT", "V5_3_0", + "V5_3_1_SNAPSHOT", "V5_3_1", "V5_3_2_SNAPSHOT", "V5_3_2", "V5_3_3_SNAPSHOT", "V5_3_3", "V5_3_4_SNAPSHOT", "V5_3_4", + "V5_3_5_SNAPSHOT", "V5_3_5", "V5_3_6_SNAPSHOT", "V5_3_6", "V5_3_7_SNAPSHOT", "V5_3_7", "V5_3_8_SNAPSHOT", "V5_3_8", + "V5_3_9_SNAPSHOT", "V5_3_9", "V5_4_0_SNAPSHOT", "V5_4_0", "V5_4_1_SNAPSHOT", "V5_4_1", "V5_4_2_SNAPSHOT", "V5_4_2", + "V5_4_3_SNAPSHOT", "V5_4_3", "V5_4_4_SNAPSHOT", "V5_4_4", "V5_4_5_SNAPSHOT", "V5_4_5", "V5_4_6_SNAPSHOT", "V5_4_6", + "V5_4_7_SNAPSHOT", "V5_4_7", "V5_4_8_SNAPSHOT", "V5_4_8", "V5_4_9_SNAPSHOT", "V5_4_9", "V5_5_0_SNAPSHOT", "V5_5_0", + "V5_5_1_SNAPSHOT", "V5_5_1", "V5_5_2_SNAPSHOT", "V5_5_2", "V5_5_3_SNAPSHOT", "V5_5_3", "V5_5_4_SNAPSHOT", "V5_5_4", + "V5_5_5_SNAPSHOT", "V5_5_5", "V5_5_6_SNAPSHOT", "V5_5_6", "V5_5_7_SNAPSHOT", "V5_5_7", "V5_5_8_SNAPSHOT", "V5_5_8", + "V5_5_9_SNAPSHOT", "V5_5_9", "V5_6_0_SNAPSHOT", "V5_6_0", "V5_6_1_SNAPSHOT", "V5_6_1", "V5_6_2_SNAPSHOT", "V5_6_2", + "V5_6_3_SNAPSHOT", "V5_6_3", "V5_6_4_SNAPSHOT", "V5_6_4", "V5_6_5_SNAPSHOT", "V5_6_5", "V5_6_6_SNAPSHOT", "V5_6_6", + "V5_6_7_SNAPSHOT", "V5_6_7", "V5_6_8_SNAPSHOT", "V5_6_8", "V5_6_9_SNAPSHOT", "V5_6_9", "V5_7_0_SNAPSHOT", "V5_7_0", + "V5_7_1_SNAPSHOT", "V5_7_1", "V5_7_2_SNAPSHOT", "V5_7_2", "V5_7_3_SNAPSHOT", "V5_7_3", "V5_7_4_SNAPSHOT", "V5_7_4", + "V5_7_5_SNAPSHOT", "V5_7_5", "V5_7_6_SNAPSHOT", "V5_7_6", "V5_7_7_SNAPSHOT", "V5_7_7", "V5_7_8_SNAPSHOT", "V5_7_8", + "V5_7_9_SNAPSHOT", "V5_7_9", "V5_8_0_SNAPSHOT", "V5_8_0", "V5_8_1_SNAPSHOT", "V5_8_1", "V5_8_2_SNAPSHOT", "V5_8_2", + "V5_8_3_SNAPSHOT", "V5_8_3", "V5_8_4_SNAPSHOT", "V5_8_4", "V5_8_5_SNAPSHOT", "V5_8_5", "V5_8_6_SNAPSHOT", "V5_8_6", + "V5_8_7_SNAPSHOT", "V5_8_7", "V5_8_8_SNAPSHOT", "V5_8_8", "V5_8_9_SNAPSHOT", "V5_8_9", "V5_9_0_SNAPSHOT", "V5_9_0", + "V5_9_1_SNAPSHOT", "V5_9_1", "V5_9_2_SNAPSHOT", "V5_9_2", "V5_9_3_SNAPSHOT", "V5_9_3", "V5_9_4_SNAPSHOT", "V5_9_4", + "V5_9_5_SNAPSHOT", "V5_9_5", "V5_9_6_SNAPSHOT", "V5_9_6", "V5_9_7_SNAPSHOT", "V5_9_7", "V5_9_8_SNAPSHOT", "V5_9_8", + "V5_9_9_SNAPSHOT", "V5_9_9", "HIGHER_VERSION"}; class MQVersion { public: @@ -425,8 +202,8 @@ class MQVersion { V3_2_8, V3_2_9_SNAPSHOT, V3_2_9, - V3_3_0_SNAPSHOT, - V3_3_0, + // V3_3_0_SNAPSHOT, + // V3_3_0, V3_3_1_SNAPSHOT, V3_3_1, V3_3_2_SNAPSHOT, @@ -445,8 +222,8 @@ class MQVersion { V3_3_8, V3_3_9_SNAPSHOT, V3_3_9, - V3_4_0_SNAPSHOT, - V3_4_0, + // V3_4_0_SNAPSHOT, + // V3_4_0, V3_4_1_SNAPSHOT, V3_4_1, V3_4_2_SNAPSHOT, @@ -465,8 +242,8 @@ class MQVersion { V3_4_8, V3_4_9_SNAPSHOT, V3_4_9, - V3_5_0_SNAPSHOT, - V3_5_0, + // V3_5_0_SNAPSHOT, + // V3_5_0, V3_5_1_SNAPSHOT, V3_5_1, V3_5_2_SNAPSHOT, @@ -485,8 +262,8 @@ class MQVersion { V3_5_8, V3_5_9_SNAPSHOT, V3_5_9, - V3_6_0_SNAPSHOT, - V3_6_0, + // V3_6_0_SNAPSHOT, + // V3_6_0, V3_6_1_SNAPSHOT, V3_6_1, V3_6_2_SNAPSHOT, @@ -505,8 +282,8 @@ class MQVersion { V3_6_8, V3_6_9_SNAPSHOT, V3_6_9, - V3_7_0_SNAPSHOT, - V3_7_0, + // V3_7_0_SNAPSHOT, + // V3_7_0, V3_7_1_SNAPSHOT, V3_7_1, V3_7_2_SNAPSHOT, @@ -525,8 +302,8 @@ class MQVersion { V3_7_8, V3_7_9_SNAPSHOT, V3_7_9, - V3_8_0_SNAPSHOT, - V3_8_0, + // V3_8_0_SNAPSHOT, + // V3_8_0, V3_8_1_SNAPSHOT, V3_8_1, V3_8_2_SNAPSHOT, @@ -545,8 +322,8 @@ class MQVersion { V3_8_8, V3_8_9_SNAPSHOT, V3_8_9, - V3_9_0_SNAPSHOT, - V3_9_0, + // V3_9_0_SNAPSHOT, + // V3_9_0, V3_9_1_SNAPSHOT, V3_9_1, V3_9_2_SNAPSHOT, From 2af15ead43fbc6e2c801fb572f0ea8d88d76d51b Mon Sep 17 00:00:00 2001 From: James Yin Date: Thu, 24 Sep 2020 11:09:51 +0800 Subject: [PATCH 29/62] refactor: logger --- src/common/UtilAll.cpp | 14 +++--- src/extern/CProducer.cpp | 4 +- src/extern/CPushConsumer.cpp | 4 +- src/log/Logging.cpp | 87 +++++++++++++++++++----------------- src/log/Logging.h | 33 ++++++++------ 5 files changed, 78 insertions(+), 64 deletions(-) diff --git a/src/common/UtilAll.cpp b/src/common/UtilAll.cpp index 90dec5b8f..7da66f255 100644 --- a/src/common/UtilAll.cpp +++ b/src/common/UtilAll.cpp @@ -278,17 +278,17 @@ uint32_t UtilAll::getIP() { std::string UtilAll::getHomeDirectory() { #ifndef WIN32 - char* homeEnv = std::getenv("HOME"); - std::string homeDir; - if (homeEnv == NULL) { - homeDir.append(getpwuid(getuid())->pw_dir); + char* home_env = std::getenv("HOME"); + std::string home_dir; + if (home_env == NULL) { + home_dir.append(getpwuid(getuid())->pw_dir); } else { - homeDir.append(homeEnv); + home_dir.append(home_env); } #else - std::string homeDir(std::getenv("USERPROFILE")); + std::string home_dir(std::getenv("USERPROFILE")); #endif - return homeDir; + return home_dir; } static bool createDirectoryInner(const char* dir) { diff --git a/src/extern/CProducer.cpp b/src/extern/CProducer.cpp index edf607287..7629594a8 100644 --- a/src/extern/CProducer.cpp +++ b/src/extern/CProducer.cpp @@ -511,7 +511,7 @@ int SetProducerLogFileNumAndSize(CProducer* producer, int fileNum, long fileSize if (producer == NULL) { return NULL_POINTER; } - DEFAULT_LOG_ADAPTER->setLogFileNumAndSize(fileNum, fileSize); + DEFAULT_LOGGER_INSTANCE->setLogFileNumAndSize(fileNum, fileSize); return OK; } @@ -519,7 +519,7 @@ int SetProducerLogLevel(CProducer* producer, CLogLevel level) { if (producer == NULL) { return NULL_POINTER; } - DEFAULT_LOG_ADAPTER->set_log_level((LogLevel)level); + DEFAULT_LOGGER_INSTANCE->set_log_level((LogLevel)level); return OK; } diff --git a/src/extern/CPushConsumer.cpp b/src/extern/CPushConsumer.cpp index 0ba977ef1..f90802e82 100644 --- a/src/extern/CPushConsumer.cpp +++ b/src/extern/CPushConsumer.cpp @@ -258,7 +258,7 @@ int SetPushConsumerLogFileNumAndSize(CPushConsumer* consumer, int fileNum, long if (consumer == NULL) { return NULL_POINTER; } - DEFAULT_LOG_ADAPTER->setLogFileNumAndSize(fileNum, fileSize); + DEFAULT_LOGGER_INSTANCE->setLogFileNumAndSize(fileNum, fileSize); return OK; } @@ -266,6 +266,6 @@ int SetPushConsumerLogLevel(CPushConsumer* consumer, CLogLevel level) { if (consumer == NULL) { return NULL_POINTER; } - DEFAULT_LOG_ADAPTER->set_log_level((LogLevel)level); + DEFAULT_LOGGER_INSTANCE->set_log_level((LogLevel)level); return OK; } diff --git a/src/log/Logging.cpp b/src/log/Logging.cpp index 8b77528ac..3fc2b9cdf 100644 --- a/src/log/Logging.cpp +++ b/src/log/Logging.cpp @@ -29,12 +29,30 @@ namespace rocketmq { -LogAdapter* LogAdapter::getLogInstance() { - static LogAdapter singleton_; +Logger* Logger::getLoggerInstance() { + static Logger singleton_("default"); return &singleton_; } -LogAdapter::LogAdapter() : log_level_(LOG_LEVEL_INFO) { +Logger::Logger(const std::string& name) : log_level_(LOG_LEVEL_INFO) { + try { + init_log_dir_(); + init_spdlog_env_(); + logger_ = create_rotating_logger_(name, log_file_, 1024 * 1024 * 100, 3); + set_log_level_(log_level_); + } catch (std::exception& e) { + std::cerr << "initialite logger failed" << std::endl; + exit(-1); + } +} + +Logger::~Logger() { + if (logger_ != nullptr) { + spdlog::drop(logger_->name()); + } +} + +void Logger::init_log_dir_() { std::string log_dir; const char* dir = std::getenv(ROCKETMQ_CPP_LOG_DIR_ENV.c_str()); if (dir != nullptr && dir[0] != '\0') { @@ -47,51 +65,34 @@ LogAdapter::LogAdapter() : log_level_(LOG_LEVEL_INFO) { if (log_dir[log_dir.size() - 1] != '/') { log_dir.append("/"); } + std::string log_file_name = UtilAll::to_string(UtilAll::getProcessId()) + "_" + "rocketmq-cpp.log"; + log_file_ = log_dir + log_file_name; +} - if (!UtilAll::existDirectory(log_dir)) { - UtilAll::createDirectory(log_dir); - } - if (!UtilAll::existDirectory(log_dir)) { - std::cerr << "create log dir error, will exit" << std::endl; - exit(1); - } - - std::string fileName = UtilAll::to_string(UtilAll::getProcessId()) + "_" + "rocketmq-cpp.log"; - log_file_ = log_dir + fileName; - -#if SPDLOG_VER_MAJOR >= 1 - spdlog::init_thread_pool(8192, 1); - - auto rotating_sink = std::make_shared(log_file_, 1024 * 1024 * 100, 3); - rotating_sink->set_level(spdlog::level::debug); - rotating_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [thread@%t] - %v"); - log_sinks_.push_back(rotating_sink); - - logger_ = std::make_shared("default", log_sinks_.begin(), log_sinks_.end(), - spdlog::thread_pool(), spdlog::async_overflow_policy::block); - - // register it if you need to access it globally - spdlog::register_logger(logger_); - +void Logger::init_spdlog_env_() { + spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [thread@%t] - %v"); // when an error occurred, flush disk immediately - logger_->flush_on(spdlog::level::err); - + spdlog::flush_on(spdlog::level::err); +#if SPDLOG_VER_MAJOR >= 1 + spdlog::init_thread_pool(spdlog::details::default_async_q_size, 1); spdlog::flush_every(std::chrono::seconds(3)); #else - size_t q_size = 4096; - spdlog::set_async_mode(q_size); - logger_ = spdlog::rotating_logger_mt("default", log_file_, 1024 * 1024 * 100, 3); - logger_->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [thread@%t] - %v"); + spdlog::set_async_mode(8192, async_overflow_policy::block_retry, nullptr, std::chrono::milliseconds(3000), nullptr); #endif - - setLogLevelInner(log_level_); } -LogAdapter::~LogAdapter() { - spdlog::drop("default"); +std::shared_ptr Logger::create_rotating_logger_(const std::string& name, + const std::string& filepath, + std::size_t max_size, + std::size_t max_files) { +#if SPDLOG_VER_MAJOR >= 1 + return spdlog::create_async(name, filepath, max_size, max_files); +#else + return spdlog::rotating_logger_mt(name, filepath, max_size, max_files); +#endif } -void LogAdapter::setLogLevelInner(LogLevel log_level) { +void Logger::set_log_level_(LogLevel log_level) { switch (log_level) { case LOG_LEVEL_FATAL: logger_->set_level(spdlog::level::critical); @@ -117,6 +118,12 @@ void LogAdapter::setLogLevelInner(LogLevel log_level) { } } -void LogAdapter::setLogFileNumAndSize(int logNum, int sizeOfPerFile) {} +void Logger::setLogFileNumAndSize(int logNum, int sizeOfPerFile) { + // FIXME: set after clients started + auto name = logger_->name(); + spdlog::drop(name); + logger_ = create_rotating_logger_(name, log_file_, sizeOfPerFile, logNum); + set_log_level_(log_level_); +} } // namespace rocketmq diff --git a/src/log/Logging.h b/src/log/Logging.h index 5afcc5673..42b1f3b42 100644 --- a/src/log/Logging.h +++ b/src/log/Logging.h @@ -42,38 +42,45 @@ enum LogLevel { LOG_LEVEL_LEVEL_NUM = 7 }; -class LogAdapter { +class Logger { public: - virtual ~LogAdapter(); + static Logger* getLoggerInstance(); - static LogAdapter* getLogInstance(); + public: + virtual ~Logger(); inline spdlog::logger* getSeverityLogger() { return logger_.get(); } void setLogFileNumAndSize(int logNum, int sizeOfPerFile); inline LogLevel log_level() const { return log_level_; } - inline void set_log_level(LogLevel logLevel) { - log_level_ = logLevel; - setLogLevelInner(logLevel); + inline void set_log_level(LogLevel log_level) { + log_level_ = log_level; + set_log_level_(log_level); } private: - LogAdapter(); - void setLogLevelInner(LogLevel logLevel); + Logger(const std::string& name); + + void init_log_dir_(); + void init_spdlog_env_(); + + std::shared_ptr create_rotating_logger_(const std::string& name, + const std::string& filepath, + std::size_t max_size, + std::size_t max_files); + + void set_log_level_(LogLevel log_level); private: LogLevel log_level_; std::string log_file_; std::shared_ptr logger_; -#if SPDLOG_VER_MAJOR >= 1 - std::vector log_sinks_; -#endif }; -#define DEFAULT_LOG_ADAPTER LogAdapter::getLogInstance() -#define DEFAULT_LOGGER DEFAULT_LOG_ADAPTER->getSeverityLogger() +#define DEFAULT_LOGGER_INSTANCE Logger::getLoggerInstance() +#define DEFAULT_LOGGER DEFAULT_LOGGER_INSTANCE->getSeverityLogger() #define SPDLOG_PRINTF(logger, level, format, ...) \ do { \ From a750efad307a98c49b20d2beebc763633af2e472 Mon Sep 17 00:00:00 2001 From: James Yin Date: Mon, 21 Sep 2020 15:46:55 +0800 Subject: [PATCH 30/62] feat: DefaultLitePullConsumer --- ...sumeMessage.c => PullConsumeMessage.c.bak} | 0 ...{PullConsumer.cpp => PullConsumer.cpp.bak} | 0 include/DefaultLitePullConsumer.h | 79 ++ include/DefaultLitePullConsumerConfig.h | 85 ++ include/DefaultLitePullConsumerConfigProxy.h | 175 ++++ include/DefaultMQPullConsumer.h | 81 -- include/DefaultMQPullConsumerConfigProxy.h | 48 - include/LitePullConsumer.h | 79 ++ include/MQAdmin.h | 2 +- include/MQPullConsumer.h | 103 -- ...ig.h => TopicMessageQueueChangeListener.h} | 25 +- src/MQClientAPIImpl.cpp | 2 +- src/MQClientAPIImpl.h | 2 +- src/MQClientImpl.cpp | 2 +- src/MQClientImpl.h | 2 +- src/common/PullCallbackWrap.cpp | 0 src/common/PullCallbackWrap.h | 0 src/common/PullSysFlag.cpp | 11 +- src/common/PullSysFlag.h | 3 +- src/common/SendCallbackWrap.cpp | 0 src/common/SendCallbackWrap.h | 0 src/concurrent/blocking_queue.hpp | 94 ++ src/concurrent/concurrent_queue.hpp | 2 +- src/concurrent/executor_impl.hpp | 1 + src/consumer/AssignedMessageQueue.hpp | 219 +++++ src/consumer/DefaultLitePullConsumer.cpp | 130 +++ .../DefaultLitePullConsumerConfigImpl.hpp | 150 +++ src/consumer/DefaultLitePullConsumerImpl.cpp | 894 ++++++++++++++++++ src/consumer/DefaultLitePullConsumerImpl.h | 228 +++++ src/consumer/DefaultMQPullConsumer.cpp | 110 --- src/consumer/DefaultMQPullConsumerImpl.cpp | 375 -------- src/consumer/DefaultMQPullConsumerImpl.h | 173 ---- .../consumer/MessageQueueListener.h | 14 +- src/consumer/RebalanceImpl.cpp | 99 +- src/consumer/RebalanceImpl.h | 2 +- src/consumer/RebalanceLitePullImpl.cpp | 119 +++ ...ancePullImpl.h => RebalanceLitePullImpl.h} | 14 +- src/consumer/RebalancePullImpl.cpp | 48 - src/extern/CPullConsumer.cpp | 504 +++++----- ...umerTest.cpp => CPullConsumerTest.cpp.bak} | 2 +- 40 files changed, 2598 insertions(+), 1279 deletions(-) rename example/{PullConsumeMessage.c => PullConsumeMessage.c.bak} (100%) rename example/{PullConsumer.cpp => PullConsumer.cpp.bak} (100%) create mode 100755 include/DefaultLitePullConsumer.h create mode 100644 include/DefaultLitePullConsumerConfig.h create mode 100644 include/DefaultLitePullConsumerConfigProxy.h delete mode 100755 include/DefaultMQPullConsumer.h delete mode 100644 include/DefaultMQPullConsumerConfigProxy.h create mode 100644 include/LitePullConsumer.h delete mode 100644 include/MQPullConsumer.h rename include/{DefaultMQPullConsumerConfig.h => TopicMessageQueueChangeListener.h} (53%) mode change 100755 => 100644 src/common/PullCallbackWrap.cpp mode change 100755 => 100644 src/common/PullCallbackWrap.h mode change 100755 => 100644 src/common/SendCallbackWrap.cpp mode change 100755 => 100644 src/common/SendCallbackWrap.h create mode 100644 src/concurrent/blocking_queue.hpp create mode 100644 src/consumer/AssignedMessageQueue.hpp create mode 100644 src/consumer/DefaultLitePullConsumer.cpp create mode 100644 src/consumer/DefaultLitePullConsumerConfigImpl.hpp create mode 100644 src/consumer/DefaultLitePullConsumerImpl.cpp create mode 100755 src/consumer/DefaultLitePullConsumerImpl.h delete mode 100644 src/consumer/DefaultMQPullConsumer.cpp delete mode 100644 src/consumer/DefaultMQPullConsumerImpl.cpp delete mode 100755 src/consumer/DefaultMQPullConsumerImpl.h rename include/MQueueListener.h => src/consumer/MessageQueueListener.h (80%) create mode 100644 src/consumer/RebalanceLitePullImpl.cpp rename src/consumer/{RebalancePullImpl.h => RebalanceLitePullImpl.h} (82%) delete mode 100644 src/consumer/RebalancePullImpl.cpp rename test/src/extern/{CPullConsumerTest.cpp => CPullConsumerTest.cpp.bak} (99%) diff --git a/example/PullConsumeMessage.c b/example/PullConsumeMessage.c.bak similarity index 100% rename from example/PullConsumeMessage.c rename to example/PullConsumeMessage.c.bak diff --git a/example/PullConsumer.cpp b/example/PullConsumer.cpp.bak similarity index 100% rename from example/PullConsumer.cpp rename to example/PullConsumer.cpp.bak diff --git a/include/DefaultLitePullConsumer.h b/include/DefaultLitePullConsumer.h new file mode 100755 index 000000000..8ad2e9b46 --- /dev/null +++ b/include/DefaultLitePullConsumer.h @@ -0,0 +1,79 @@ +/* + * 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_DEFAULTLITEPULLCONSUMER_H_ +#define ROCKETMQ_DEFAULTLITEPULLCONSUMER_H_ + +#include "DefaultLitePullConsumerConfigProxy.h" +#include "LitePullConsumer.h" +#include "RPCHook.h" + +namespace rocketmq { + +class ROCKETMQCLIENT_API DefaultLitePullConsumer : public DefaultLitePullConsumerConfigProxy, // base + public LitePullConsumer // interface +{ + public: + DefaultLitePullConsumer(const std::string& groupname); + DefaultLitePullConsumer(const std::string& groupname, RPCHookPtr rpcHook); + virtual ~DefaultLitePullConsumer(); + + public: // LitePullConsumer + void start() override; + void shutdown() override; + + bool isAutoCommit() const override; + void setAutoCommit(bool auto_commit) override; + + void subscribe(const std::string& topic, const std::string& subExpression) override; + void subscribe(const std::string& topic, const MessageSelector& selector) override; + + void unsubscribe(const std::string& topic) override; + + std::vector poll() override; + std::vector poll(long timeout) override; + + std::vector fetchMessageQueues(const std::string& topic) override; + + void assign(const std::vector& messageQueues) override; + + void seek(const MQMessageQueue& messageQueue, int64_t offset) override; + void seekToBegin(const MQMessageQueue& messageQueue) override; + void seekToEnd(const MQMessageQueue& messageQueue) override; + + int64_t offsetForTimestamp(const MQMessageQueue& messageQueue, int64_t timestamp) override; + + void pause(const std::vector& messageQueues) override; + void resume(const std::vector& messageQueues) override; + + void commitSync() override; + + int64_t committed(const MQMessageQueue& messageQueue) override; + + void registerTopicMessageQueueChangeListener( + const std::string& topic, + TopicMessageQueueChangeListener* topicMessageQueueChangeListener) override; + + public: + void setRPCHook(RPCHookPtr rpcHook); + + protected: + std::shared_ptr pull_consumer_impl_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_DEFAULTLITEPULLCONSUMER_H_ diff --git a/include/DefaultLitePullConsumerConfig.h b/include/DefaultLitePullConsumerConfig.h new file mode 100644 index 000000000..037d33154 --- /dev/null +++ b/include/DefaultLitePullConsumerConfig.h @@ -0,0 +1,85 @@ +/* + * 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_DEFAULTLITEPULLCONSUMERCONFIG_H_ +#define ROCKETMQ_DEFAULTLITEPULLCONSUMERCONFIG_H_ + +#include "AllocateMQStrategy.h" +#include "ConsumeType.h" +#include "MQClientConfig.h" + +namespace rocketmq { + +class DefaultLitePullConsumerConfig; +typedef std::shared_ptr DefaultLitePullConsumerConfigPtr; + +class ROCKETMQCLIENT_API DefaultLitePullConsumerConfig : virtual public MQClientConfig // base interface +{ + public: + virtual ~DefaultLitePullConsumerConfig() = default; + + virtual MessageModel message_model() const = 0; + virtual void set_message_model(MessageModel message_model) = 0; + + virtual ConsumeFromWhere consume_from_where() const = 0; + virtual void set_consume_from_where(ConsumeFromWhere consume_from_where) = 0; + + virtual const std::string& consume_timestamp() const = 0; + virtual void set_consume_timestamp(const std::string& consume_timestamp) = 0; + + virtual long auto_commit_interval_millis() const = 0; + virtual void set_auto_commit_interval_millis(long auto_commit_interval_millis) = 0; + + virtual int pull_batch_size() const = 0; + virtual void set_pull_batch_size(int pull_batch_size) = 0; + + virtual int pull_thread_nums() const = 0; + virtual void set_pull_thread_nums(int pull_thread_nums) = 0; + + virtual bool long_polling_enable() const = 0; + virtual void set_long_polling_enable(bool long_polling_enable) = 0; + + virtual long consumer_pull_timeout_millis() const = 0; + virtual void set_consumer_pull_timeout_millis(long consumer_pull_timeout_millis) = 0; + + virtual long consumer_timeout_millis_when_suspend() const = 0; + virtual void set_consumer_timeout_millis_when_suspend(long consumer_timeout_millis_when_suspend) = 0; + + virtual long broker_suspend_max_time_millis() const = 0; + virtual void set_broker_suspend_max_time_millis(long broker_suspend_max_time_millis) = 0; + + virtual long pull_threshold_for_all() const = 0; + virtual void set_pull_threshold_for_all(long pull_threshold_for_all) = 0; + + virtual int pull_threshold_for_queue() const = 0; + virtual void set_pull_threshold_for_queue(int pull_threshold_for_queue) = 0; + + virtual long pull_time_delay_millis_when_exception() const = 0; + virtual void set_pull_time_delay_millis_when_exception(long pull_time_delay_millis_when_exception) = 0; + + virtual long poll_timeout_millis() const = 0; + virtual void set_poll_timeout_millis(long poll_timeout_millis) = 0; + + virtual long topic_metadata_check_interval_millis() const = 0; + virtual void set_topic_metadata_check_interval_millis(long topic_metadata_check_interval_millis) = 0; + + virtual AllocateMQStrategy* allocate_mq_strategy() const = 0; + virtual void set_allocate_mq_strategy(AllocateMQStrategy* strategy) = 0; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_DEFAULTLITEPULLCONSUMERCONFIG_H_ diff --git a/include/DefaultLitePullConsumerConfigProxy.h b/include/DefaultLitePullConsumerConfigProxy.h new file mode 100644 index 000000000..eae047fe4 --- /dev/null +++ b/include/DefaultLitePullConsumerConfigProxy.h @@ -0,0 +1,175 @@ +/* + * 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_DEFAULTLITEPULLCONSUMERCONFIGPROXY_H__ +#define ROCKETMQ_DEFAULTLITEPULLCONSUMERCONFIGPROXY_H__ + +#include "DefaultLitePullConsumerConfig.h" +#include "MQClientConfigProxy.h" + +namespace rocketmq { + +class ROCKETMQCLIENT_API DefaultLitePullConsumerConfigProxy : public MQClientConfigProxy, // base + virtual public DefaultLitePullConsumerConfig // interface +{ + public: + DefaultLitePullConsumerConfigProxy(DefaultLitePullConsumerConfigPtr consumerConfig) + : MQClientConfigProxy(consumerConfig) {} + virtual ~DefaultLitePullConsumerConfigProxy() = default; + + MessageModel message_model() const override { + return dynamic_cast(client_config_.get())->message_model(); + } + + void set_message_model(MessageModel messageModel) override { + dynamic_cast(client_config_.get())->set_message_model(messageModel); + } + + ConsumeFromWhere consume_from_where() const override { + return dynamic_cast(client_config_.get())->consume_from_where(); + } + + void set_consume_from_where(ConsumeFromWhere consumeFromWhere) override { + dynamic_cast(client_config_.get())->set_consume_from_where(consumeFromWhere); + } + + const std::string& consume_timestamp() const override { + return dynamic_cast(client_config_.get())->consume_timestamp(); + } + void set_consume_timestamp(const std::string& consumeTimestamp) override { + dynamic_cast(client_config_.get())->set_consume_timestamp(consumeTimestamp); + } + + long auto_commit_interval_millis() const override { + return dynamic_cast(client_config_.get())->auto_commit_interval_millis(); + } + + void set_auto_commit_interval_millis(long auto_commit_interval_millis) override { + dynamic_cast(client_config_.get()) + ->set_auto_commit_interval_millis(auto_commit_interval_millis); + } + + int pull_batch_size() const override { + return dynamic_cast(client_config_.get())->pull_batch_size(); + } + + void set_pull_batch_size(int pull_batch_size) override { + dynamic_cast(client_config_.get())->set_pull_batch_size(pull_batch_size); + } + + int pull_thread_nums() const override { + return dynamic_cast(client_config_.get())->pull_thread_nums(); + } + + void set_pull_thread_nums(int pullThreadNums) override { + dynamic_cast(client_config_.get())->set_pull_thread_nums(pullThreadNums); + } + + bool long_polling_enable() const override { + return dynamic_cast(client_config_.get())->long_polling_enable(); + } + + void set_long_polling_enable(bool long_polling_enable) override { + dynamic_cast(client_config_.get())->set_long_polling_enable(long_polling_enable); + } + + long consumer_pull_timeout_millis() const override { + return dynamic_cast(client_config_.get())->consumer_pull_timeout_millis(); + } + + void set_consumer_pull_timeout_millis(long consumer_pull_timeout_millis) override { + dynamic_cast(client_config_.get()) + ->set_consumer_pull_timeout_millis(consumer_pull_timeout_millis); + } + + long consumer_timeout_millis_when_suspend() const override { + return dynamic_cast(client_config_.get())->consumer_timeout_millis_when_suspend(); + } + + void set_consumer_timeout_millis_when_suspend(long consumer_timeout_millis_when_suspend) override { + dynamic_cast(client_config_.get()) + ->set_consumer_timeout_millis_when_suspend(consumer_timeout_millis_when_suspend); + } + + long broker_suspend_max_time_millis() const override { + return dynamic_cast(client_config_.get())->broker_suspend_max_time_millis(); + } + + void set_broker_suspend_max_time_millis(long broker_suspend_max_time_millis) override { + dynamic_cast(client_config_.get()) + ->set_broker_suspend_max_time_millis(broker_suspend_max_time_millis); + } + + long pull_threshold_for_all() const override { + return dynamic_cast(client_config_.get())->pull_threshold_for_all(); + } + + void set_pull_threshold_for_all(long pull_threshold_for_all) override { + dynamic_cast(client_config_.get()) + ->set_pull_threshold_for_all(pull_threshold_for_all); + } + + int pull_threshold_for_queue() const override { + return dynamic_cast(client_config_.get())->pull_threshold_for_queue(); + } + + void set_pull_threshold_for_queue(int pull_threshold_for_queue) override { + dynamic_cast(client_config_.get()) + ->set_pull_threshold_for_queue(pull_threshold_for_queue); + } + + long pull_time_delay_millis_when_exception() const override { + return dynamic_cast(client_config_.get())->pull_time_delay_millis_when_exception(); + } + + void set_pull_time_delay_millis_when_exception(long pull_time_delay_millis_when_exception) override { + dynamic_cast(client_config_.get()) + ->set_pull_time_delay_millis_when_exception(pull_time_delay_millis_when_exception); + } + + long poll_timeout_millis() const override { + return dynamic_cast(client_config_.get())->poll_timeout_millis(); + } + + void set_poll_timeout_millis(long poll_timeout_millis) override { + dynamic_cast(client_config_.get())->set_poll_timeout_millis(poll_timeout_millis); + } + + long topic_metadata_check_interval_millis() const override { + return dynamic_cast(client_config_.get())->topic_metadata_check_interval_millis(); + } + + void set_topic_metadata_check_interval_millis(long topicMetadataCheckIntervalMillis) override { + dynamic_cast(client_config_.get()) + ->set_topic_metadata_check_interval_millis(topicMetadataCheckIntervalMillis); + } + + AllocateMQStrategy* allocate_mq_strategy() const override { + return dynamic_cast(client_config_.get())->allocate_mq_strategy(); + } + + void set_allocate_mq_strategy(AllocateMQStrategy* strategy) override { + dynamic_cast(client_config_.get())->set_allocate_mq_strategy(strategy); + } + + inline DefaultLitePullConsumerConfigPtr real_config() const { + return std::dynamic_pointer_cast(client_config_); + } +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_DEFAULTLITEPULLCONSUMERCONFIGPROXY_H__ diff --git a/include/DefaultMQPullConsumer.h b/include/DefaultMQPullConsumer.h deleted file mode 100755 index 2f39e9705..000000000 --- a/include/DefaultMQPullConsumer.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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 ROCCKETMQ_DEFAULTMQPULLCONSUMER_H_ -#define ROCCKETMQ_DEFAULTMQPULLCONSUMER_H_ - -#include -#include - -#include "AllocateMQStrategy.h" -#include "DefaultMQPullConsumerConfigProxy.h" -#include "MQPullConsumer.h" -#include "RPCHook.h" - -namespace rocketmq { - -class ROCKETMQCLIENT_API DefaultMQPullConsumer : public MQPullConsumer, public DefaultMQPullConsumerConfigProxy { - public: - DefaultMQPullConsumer(const std::string& groupname); - DefaultMQPullConsumer(const std::string& groupname, RPCHookPtr rpcHook); - virtual ~DefaultMQPullConsumer(); - - public: // MQConsumer - void start() override; - void shutdown() override; - - bool sendMessageBack(MessageExtPtr msg, int delayLevel) override; - bool sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) override; - void fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) override; - - public: // MQPullConsumer - void registerMessageQueueListener(const std::string& topic, MQueueListener* pListener) override; - - PullResult pull(const MQMessageQueue& mq, const std::string& subExpression, int64_t offset, int maxNums) override; - - void pull(const MQMessageQueue& mq, - const std::string& subExpression, - int64_t offset, - int maxNums, - PullCallback* pullCallback) override; - - PullResult pullBlockIfNotFound(const MQMessageQueue& mq, - const std::string& subExpression, - int64_t offset, - int maxNums) override; - - void pullBlockIfNotFound(const MQMessageQueue& mq, - const std::string& subExpression, - int64_t offset, - int maxNums, - PullCallback* pullCallback) override; - - void updateConsumeOffset(const MQMessageQueue& mq, int64_t offset) override; - - int64_t fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore) override; - - void fetchMessageQueuesInBalance(const std::string& topic, std::vector& mqs) override; - - public: - void setRPCHook(RPCHookPtr rpcHook); - - protected: - std::shared_ptr m_pullConsumerDelegate; -}; - -} // namespace rocketmq - -#endif // ROCCKETMQ_DEFAULTMQPULLCONSUMER_H_ diff --git a/include/DefaultMQPullConsumerConfigProxy.h b/include/DefaultMQPullConsumerConfigProxy.h deleted file mode 100644 index 63c73ec0e..000000000 --- a/include/DefaultMQPullConsumerConfigProxy.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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_DEFAULTMQPULLCONSUMERCONFIGPROXY_H_ -#define ROCKETMQ_DEFAULTMQPULLCONSUMERCONFIGPROXY_H_ - -#include "DefaultMQPullConsumerConfig.h" -#include "MQClientConfigProxy.h" - -namespace rocketmq { - -class ROCKETMQCLIENT_API DefaultMQPullConsumerConfigProxy : virtual public DefaultMQPullConsumerConfig, - public MQClientConfigProxy { - public: - DefaultMQPullConsumerConfigProxy(DefaultMQPullConsumerConfigPtr consumerConfig) - : MQClientConfigProxy(consumerConfig), m_consumerConfig(consumerConfig) {} - virtual ~DefaultMQPullConsumerConfigProxy() = default; - - MessageModel getMessageModel() const override { return m_consumerConfig->getMessageModel(); } - - void setMessageModel(MessageModel messageModel) override { m_consumerConfig->setMessageModel(messageModel); } - - AllocateMQStrategy* getAllocateMQStrategy() const override { return m_consumerConfig->getAllocateMQStrategy(); } - - void setAllocateMQStrategy(AllocateMQStrategy* strategy) override { - m_consumerConfig->setAllocateMQStrategy(strategy); - } - - private: - DefaultMQPullConsumerConfigPtr m_consumerConfig; -}; - -} // namespace rocketmq - -#endif // ROCKETMQ_DEFAULTMQPULLCONSUMERCONFIGPROXY_H_ diff --git a/include/LitePullConsumer.h b/include/LitePullConsumer.h new file mode 100644 index 000000000..6dcc6d17b --- /dev/null +++ b/include/LitePullConsumer.h @@ -0,0 +1,79 @@ +/* + * 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_LITEPULLCONSUMER_H_ +#define ROCKETMQ_LITEPULLCONSUMER_H_ + +#include "TopicMessageQueueChangeListener.h" +#include "MessageSelector.h" +#include "MQMessageExt.h" +#include "MQMessageQueue.h" + +namespace rocketmq { + +/** + * LitePullConsumer - interface for pull consumer + */ +class ROCKETMQCLIENT_API LitePullConsumer { + public: + virtual ~LitePullConsumer() = default; + + public: // LitePullConsumer in Java + virtual void start() = 0; + virtual void shutdown() = 0; + + virtual bool isAutoCommit() const = 0; + virtual void setAutoCommit(bool auto_commit) = 0; + + // + // Automatic mode + + virtual void subscribe(const std::string& topic, const std::string& subExpression) = 0; + virtual void subscribe(const std::string& topic, const MessageSelector& selector) = 0; + + virtual void unsubscribe(const std::string& topic) = 0; + + virtual std::vector poll() = 0; + virtual std::vector poll(long timeout) = 0; + + // + // Manually mode + + virtual std::vector fetchMessageQueues(const std::string& topic) = 0; + + virtual void assign(const std::vector& messageQueues) = 0; + + virtual void seek(const MQMessageQueue& messageQueue, int64_t offset) = 0; + virtual void seekToBegin(const MQMessageQueue& messageQueue) = 0; + virtual void seekToEnd(const MQMessageQueue& messageQueue) = 0; + + virtual int64_t offsetForTimestamp(const MQMessageQueue& messageQueue, int64_t timestamp) = 0; + + virtual void pause(const std::vector& messageQueues) = 0; + virtual void resume(const std::vector& messageQueues) = 0; + + virtual void commitSync() = 0; + + virtual int64_t committed(const MQMessageQueue& messageQueue) = 0; + + virtual void registerTopicMessageQueueChangeListener( + const std::string& topic, + TopicMessageQueueChangeListener* topicMessageQueueChangeListener) = 0; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_LITEPULLCONSUMER_H_ diff --git a/include/MQAdmin.h b/include/MQAdmin.h index dff6f5111..61c3044d4 100644 --- a/include/MQAdmin.h +++ b/include/MQAdmin.h @@ -47,7 +47,7 @@ class ROCKETMQCLIENT_API MQAdmin { * @param timestamp from when in milliseconds. * @return offset */ - virtual int64_t searchOffset(const MQMessageQueue& mq, uint64_t timestamp) = 0; + virtual int64_t searchOffset(const MQMessageQueue& mq, int64_t timestamp) = 0; /** * Gets the max offset diff --git a/include/MQPullConsumer.h b/include/MQPullConsumer.h deleted file mode 100644 index 2545116d6..000000000 --- a/include/MQPullConsumer.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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_MQPULLCONSUMER_H_ -#define ROCKETMQ_MQPULLCONSUMER_H_ - -#include "MQConsumer.h" -#include "MQueueListener.h" -#include "PullCallback.h" - -namespace rocketmq { - -class ROCKETMQCLIENT_API MQPullConsumer : public MQConsumer { - public: - virtual void registerMessageQueueListener(const std::string& topic, MQueueListener* pListener) = 0; - - /** - * pull msg 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 - * accroding to PullResult - */ - virtual PullResult pull(const MQMessageQueue& mq, const std::string& subExpression, int64_t offset, int maxNums) = 0; - - virtual void pull(const MQMessageQueue& mq, - const std::string& subExpression, - int64_t offset, - int maxNums, - PullCallback* pullCallback) = 0; - - /** - * 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 - */ - virtual PullResult pullBlockIfNotFound(const MQMessageQueue& mq, - const std::string& subExpression, - int64_t offset, - int maxNums) = 0; - - virtual void pullBlockIfNotFound(const MQMessageQueue& mq, - const std::string& subExpression, - int64_t offset, - int maxNums, - PullCallback* pullCallback) = 0; - - virtual void updateConsumeOffset(const MQMessageQueue& mq, int64_t offset) = 0; - - /** - * Fetch the offset - * - * @param mq - * @param fromStore - * @return - */ - virtual int64_t fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore) = 0; - - /** - * Fetch the message queues according to the topic - * - * @param topic Message Topic - * @return - */ - virtual void fetchMessageQueuesInBalance(const std::string& topic, std::vector& mqs) = 0; -}; - -} // namespace rocketmq - -#endif // ROCKETMQ_MQPULLCONSUMER_H_ diff --git a/include/DefaultMQPullConsumerConfig.h b/include/TopicMessageQueueChangeListener.h similarity index 53% rename from include/DefaultMQPullConsumerConfig.h rename to include/TopicMessageQueueChangeListener.h index 056e6d970..59e7121d0 100644 --- a/include/DefaultMQPullConsumerConfig.h +++ b/include/TopicMessageQueueChangeListener.h @@ -14,29 +14,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef ROCKETMQ_DEFAULTMQPULLCONSUMERCONFIG_H_ -#define ROCKETMQ_DEFAULTMQPULLCONSUMERCONFIG_H_ +#ifndef ROCKETMQ_TOPICMESSAGEQUEUECHANGLISTENER_H_ +#define ROCKETMQ_TOPICMESSAGEQUEUECHANGLISTENER_H_ -#include "AllocateMQStrategy.h" -#include "ConsumeType.h" -#include "MQClientConfig.h" +#include // std::vector -namespace rocketmq { +#include "MQMessageQueue.h" -class DefaultMQPullConsumerConfig; -typedef std::shared_ptr DefaultMQPullConsumerConfigPtr; +namespace rocketmq { -class ROCKETMQCLIENT_API DefaultMQPullConsumerConfig : virtual public MQClientConfig { +class ROCKETMQCLIENT_API TopicMessageQueueChangeListener { public: - virtual ~DefaultMQPullConsumerConfig() = default; - - virtual MessageModel getMessageModel() const = 0; - virtual void setMessageModel(MessageModel messageModel) = 0; + virtual ~TopicMessageQueueChangeListener() = default; - virtual AllocateMQStrategy* getAllocateMQStrategy() const = 0; - virtual void setAllocateMQStrategy(AllocateMQStrategy* strategy) = 0; + virtual void onChanged(const std::string& topic, const std::vector& messageQueues) = 0; }; } // namespace rocketmq -#endif // ROCKETMQ_DEFAULTMQPULLCONSUMERCONFIG_H_ +#endif // ROCKETMQ_TOPICMESSAGEQUEUECHANGLISTENER_H_ diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index c3e010fb7..2d35354dd 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -331,7 +331,7 @@ MQMessageExt MQClientAPIImpl::viewMessage(const std::string& addr, int64_t phyof int64_t MQClientAPIImpl::searchOffset(const std::string& addr, const std::string& topic, int queueId, - uint64_t timestamp, + int64_t timestamp, int timeoutMillis) { auto* requestHeader = new SearchOffsetRequestHeader(); requestHeader->topic = topic; diff --git a/src/MQClientAPIImpl.h b/src/MQClientAPIImpl.h index b105ffefe..143a6a5db 100644 --- a/src/MQClientAPIImpl.h +++ b/src/MQClientAPIImpl.h @@ -91,7 +91,7 @@ class MQClientAPIImpl { int64_t searchOffset(const std::string& addr, const std::string& topic, int queueId, - uint64_t timestamp, + int64_t timestamp, int timeoutMillis); int64_t getMaxOffset(const std::string& addr, const std::string& topic, int queueId, int timeoutMillis); diff --git a/src/MQClientImpl.cpp b/src/MQClientImpl.cpp index 195e6800f..e7c97a5cc 100644 --- a/src/MQClientImpl.cpp +++ b/src/MQClientImpl.cpp @@ -55,7 +55,7 @@ void MQClientImpl::createTopic(const std::string& key, const std::string& newTop } } -int64_t MQClientImpl::searchOffset(const MQMessageQueue& mq, uint64_t timestamp) { +int64_t MQClientImpl::searchOffset(const MQMessageQueue& mq, int64_t timestamp) { return client_instance_->getMQAdminImpl()->searchOffset(mq, timestamp); } diff --git a/src/MQClientImpl.h b/src/MQClientImpl.h index 879f471ce..074837490 100644 --- a/src/MQClientImpl.h +++ b/src/MQClientImpl.h @@ -31,7 +31,7 @@ class MQClientImpl : public MQAdmin { public: // MQAdmin void createTopic(const std::string& key, const std::string& newTopic, int queueNum) override; - int64_t searchOffset(const MQMessageQueue& mq, uint64_t timestamp) override; + int64_t searchOffset(const MQMessageQueue& mq, int64_t timestamp) override; int64_t maxOffset(const MQMessageQueue& mq) override; int64_t minOffset(const MQMessageQueue& mq) override; int64_t earliestMsgStoreTime(const MQMessageQueue& mq) override; diff --git a/src/common/PullCallbackWrap.cpp b/src/common/PullCallbackWrap.cpp old mode 100755 new mode 100644 diff --git a/src/common/PullCallbackWrap.h b/src/common/PullCallbackWrap.h old mode 100755 new mode 100644 diff --git a/src/common/PullSysFlag.cpp b/src/common/PullSysFlag.cpp index dc8194fd8..68f6a3b28 100644 --- a/src/common/PullSysFlag.cpp +++ b/src/common/PullSysFlag.cpp @@ -20,10 +20,11 @@ static const int FLAG_COMMIT_OFFSET = 0x1 << 0; static const int FLAG_SUSPEND = 0x1 << 1; static const int FLAG_SUBSCRIPTION = 0x1 << 2; static const int FLAG_CLASS_FILTER = 0x1 << 3; +static const int FLAG_LITE_PULL_MESSAGE = 0x1 << 4; namespace rocketmq { -int PullSysFlag::buildSysFlag(bool commitOffset, bool suspend, bool subscription, bool classFilter) { +int PullSysFlag::buildSysFlag(bool commitOffset, bool suspend, bool subscription, bool classFilter, bool litePull) { int flag = 0; if (commitOffset) { @@ -42,6 +43,10 @@ int PullSysFlag::buildSysFlag(bool commitOffset, bool suspend, bool subscription flag |= FLAG_CLASS_FILTER; } + if (litePull) { + flag |= FLAG_LITE_PULL_MESSAGE; + } + return flag; } @@ -65,4 +70,8 @@ bool PullSysFlag::hasClassFilterFlag(int sysFlag) { return (sysFlag & FLAG_CLASS_FILTER) == FLAG_CLASS_FILTER; } +bool PullSysFlag::hasLitePullFlag(int sysFlag) { + return (sysFlag & FLAG_LITE_PULL_MESSAGE) == FLAG_LITE_PULL_MESSAGE; +} + } // namespace rocketmq diff --git a/src/common/PullSysFlag.h b/src/common/PullSysFlag.h index 51f2944b5..f604eaeba 100644 --- a/src/common/PullSysFlag.h +++ b/src/common/PullSysFlag.h @@ -21,13 +21,14 @@ namespace rocketmq { class PullSysFlag { public: - static int buildSysFlag(bool commitOffset, bool suspend, bool subscription, bool classFilter); + static int buildSysFlag(bool commitOffset, bool suspend, bool subscription, bool classFilter, bool litePull = false); 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); + static bool hasLitePullFlag(int sysFlag); }; } // namespace rocketmq diff --git a/src/common/SendCallbackWrap.cpp b/src/common/SendCallbackWrap.cpp old mode 100755 new mode 100644 diff --git a/src/common/SendCallbackWrap.h b/src/common/SendCallbackWrap.h old mode 100755 new mode 100644 diff --git a/src/concurrent/blocking_queue.hpp b/src/concurrent/blocking_queue.hpp new file mode 100644 index 000000000..e801cf78e --- /dev/null +++ b/src/concurrent/blocking_queue.hpp @@ -0,0 +1,94 @@ +/* + * 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_CONCURRENT_BLOCKINGQUEUE_HPP_ +#define ROCKETMQ_CONCURRENT_BLOCKINGQUEUE_HPP_ + +#include +#include +#include +#include + +#include "time.hpp" + +namespace rocketmq { + +template +class blocking_queue { + public: + // types: + typedef T value_type; + + virtual ~blocking_queue() = default; + + bool empty() { + std::lock_guard lock(mutex_); + return queue_.empty(); + } + + size_t size() { + std::lock_guard lock(mutex_); + return queue_.size(); + } + + template ::type, value_type>::value, int>::type = 0> + void push_back(E&& v) { + std::unique_lock lock(mutex_); + queue_.emplace_back(new value_type(std::forward(v))); + cv_.notify_one(); + } + + template ::value, int>::type = 0> + void push_back(E v) { + std::unique_lock lock(mutex_); + queue_.emplace_back(v); + cv_.notify_one(); + } + + std::unique_ptr pop_front() { + std::unique_lock lock(mutex_); + if (queue_.empty()) { + cv_.wait(lock, [&] { return !queue_.empty(); }); + } + auto v = std::move(queue_.front()); + queue_.pop_front(); + return v; + } + + std::unique_ptr pop_front(long timeout, time_unit unit) { + auto deadline = until_time_point(timeout, unit); + std::unique_lock lock(mutex_); + if (queue_.empty()) { + cv_.wait_until(lock, deadline, [&] { return !queue_.empty(); }); + } + if (!queue_.empty()) { + auto v = std::move(queue_.front()); + queue_.pop_front(); + return v; + } + return std::unique_ptr(); + } + + private: + std::deque> queue_; + std::mutex mutex_; + std::condition_variable cv_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_CONCURRENT_BLOCKINGQUEUE_HPP_ diff --git a/src/concurrent/concurrent_queue.hpp b/src/concurrent/concurrent_queue.hpp index 7fed592a4..5106341b5 100644 --- a/src/concurrent/concurrent_queue.hpp +++ b/src/concurrent/concurrent_queue.hpp @@ -57,7 +57,7 @@ class concurrent_queue { typedef T value_type; typedef concurrent_queue_node node_type; - ~concurrent_queue() { + virtual ~concurrent_queue() { // clear this queue while (_clear_when_destruct) { if (nullptr == pop_front()) { diff --git a/src/concurrent/executor_impl.hpp b/src/concurrent/executor_impl.hpp index 89b90dd7f..616eb9810 100644 --- a/src/concurrent/executor_impl.hpp +++ b/src/concurrent/executor_impl.hpp @@ -73,6 +73,7 @@ class thread_pool_executor : public abstract_executor_service { bool is_shutdown() override { return state_ != RUNNING; } std::size_t thread_nums() { return thread_nums_; } + void set_thread_nums(std::size_t thread_nums) { thread_nums_ = thread_nums; } protected: static const unsigned int ACCEPT_NEW_TASKS = 1U << 0U; diff --git a/src/consumer/AssignedMessageQueue.hpp b/src/consumer/AssignedMessageQueue.hpp new file mode 100644 index 000000000..92257282b --- /dev/null +++ b/src/consumer/AssignedMessageQueue.hpp @@ -0,0 +1,219 @@ +/* + * 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_CONSUMER_ASSIGNEDMESSAGEQUEUE_H_ +#define ROCKETMQ_CONSUMER_ASSIGNEDMESSAGEQUEUE_H_ + +#include // std::move, std::binary_search +#include // std::mutex + +#include "MQMessageQueue.h" +#include "ProcessQueue.h" +#include "RebalanceImpl.h" + +namespace rocketmq { + +class MessageQueueState { + public: + MessageQueueState(const MQMessageQueue& message_queue, ProcessQueuePtr process_queue) + : message_queue_(message_queue), + process_queue_(std::move(process_queue)), + paused_(false), + pull_offset_(-1), + consume_offset_(-1), + seek_offset_(-1) {} + + inline const MQMessageQueue& message_queue() const { return message_queue_; } + inline void set_message_queue(const MQMessageQueue message_queue) { message_queue_ = message_queue; } + + inline ProcessQueuePtr process_queue() const { return process_queue_; } + inline void process_queue(ProcessQueuePtr process_queue) { process_queue_ = std::move(process_queue); } + + inline bool is_paused() const { return paused_; } + inline void set_paused(bool paused) { paused_ = paused; } + + inline int64_t pull_offset() const { return pull_offset_; } + inline void set_pull_offset(int64_t pull_offset) { pull_offset_ = pull_offset; } + + inline int64_t consume_offset() const { return consume_offset_; } + inline void set_consume_offset(int64_t consume_offset) { consume_offset_ = consume_offset; } + + inline int64_t seek_offset() const { return seek_offset_; } + inline void set_seek_offset(int64_t seek_offset) { seek_offset_ = seek_offset; } + + private: + MQMessageQueue message_queue_; + ProcessQueuePtr process_queue_; + volatile bool paused_; + volatile int64_t pull_offset_; + volatile int64_t consume_offset_; + volatile int64_t seek_offset_; +}; + +class AssignedMessageQueue { + public: + std::vector messageQueues() { + std::vector mqs; + std::lock_guard lock(assigned_message_queue_state_mutex_); + for (const auto& it : assigned_message_queue_state_) { + mqs.push_back(it.first); + } + return mqs; + } + + bool isPaused(const MQMessageQueue& message_queue) { + std::lock_guard lock(assigned_message_queue_state_mutex_); + auto it = assigned_message_queue_state_.find(message_queue); + if (it != assigned_message_queue_state_.end()) { + auto& message_queue_state = it->second; + return message_queue_state.is_paused(); + } + return true; + } + + void pause(const std::vector& message_queues) { + std::lock_guard lock(assigned_message_queue_state_mutex_); + for (const auto& message_queue : message_queues) { + auto it = assigned_message_queue_state_.find(message_queue); + if (it != assigned_message_queue_state_.end()) { + auto& message_queue_state = it->second; + message_queue_state.set_paused(true); + } + } + } + + void resume(const std::vector& message_queues) { + std::lock_guard lock(assigned_message_queue_state_mutex_); + for (const auto& message_queue : message_queues) { + auto it = assigned_message_queue_state_.find(message_queue); + if (it != assigned_message_queue_state_.end()) { + auto& message_queue_state = it->second; + message_queue_state.set_paused(false); + } + } + } + + ProcessQueuePtr getProcessQueue(const MQMessageQueue& message_queue) { + std::lock_guard lock(assigned_message_queue_state_mutex_); + auto it = assigned_message_queue_state_.find(message_queue); + if (it != assigned_message_queue_state_.end()) { + auto& message_queue_state = it->second; + return message_queue_state.process_queue(); + } + return nullptr; + } + + int64_t getPullOffset(const MQMessageQueue& message_queue) { + std::lock_guard lock(assigned_message_queue_state_mutex_); + auto it = assigned_message_queue_state_.find(message_queue); + if (it != assigned_message_queue_state_.end()) { + auto& message_queue_state = it->second; + return message_queue_state.pull_offset(); + } + return -1; + } + + void updatePullOffset(const MQMessageQueue& message_queue, int64_t offset) { + std::lock_guard lock(assigned_message_queue_state_mutex_); + auto it = assigned_message_queue_state_.find(message_queue); + if (it != assigned_message_queue_state_.end()) { + auto& message_queue_state = it->second; + return message_queue_state.set_pull_offset(offset); + } + } + + int64_t getConsumerOffset(const MQMessageQueue& message_queue) { + std::lock_guard lock(assigned_message_queue_state_mutex_); + auto it = assigned_message_queue_state_.find(message_queue); + if (it != assigned_message_queue_state_.end()) { + auto& message_queue_state = it->second; + return message_queue_state.consume_offset(); + } + return -1; + } + + void updateConsumeOffset(const MQMessageQueue& message_queue, int64_t offset) { + std::lock_guard lock(assigned_message_queue_state_mutex_); + auto it = assigned_message_queue_state_.find(message_queue); + if (it != assigned_message_queue_state_.end()) { + auto& message_queue_state = it->second; + return message_queue_state.set_consume_offset(offset); + } + } + + int64_t getSeekOffset(const MQMessageQueue& message_queue) { + std::lock_guard lock(assigned_message_queue_state_mutex_); + auto it = assigned_message_queue_state_.find(message_queue); + if (it != assigned_message_queue_state_.end()) { + auto& message_queue_state = it->second; + return message_queue_state.seek_offset(); + } + return -1; + } + + void setSeekOffset(const MQMessageQueue& message_queue, int64_t offset) { + std::lock_guard lock(assigned_message_queue_state_mutex_); + auto it = assigned_message_queue_state_.find(message_queue); + if (it != assigned_message_queue_state_.end()) { + auto& message_queue_state = it->second; + return message_queue_state.set_seek_offset(offset); + } + } + + void updateAssignedMessageQueue(const std::string& topic, std::vector& assigned) { + std::sort(assigned.begin(), assigned.end()); + std::lock_guard lock(assigned_message_queue_state_mutex_); + for (auto it = assigned_message_queue_state_.begin(); it != assigned_message_queue_state_.end();) { + auto& mq = it->first; + if (mq.topic() == topic) { + if (!std::binary_search(assigned.begin(), assigned.end(), mq)) { + it = assigned_message_queue_state_.erase(it); + continue; + } + } + it++; + } + addAssignedMessageQueue(assigned); + } + + private: + void addAssignedMessageQueue(const std::vector& assigned) { + for (const auto& message_queue : assigned) { + if (assigned_message_queue_state_.find(message_queue) == assigned_message_queue_state_.end()) { + ProcessQueuePtr process_queue; + if (rebalance_impl_ != nullptr) { + process_queue = rebalance_impl_->getProcessQueue(message_queue); + } + if (nullptr == process_queue) { + process_queue.reset(new ProcessQueue()); + } + assigned_message_queue_state_.emplace(message_queue, MessageQueueState(message_queue, process_queue)); + } + } + } + + public: + inline void set_rebalance_impl(RebalanceImpl* rebalance_impl) { rebalance_impl_ = rebalance_impl; } + + private: + std::map assigned_message_queue_state_; + std::mutex assigned_message_queue_state_mutex_; + RebalanceImpl* rebalance_impl_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_CONSUMER_ASSIGNEDMESSAGEQUEUE_H_ diff --git a/src/consumer/DefaultLitePullConsumer.cpp b/src/consumer/DefaultLitePullConsumer.cpp new file mode 100644 index 000000000..1351ea470 --- /dev/null +++ b/src/consumer/DefaultLitePullConsumer.cpp @@ -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 "DefaultLitePullConsumer.h" + +#include "DefaultLitePullConsumerConfigImpl.hpp" +#include "DefaultLitePullConsumerImpl.h" +#include "UtilAll.h" + +namespace rocketmq { + +DefaultLitePullConsumer::DefaultLitePullConsumer(const std::string& groupname) + : DefaultLitePullConsumer(groupname, nullptr) {} + +DefaultLitePullConsumer::DefaultLitePullConsumer(const std::string& groupname, RPCHookPtr rpcHook) + : DefaultLitePullConsumerConfigProxy(std::make_shared()), + pull_consumer_impl_(nullptr) { + // set default group name + if (groupname.empty()) { + set_group_name(DEFAULT_CONSUMER_GROUP); + } else { + set_group_name(groupname); + } + + // create DefaultLitePullConsumerImpl + pull_consumer_impl_ = DefaultLitePullConsumerImpl::create(real_config(), rpcHook); +} + +DefaultLitePullConsumer::~DefaultLitePullConsumer() = default; + +void DefaultLitePullConsumer::start() { + pull_consumer_impl_->start(); +} + +void DefaultLitePullConsumer::shutdown() { + pull_consumer_impl_->shutdown(); +} + +bool DefaultLitePullConsumer::isAutoCommit() const { + return pull_consumer_impl_->isAutoCommit(); +} + +void DefaultLitePullConsumer::setAutoCommit(bool auto_commit) { + pull_consumer_impl_->setAutoCommit(auto_commit); +} + +void DefaultLitePullConsumer::subscribe(const std::string& topic, const std::string& subExpression) { + pull_consumer_impl_->subscribe(topic, subExpression); +} + +void DefaultLitePullConsumer::subscribe(const std::string& topic, const MessageSelector& selector) { + pull_consumer_impl_->subscribe(topic, selector); +} + +void DefaultLitePullConsumer::unsubscribe(const std::string& topic) { + pull_consumer_impl_->unsubscribe(topic); +} + +std::vector DefaultLitePullConsumer::poll() { + return pull_consumer_impl_->poll(); +} + +std::vector DefaultLitePullConsumer::poll(long timeout) { + return pull_consumer_impl_->poll(timeout); +} + +std::vector DefaultLitePullConsumer::fetchMessageQueues(const std::string& topic) { + return pull_consumer_impl_->fetchMessageQueues(topic); +} + +void DefaultLitePullConsumer::assign(const std::vector& messageQueues) { + pull_consumer_impl_->assign(messageQueues); +} + +void DefaultLitePullConsumer::seek(const MQMessageQueue& messageQueue, int64_t offset) { + pull_consumer_impl_->seek(messageQueue, offset); +} + +void DefaultLitePullConsumer::seekToBegin(const MQMessageQueue& messageQueue) { + pull_consumer_impl_->seekToBegin(messageQueue); +} + +void DefaultLitePullConsumer::seekToEnd(const MQMessageQueue& messageQueue) { + pull_consumer_impl_->seekToEnd(messageQueue); +} + +int64_t DefaultLitePullConsumer::offsetForTimestamp(const MQMessageQueue& messageQueue, int64_t timestamp) { + return pull_consumer_impl_->offsetForTimestamp(messageQueue, timestamp); +} + +void DefaultLitePullConsumer::pause(const std::vector& messageQueues) { + pull_consumer_impl_->pause(messageQueues); +} + +void DefaultLitePullConsumer::resume(const std::vector& messageQueues) { + pull_consumer_impl_->resume(messageQueues); +} + +void DefaultLitePullConsumer::commitSync() { + pull_consumer_impl_->commitSync(); +} + +int64_t DefaultLitePullConsumer::committed(const MQMessageQueue& messageQueue) { + return pull_consumer_impl_->committed(messageQueue); +} + +void DefaultLitePullConsumer::registerTopicMessageQueueChangeListener( + const std::string& topic, + TopicMessageQueueChangeListener* topicMessageQueueChangeListener) { + pull_consumer_impl_->registerTopicMessageQueueChangeListener(topic, topicMessageQueueChangeListener); +} + +void DefaultLitePullConsumer::setRPCHook(RPCHookPtr rpcHook) { + dynamic_cast(pull_consumer_impl_.get())->setRPCHook(rpcHook); +} + +} // namespace rocketmq diff --git a/src/consumer/DefaultLitePullConsumerConfigImpl.hpp b/src/consumer/DefaultLitePullConsumerConfigImpl.hpp new file mode 100644 index 000000000..ad41c5bb9 --- /dev/null +++ b/src/consumer/DefaultLitePullConsumerConfigImpl.hpp @@ -0,0 +1,150 @@ + +/* + * 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_CONSUMER_DEFAULTMQPUSHCONSUMERCONFIGIMPL_H_ +#define ROCKETMQ_CONSUMER_DEFAULTMQPUSHCONSUMERCONFIGIMPL_H_ + +#include // std::min +#include // std::thread::hardware_concurrency + +#include "AllocateMQAveragely.hpp" +#include "DefaultLitePullConsumerConfig.h" +#include "MQClientConfigImpl.hpp" + +namespace rocketmq { + +/** + * DefaultLitePullConsumerConfigImpl - implement for DefaultLitePullConsumerConfig + */ +class DefaultLitePullConsumerConfigImpl : virtual public DefaultLitePullConsumerConfig, public MQClientConfigImpl { + public: + DefaultLitePullConsumerConfigImpl() + : message_model_(MessageModel::CLUSTERING), + consume_from_where_(ConsumeFromWhere::CONSUME_FROM_LAST_OFFSET), + consume_timestamp_(UtilAll::to_string(UtilAll::currentTimeMillis() - (1000 * 60 * 30))), + auto_commit_interval_millis_(5 * 1000), + pull_batch_size_(10), + pull_thread_nums_(20), + long_polling_enable_(true), + consumer_pull_timeout_millis_(1000 * 10), + consumer_timeout_millis_when_suspend_(1000 * 30), + broker_suspend_max_time_millis_(1000 * 20), + pull_threshold_for_all_(10000), + pull_threshold_for_queue_(1000), + pull_time_delay_millis_when_exception_(1000), + poll_timeout_millis_(1000 * 5), + topic_metadata_check_interval_millis_(30 * 1000), + allocate_mq_strategy_(new AllocateMQAveragely()) {} + virtual ~DefaultLitePullConsumerConfigImpl() = default; + + MessageModel message_model() const override { return message_model_; } + void set_message_model(MessageModel messageModel) override { message_model_ = messageModel; } + + ConsumeFromWhere consume_from_where() const override { return consume_from_where_; } + void set_consume_from_where(ConsumeFromWhere consumeFromWhere) override { consume_from_where_ = consumeFromWhere; } + + const std::string& consume_timestamp() const override { return consume_timestamp_; } + void set_consume_timestamp(const std::string& consumeTimestamp) override { consume_timestamp_ = consumeTimestamp; } + + long auto_commit_interval_millis() const override { return auto_commit_interval_millis_; } + void set_auto_commit_interval_millis(long auto_commit_interval_millis) override { + auto_commit_interval_millis_ = auto_commit_interval_millis; + } + + int pull_batch_size() const override { return pull_batch_size_; } + void set_pull_batch_size(int pull_batch_size) override { pull_batch_size_ = pull_batch_size; } + + int pull_thread_nums() const override { return pull_thread_nums_; } + void set_pull_thread_nums(int pullThreadNums) override { pull_thread_nums_ = pullThreadNums; } + + bool long_polling_enable() const override { return long_polling_enable_; } + void set_long_polling_enable(bool long_polling_enable) override { long_polling_enable_ = long_polling_enable; } + + long consumer_pull_timeout_millis() const override { return consumer_pull_timeout_millis_; } + void set_consumer_pull_timeout_millis(long consumer_pull_timeout_millis) override { + consumer_pull_timeout_millis_ = consumer_pull_timeout_millis; + } + + long consumer_timeout_millis_when_suspend() const override { return consumer_timeout_millis_when_suspend_; } + void set_consumer_timeout_millis_when_suspend(long consumer_timeout_millis_when_suspend) override { + consumer_timeout_millis_when_suspend_ = consumer_timeout_millis_when_suspend; + } + + long broker_suspend_max_time_millis() const override { return broker_suspend_max_time_millis_; } + void set_broker_suspend_max_time_millis(long broker_suspend_max_time_millis) override { + broker_suspend_max_time_millis_ = broker_suspend_max_time_millis; + } + + long pull_threshold_for_all() const override { return pull_threshold_for_all_; } + void set_pull_threshold_for_all(long pull_threshold_for_all) override { + pull_threshold_for_all_ = pull_threshold_for_all; + } + + int pull_threshold_for_queue() const override { return pull_threshold_for_queue_; } + void set_pull_threshold_for_queue(int pull_threshold_for_queue) override { + pull_threshold_for_queue_ = pull_threshold_for_queue; + } + + long pull_time_delay_millis_when_exception() const override { return pull_time_delay_millis_when_exception_; } + void set_pull_time_delay_millis_when_exception(long pull_time_delay_millis_when_exception) override { + pull_time_delay_millis_when_exception_ = pull_time_delay_millis_when_exception; + } + + long poll_timeout_millis() const override { return poll_timeout_millis_; } + void set_poll_timeout_millis(long poll_timeout_millis) override { poll_timeout_millis_ = poll_timeout_millis; } + + long topic_metadata_check_interval_millis() const override { return topic_metadata_check_interval_millis_; } + void set_topic_metadata_check_interval_millis(long topicMetadataCheckIntervalMillis) override { + topic_metadata_check_interval_millis_ = topicMetadataCheckIntervalMillis; + } + + AllocateMQStrategy* allocate_mq_strategy() const override { return allocate_mq_strategy_.get(); } + void set_allocate_mq_strategy(AllocateMQStrategy* strategy) override { allocate_mq_strategy_.reset(strategy); } + + private: + MessageModel message_model_; + + ConsumeFromWhere consume_from_where_; + std::string consume_timestamp_; + + long auto_commit_interval_millis_; + + int pull_batch_size_; + + int pull_thread_nums_; + + bool long_polling_enable_; + + long consumer_pull_timeout_millis_; + long consumer_timeout_millis_when_suspend_; + long broker_suspend_max_time_millis_; + + long pull_threshold_for_all_; + int pull_threshold_for_queue_; + + long pull_time_delay_millis_when_exception_; // 1000 + + long poll_timeout_millis_; + + long topic_metadata_check_interval_millis_; + + std::unique_ptr allocate_mq_strategy_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_CONSUMER_DEFAULTMQPUSHCONSUMERCONFIGIMPL_H_ diff --git a/src/consumer/DefaultLitePullConsumerImpl.cpp b/src/consumer/DefaultLitePullConsumerImpl.cpp new file mode 100644 index 000000000..3a5fc8166 --- /dev/null +++ b/src/consumer/DefaultLitePullConsumerImpl.cpp @@ -0,0 +1,894 @@ +/* + * 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 "DefaultLitePullConsumerImpl.h" + +#ifndef WIN32 +#include +#endif + +#include "AssignedMessageQueue.hpp" +#include "FilterAPI.hpp" +#include "MQAdminImpl.h" +#include "MQClientAPIImpl.h" +#include "MQClientInstance.h" +#include "NamespaceUtil.h" +#include "LocalFileOffsetStore.h" +#include "PullAPIWrapper.h" +#include "PullSysFlag.h" +#include "RebalanceLitePullImpl.h" +#include "RemoteBrokerOffsetStore.h" +#include "UtilAll.h" +#include "Validators.h" + +static const long PULL_TIME_DELAY_MILLS_WHEN_PAUSE = 1000; +static const long PULL_TIME_DELAY_MILLS_WHEN_FLOW_CONTROL = 50; + +namespace rocketmq { + +class DefaultLitePullConsumerImpl::MessageQueueListenerImpl : public MessageQueueListener { + public: + MessageQueueListenerImpl(DefaultLitePullConsumerImplPtr pull_consumer) : default_lite_pull_consumer_(pull_consumer) {} + + ~MessageQueueListenerImpl() = default; + + void messageQueueChanged(const std::string& topic, + std::vector& mq_all, + std::vector& mq_divided) override { + auto consumer = default_lite_pull_consumer_.lock(); + if (nullptr == consumer) { + return; + } + switch (consumer->messageModel()) { + case BROADCASTING: + consumer->updateAssignedMessageQueue(topic, mq_all); + consumer->updatePullTask(topic, mq_all); + break; + case CLUSTERING: + consumer->updateAssignedMessageQueue(topic, mq_divided); + consumer->updatePullTask(topic, mq_divided); + break; + default: + break; + } + } + + private: + std::weak_ptr default_lite_pull_consumer_; +}; + +class DefaultLitePullConsumerImpl::ConsumeRequest { + public: + ConsumeRequest(std::vector&& message_exts, + const MQMessageQueue& message_queue, + ProcessQueuePtr process_queue) + : message_exts_(std::move(message_exts)), message_queue_(message_queue), process_queue_(process_queue) {} + + public: + std::vector& message_exts() { return message_exts_; } + + MQMessageQueue& message_queue() { return message_queue_; } + + ProcessQueuePtr process_queue() { return process_queue_; } + + private: + std::vector message_exts_; + MQMessageQueue message_queue_; + ProcessQueuePtr process_queue_; +}; + +class DefaultLitePullConsumerImpl::PullTaskImpl : public std::enable_shared_from_this { + public: + PullTaskImpl(DefaultLitePullConsumerImplPtr pull_consumer, const MQMessageQueue& message_queue) + : default_lite_pull_consumer_(pull_consumer), message_queue_(message_queue), cancelled_(false) {} + + void run() { + auto consumer = default_lite_pull_consumer_.lock(); + if (nullptr == consumer) { + LOG_WARN_NEW("PullTaskImpl::run: DefaultLitePullConsumerImpl is released."); + return; + } + + if (cancelled_) { + return; + } + + if (consumer->assigned_message_queue_->isPaused(message_queue_)) { + consumer->scheduled_thread_pool_executor_.schedule( + std::bind(&DefaultLitePullConsumerImpl::PullTaskImpl::run, shared_from_this()), + PULL_TIME_DELAY_MILLS_WHEN_PAUSE, time_unit::milliseconds); + LOG_DEBUG_NEW("Message Queue: {} has been paused!", message_queue_.toString()); + return; + } + + auto process_queue = consumer->assigned_message_queue_->getProcessQueue(message_queue_); + if (nullptr == process_queue || process_queue->dropped()) { + LOG_INFO_NEW("The message queue not be able to poll, because it's dropped. group={}, messageQueue={}", + consumer->groupName(), message_queue_.toString()); + return; + } + + auto config = consumer->getDefaultLitePullConsumerConfig(); + + if (consumer->consume_request_cache_.size() * config->pull_batch_size() > config->pull_threshold_for_all()) { + consumer->scheduled_thread_pool_executor_.schedule( + std::bind(&DefaultLitePullConsumerImpl::PullTaskImpl::run, shared_from_this()), + PULL_TIME_DELAY_MILLS_WHEN_FLOW_CONTROL, time_unit::milliseconds); + if ((consumer->consume_request_flow_control_times_++ % 1000) == 0) + LOG_WARN_NEW( + "The consume request count exceeds threshold {}, so do flow control, consume request count={}, " + "flowControlTimes={}", + config->pull_threshold_for_all(), consumer->consume_request_cache_.size(), + consumer->consume_request_flow_control_times_); + return; + } + + auto cached_message_count = process_queue->getCacheMsgCount(); + if (cached_message_count > config->pull_threshold_for_queue()) { + consumer->scheduled_thread_pool_executor_.schedule( + std::bind(&DefaultLitePullConsumerImpl::PullTaskImpl::run, shared_from_this()), + PULL_TIME_DELAY_MILLS_WHEN_FLOW_CONTROL, time_unit::milliseconds); + if ((consumer->queue_flow_control_times_++ % 1000) == 0) { + LOG_WARN_NEW( + "The cached message count exceeds the threshold {}, so do flow control, minOffset={}, maxOffset={}, " + "count={}, size={} MiB, flowControlTimes={}", + config->pull_threshold_for_queue(), process_queue->getCacheMinOffset(), process_queue->getCacheMaxOffset(), + cached_message_count, "unknown", consumer->queue_flow_control_times_); + } + return; + } + + // long cachedMessageSizeInMiB = processQueue->getMsgSize() / (1024 * 1024); + // if (cachedMessageSizeInMiB > consumer.getPullThresholdSizeForQueue()) { + // scheduledThreadPoolExecutor.schedule(this, PULL_TIME_DELAY_MILLS_WHEN_FLOW_CONTROL, TimeUnit.MILLISECONDS); + // if ((queueFlowControlTimes++ % 1000) == 0) { + // log.warn( + // "The cached message size exceeds the threshold {} MiB, so do flow control, minOffset={}, maxOffset={}, + // " + // "count={}, size={} MiB, flowControlTimes={}", + // consumer.getPullThresholdSizeForQueue(), processQueue.getMsgTreeMap().firstKey(), + // processQueue.getMsgTreeMap().lastKey(), cachedMessageCount, cachedMessageSizeInMiB, + // queueFlowControlTimes); + // } + // return; + // } + + // if (processQueue.getMaxSpan() > consumer.getConsumeMaxSpan()) { + // scheduledThreadPoolExecutor.schedule(this, PULL_TIME_DELAY_MILLS_WHEN_FLOW_CONTROL, TimeUnit.MILLISECONDS); + // if ((queueMaxSpanFlowControlTimes++ % 1000) == 0) { + // log.warn( + // "The queue's messages, span too long, so do flow control, minOffset={}, maxOffset={}, maxSpan={}, " + // "flowControlTimes={}", + // processQueue.getMsgTreeMap().firstKey(), processQueue.getMsgTreeMap().lastKey(), + // processQueue.getMaxSpan(), + // queueMaxSpanFlowControlTimes); + // } + // return; + // } + + auto offset = consumer->nextPullOffset(message_queue_); + long pull_delay_time_millis = 0; + SubscriptionData* subscription_data = nullptr; + try { + if (consumer->subscription_type_ == SubscriptionType::SUBSCRIBE) { + subscription_data = consumer->rebalance_impl_->getSubscriptionData(message_queue_.topic()); + } else { + subscription_data = FilterAPI::buildSubscriptionData(message_queue_.topic(), SUB_ALL); + } + + std::unique_ptr pull_result( + consumer->pull(message_queue_, subscription_data, offset, config->pull_batch_size())); + + switch (pull_result->pull_status()) { + case PullStatus::FOUND: { + auto objLock = consumer->message_queue_lock_.fetchLockObject(message_queue_); + std::lock_guard lock(*objLock); + if (!pull_result->msg_found_list().empty() && + consumer->assigned_message_queue_->getSeekOffset(message_queue_) == -1) { + process_queue->putMessage(pull_result->msg_found_list()); + consumer->submitConsumeRequest( + new ConsumeRequest(std::move(pull_result->msg_found_list()), message_queue_, process_queue)); + } + } break; + case PullStatus::OFFSET_ILLEGAL: + LOG_WARN_NEW("The pull request offset illegal, {}", pull_result->toString()); + break; + case PullStatus::NO_NEW_MSG: + case PullStatus::NO_MATCHED_MSG: + pull_delay_time_millis = 1000; + break; + case PullStatus::NO_LATEST_MSG: + pull_delay_time_millis = config->pull_time_delay_millis_when_exception(); + break; + default: + break; + } + + consumer->updatePullOffset(message_queue_, pull_result->next_begin_offset()); + } catch (std::exception& e) { + pull_delay_time_millis = config->pull_time_delay_millis_when_exception(); + LOG_ERROR_NEW("An error occurred in pull message process. {}", e.what()); + } + + if (consumer->subscription_type_ != SubscriptionType::SUBSCRIBE) { + delete subscription_data; + } + + if (!cancelled_) { + consumer->scheduled_thread_pool_executor_.schedule( + std::bind(&DefaultLitePullConsumerImpl::PullTaskImpl::run, shared_from_this()), pull_delay_time_millis, + time_unit::milliseconds); + } else { + LOG_WARN_NEW("The Pull Task is cancelled after doPullTask, {}", message_queue_.toString()); + } + } + + public: + inline const MQMessageQueue& message_queue() { return message_queue_; } + + inline bool is_cancelled() const { return cancelled_; } + inline void set_cancelled(bool cancelled) { cancelled_ = cancelled; } + + private: + std::weak_ptr default_lite_pull_consumer_; + MQMessageQueue message_queue_; + volatile bool cancelled_; +}; + +DefaultLitePullConsumerImpl::DefaultLitePullConsumerImpl(DefaultLitePullConsumerConfigPtr config) + : DefaultLitePullConsumerImpl(config, nullptr) {} + +DefaultLitePullConsumerImpl::DefaultLitePullConsumerImpl(DefaultLitePullConsumerConfigPtr config, RPCHookPtr rpcHook) + : MQClientImpl(config, rpcHook), + start_time_(UtilAll::currentTimeMillis()), + subscription_type_(SubscriptionType::NONE), + consume_request_flow_control_times_(0), + queue_flow_control_times_(0), + next_auto_commit_deadline_(-1LL), + auto_commit_(true), + message_queue_listener_(nullptr), + assigned_message_queue_(new AssignedMessageQueue()), + scheduled_thread_pool_executor_("PullMsgThread", config->pull_thread_nums(), false), + scheduled_executor_service_("MonitorMessageQueueChangeThread", false), + rebalance_impl_(new RebalanceLitePullImpl(this)), + pull_api_wrapper_(nullptr), + offset_store_(nullptr) {} + +DefaultLitePullConsumerImpl::~DefaultLitePullConsumerImpl() = default; + +void DefaultLitePullConsumerImpl::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 + + switch (service_state_) { + case CREATE_JUST: { + // wrap namespace + client_config_->set_group_name( + NamespaceUtil::wrapNamespace(client_config_->name_space(), client_config_->group_name())); + + LOG_INFO_NEW("the consumer [{}] start beginning.", client_config_->group_name()); + + service_state_ = START_FAILED; + + checkConfig(); + + if (messageModel() == MessageModel::CLUSTERING) { + client_config_->changeInstanceNameToPID(); + } + + // init client_instance_ + MQClientImpl::start(); + + // init rebalance_impl_ + rebalance_impl_->set_consumer_group(client_config_->group_name()); + rebalance_impl_->set_message_model(getDefaultLitePullConsumerConfig()->message_model()); + rebalance_impl_->set_allocate_mq_strategy(getDefaultLitePullConsumerConfig()->allocate_mq_strategy()); + rebalance_impl_->set_client_instance(client_instance_.get()); + + // init pull_api_wrapper_ + pull_api_wrapper_.reset(new PullAPIWrapper(client_instance_.get(), client_config_->group_name())); + // TODO: registerFilterMessageHook + + // init offset_store_ + switch (getDefaultLitePullConsumerConfig()->message_model()) { + case MessageModel::BROADCASTING: + offset_store_.reset(new LocalFileOffsetStore(client_instance_.get(), client_config_->group_name())); + break; + case MessageModel::CLUSTERING: + offset_store_.reset(new RemoteBrokerOffsetStore(client_instance_.get(), client_config_->group_name())); + break; + } + offset_store_->load(); + + scheduled_thread_pool_executor_.set_thread_nums(getDefaultLitePullConsumerConfig()->pull_thread_nums()); + scheduled_thread_pool_executor_.startup(); + scheduled_executor_service_.startup(); + + // register consumer + bool registerOK = client_instance_->registerConsumer(client_config_->group_name(), this); + if (!registerOK) { + service_state_ = CREATE_JUST; + THROW_MQEXCEPTION(MQClientException, "The cousumer group[" + client_config_->group_name() + + "] has been created before, specify another name please.", + -1); + } + + client_instance_->start(); + + startScheduleTask(); + + LOG_INFO_NEW("the consumer [{}] start OK", client_config_->group_name()); + service_state_ = RUNNING; + + operateAfterRunning(); + break; + } + case RUNNING: + case START_FAILED: + case SHUTDOWN_ALREADY: + THROW_MQEXCEPTION(MQClientException, "The PullConsumer service state not OK, maybe started once", -1); + break; + default: + break; + }; +} + +void DefaultLitePullConsumerImpl::checkConfig() { + const auto& groupname = client_config_->group_name(); + + // check consumerGroup + Validators::checkGroup(groupname); + + // consumerGroup + if (DEFAULT_CONSUMER_GROUP == groupname) { + THROW_MQEXCEPTION(MQClientException, + "consumerGroup can not equal " + DEFAULT_CONSUMER_GROUP + ", please specify another one.", -1); + } + + // messageModel + if (getDefaultLitePullConsumerConfig()->message_model() != BROADCASTING && + getDefaultLitePullConsumerConfig()->message_model() != CLUSTERING) { + THROW_MQEXCEPTION(MQClientException, "messageModel is valid", -1); + } + + // allocateMessageQueueStrategy + if (nullptr == getDefaultLitePullConsumerConfig()->allocate_mq_strategy()) { + THROW_MQEXCEPTION(MQClientException, "allocateMessageQueueStrategy is null", -1); + } + + // if (getDefaultLitePullConsumerConfig()->getConsumerTimeoutMillisWhenSuspend() < + // getDefaultLitePullConsumerConfig()->getBrokerSuspendMaxTimeMillis()) { + // THROW_MQEXCEPTION( + // MQClientException, + // "Long polling mode, the consumer consumerTimeoutMillisWhenSuspend must greater than + // brokerSuspendMaxTimeMillis", + // -1); + // } +} + +void DefaultLitePullConsumerImpl::startScheduleTask() { + scheduled_executor_service_.schedule( + std::bind(&DefaultLitePullConsumerImpl::fetchTopicMessageQueuesAndComparePeriodically, this), 1000 * 10, + time_unit::milliseconds); +} + +void DefaultLitePullConsumerImpl::fetchTopicMessageQueuesAndComparePeriodically() { + try { + fetchTopicMessageQueuesAndCompare(); + } catch (std::exception& e) { + LOG_ERROR_NEW("ScheduledTask fetchMessageQueuesAndCompare exception: {}", e.what()); + } + + // next round + scheduled_executor_service_.schedule( + std::bind(&DefaultLitePullConsumerImpl::fetchTopicMessageQueuesAndComparePeriodically, this), + getDefaultLitePullConsumerConfig()->topic_metadata_check_interval_millis(), time_unit::milliseconds); +} + +void DefaultLitePullConsumerImpl::fetchTopicMessageQueuesAndCompare() { + std::lock_guard lock(mutex_); // synchronized + for (const auto& it : topic_message_queue_change_listener_map_) { + const auto& topic = it.first; + auto* topic_message_queue_change_listener = it.second; + std::vector old_message_queues = message_queues_for_topic_[topic]; + std::vector new_message_queues = fetchMessageQueues(topic); + bool isChanged = !isSetEqual(new_message_queues, old_message_queues); + if (isChanged) { + message_queues_for_topic_[topic] = new_message_queues; + if (topic_message_queue_change_listener != nullptr) { + topic_message_queue_change_listener->onChanged(topic, new_message_queues); + } + } + } +} + +bool DefaultLitePullConsumerImpl::isSetEqual(std::vector& new_message_queues, + std::vector& old_message_queues) { + if (new_message_queues.size() != old_message_queues.size()) { + return false; + } + std::sort(new_message_queues.begin(), new_message_queues.end()); + std::sort(old_message_queues.begin(), old_message_queues.end()); + return new_message_queues == old_message_queues; +} + +void DefaultLitePullConsumerImpl::operateAfterRunning() { + // If subscribe function invoke before start function, then update topic subscribe info after initialization. + if (subscription_type_ == SubscriptionType::SUBSCRIBE) { + updateTopicSubscribeInfoWhenSubscriptionChanged(); + } + // If assign function invoke before start function, then update pull task after initialization. + else if (subscription_type_ == SubscriptionType::ASSIGN) { + auto message_queues = assigned_message_queue_->messageQueues(); + updateAssignPullTask(message_queues); + } + + for (const auto& it : topic_message_queue_change_listener_map_) { + const auto& topic = it.first; + auto messageQueues = fetchMessageQueues(topic); + message_queues_for_topic_[topic] = std::move(messageQueues); + } + // client_instance_->checkClientInBroker(); +} + +void DefaultLitePullConsumerImpl::updateTopicSubscribeInfoWhenSubscriptionChanged() { + auto& subTable = rebalance_impl_->getSubscriptionInner(); + for (const auto& it : subTable) { + const auto& topic = it.first; + bool ret = client_instance_->updateTopicRouteInfoFromNameServer(topic); + if (!ret) { + LOG_WARN_NEW("The topic:[{}] not exist", topic); + } + } +} + +void DefaultLitePullConsumerImpl::updateAssignPullTask(std::vector& mq_new_set) { + std::sort(mq_new_set.begin(), mq_new_set.end()); + std::lock_guard lock(task_table_mutex_); + for (auto it = task_table_.begin(); it != task_table_.end();) { + auto& mq = it->first; + if (!std::binary_search(mq_new_set.begin(), mq_new_set.end(), mq)) { + it->second->set_cancelled(true); + it = task_table_.erase(it); + continue; + } + it++; + } + startPullTask(mq_new_set); +} + +void DefaultLitePullConsumerImpl::shutdown() { + switch (service_state_) { + case CREATE_JUST: + break; + case RUNNING: + persistConsumerOffset(); + client_instance_->unregisterConsumer(client_config_->group_name()); + scheduled_thread_pool_executor_.shutdown(); + scheduled_executor_service_.shutdown(); + client_instance_->shutdown(); + rebalance_impl_->destroy(); + service_state_ = ServiceState::SHUTDOWN_ALREADY; + LOG_INFO_NEW("the consumer [{}] shutdown OK", client_config_->group_name()); + break; + default: + break; + } +} + +void DefaultLitePullConsumerImpl::subscribe(const std::string& topic, const std::string& subExpression) { + std::lock_guard lock(mutex_); // synchronized + try { + if (topic.empty()) { + THROW_MQEXCEPTION(MQClientException, "Topic can not be null or empty.", -1); + } + set_subscription_type(SubscriptionType::SUBSCRIBE); + auto* subscription_data = FilterAPI::buildSubscriptionData(topic, subExpression); + rebalance_impl_->setSubscriptionData(topic, subscription_data); + + message_queue_listener_.reset(new MessageQueueListenerImpl(shared_from_this())); + assigned_message_queue_->set_rebalance_impl(rebalance_impl_.get()); + + if (service_state_ == ServiceState::RUNNING) { + client_instance_->sendHeartbeatToAllBrokerWithLock(); + updateTopicSubscribeInfoWhenSubscriptionChanged(); + } + } catch (std::exception& e) { + THROW_MQEXCEPTION2(MQClientException, "subscribe exception", -1, std::make_exception_ptr(e)); + } +} + +void DefaultLitePullConsumerImpl::subscribe(const std::string& topic, const MessageSelector& selector) { + // TODO: +} + +void DefaultLitePullConsumerImpl::unsubscribe(const std::string& topic) { + // TODO: +} + +std::vector DefaultLitePullConsumerImpl::subscriptions() const { + std::vector result; + auto& subTable = rebalance_impl_->getSubscriptionInner(); + for (const auto& it : subTable) { + result.push_back(*(it.second)); + } + return result; +} + +void DefaultLitePullConsumerImpl::updateTopicSubscribeInfo(const std::string& topic, + std::vector& info) { + rebalance_impl_->setTopicSubscribeInfo(topic, info); +} + +void DefaultLitePullConsumerImpl::doRebalance() { + if (rebalance_impl_ != nullptr) { + rebalance_impl_->doRebalance(false); + } +} + +void DefaultLitePullConsumerImpl::updateAssignedMessageQueue(const std::string& topic, + std::vector& assigned_message_queue) { + assigned_message_queue_->updateAssignedMessageQueue(topic, assigned_message_queue); +} + +void DefaultLitePullConsumerImpl::updatePullTask(const std::string& topic, std::vector& mq_new_set) { + std::sort(mq_new_set.begin(), mq_new_set.end()); + std::lock_guard lock(task_table_mutex_); + for (auto it = task_table_.begin(); it != task_table_.end();) { + auto& mq = it->first; + if (mq.topic() == topic) { + // remove unnecessary PullTask + if (!std::binary_search(mq_new_set.begin(), mq_new_set.end(), mq)) { + it->second->set_cancelled(true); + it = task_table_.erase(it); + continue; + } + } + it++; + } + startPullTask(mq_new_set); +} + +void DefaultLitePullConsumerImpl::startPullTask(std::vector& mq_set) { + for (const auto& mq : mq_set) { + // add new PullTask + if (task_table_.find(mq) == task_table_.end()) { + auto pull_task = std::make_shared(shared_from_this(), mq); + task_table_.emplace(mq, pull_task); + scheduled_thread_pool_executor_.submit(std::bind(&PullTaskImpl::run, pull_task)); + } + } +} + +int64_t DefaultLitePullConsumerImpl::nextPullOffset(const MQMessageQueue& message_queue) { + int64_t offset = -1; + int64_t seek_offset = assigned_message_queue_->getSeekOffset(message_queue); + if (seek_offset != -1) { + offset = seek_offset; + assigned_message_queue_->updateConsumeOffset(message_queue, offset); + assigned_message_queue_->setSeekOffset(message_queue, -1); + } else { + offset = assigned_message_queue_->getPullOffset(message_queue); + if (offset == -1) { + offset = fetchConsumeOffset(message_queue); + } + } + return offset; +} + +int64_t DefaultLitePullConsumerImpl::fetchConsumeOffset(const MQMessageQueue& messageQueue) { + // checkServiceState(); + return rebalance_impl_->computePullFromWhere(messageQueue); +} + +PullResult* DefaultLitePullConsumerImpl::pull(const MQMessageQueue& mq, + SubscriptionData* subscription_data, + int64_t offset, + int max_nums) { + return pull(mq, subscription_data, offset, max_nums, + getDefaultLitePullConsumerConfig()->consumer_pull_timeout_millis()); +} + +PullResult* DefaultLitePullConsumerImpl::pull(const MQMessageQueue& mq, + SubscriptionData* subscription_data, + int64_t offset, + int max_nums, + long timeout) { + return pullSyncImpl(mq, subscription_data, offset, max_nums, + getDefaultLitePullConsumerConfig()->long_polling_enable(), timeout); +} + +PullResult* DefaultLitePullConsumerImpl::pullSyncImpl(const MQMessageQueue& mq, + SubscriptionData* subscription_data, + int64_t offset, + int max_nums, + bool block, + long timeout) { + if (offset < 0) { + THROW_MQEXCEPTION(MQClientException, "offset < 0", -1); + } + + if (max_nums <= 0) { + THROW_MQEXCEPTION(MQClientException, "maxNums <= 0", -1); + } + + int sysFlag = PullSysFlag::buildSysFlag(false, block, true, false, true); + + long timeoutMillis = block ? getDefaultLitePullConsumerConfig()->consumer_timeout_millis_when_suspend() : timeout; + + bool isTagType = ExpressionType::isTagType(subscription_data->expression_type()); + + std::unique_ptr pull_result(pull_api_wrapper_->pullKernelImpl( + mq, // mq + subscription_data->sub_string(), // subExpression + subscription_data->expression_type(), // expressionType + isTagType ? 0L : subscription_data->sub_version(), // subVersion + offset, // offset + max_nums, // maxNums + sysFlag, // sysFlag + 0, // commitOffset + getDefaultLitePullConsumerConfig()->broker_suspend_max_time_millis(), // brokerSuspendMaxTimeMillis + timeoutMillis, // timeoutMillis + CommunicationMode::SYNC, // communicationMode + nullptr)); // pullCallback + + return pull_api_wrapper_->processPullResult(mq, std::move(pull_result), subscription_data); +} + +void DefaultLitePullConsumerImpl::submitConsumeRequest(ConsumeRequest* consume_request) { + consume_request_cache_.push_back(consume_request); +} + +void DefaultLitePullConsumerImpl::updatePullOffset(const MQMessageQueue& message_queue, int64_t next_pull_offset) { + if (assigned_message_queue_->getSeekOffset(message_queue) == -1) { + assigned_message_queue_->updatePullOffset(message_queue, next_pull_offset); + } +} + +std::vector DefaultLitePullConsumerImpl::poll() { + return poll(getDefaultLitePullConsumerConfig()->poll_timeout_millis()); +} + +std::vector DefaultLitePullConsumerImpl::poll(long timeout) { + // checkServiceState(); + if (auto_commit_) { + maybeAutoCommit(); + } + + int64_t endTime = UtilAll::currentTimeMillis() + timeout; + + auto consume_request = consume_request_cache_.pop_front(timeout, time_unit::milliseconds); + if (endTime - UtilAll::currentTimeMillis() > 0) { + while (consume_request != nullptr && consume_request->process_queue()->dropped()) { + consume_request = consume_request_cache_.pop_front(); + if (endTime - UtilAll::currentTimeMillis() <= 0) { + break; + } + } + } + + if (consume_request != nullptr && !consume_request->process_queue()->dropped()) { + auto& messages = consume_request->message_exts(); + long offset = consume_request->process_queue()->removeMessage(messages); + assigned_message_queue_->updateConsumeOffset(consume_request->message_queue(), offset); + // If namespace not null , reset Topic without namespace. + resetTopic(messages); + return MQMessageExt::from_list(messages); + } + + return std::vector(); +} + +void DefaultLitePullConsumerImpl::maybeAutoCommit() { + auto now = UtilAll::currentTimeMillis(); + if (now >= next_auto_commit_deadline_) { + commitAll(); + next_auto_commit_deadline_ = now + getDefaultLitePullConsumerConfig()->auto_commit_interval_millis(); + } +} + +void DefaultLitePullConsumerImpl::resetTopic(std::vector& msg_list) { + if (msg_list.empty()) { + return; + } + + // If namespace not null , reset Topic without namespace. + const auto& name_space = getDefaultLitePullConsumerConfig()->name_space(); + if (!name_space.empty()) { + for (auto& message_ext : msg_list) { + message_ext->set_topic(NamespaceUtil::withoutNamespace(message_ext->topic(), name_space)); + } + } +} + +void DefaultLitePullConsumerImpl::commitAll() { + try { + std::vector message_queues = assigned_message_queue_->messageQueues(); + for (const auto& message_queue : message_queues) { + long consumer_offset = assigned_message_queue_->getConsumerOffset(message_queue); + if (consumer_offset != -1) { + auto process_queue = assigned_message_queue_->getProcessQueue(message_queue); + if (process_queue != nullptr && !process_queue->dropped()) { + updateConsumeOffset(message_queue, consumer_offset); + } + } + } + if (getDefaultLitePullConsumerConfig()->message_model() == MessageModel::BROADCASTING) { + offset_store_->persistAll(message_queues); + } + } catch (std::exception& e) { + LOG_ERROR_NEW("An error occurred when update consume offset Automatically."); + } +} + +void DefaultLitePullConsumerImpl::updateConsumeOffset(const MQMessageQueue& mq, int64_t offset) { + // checkServiceState(); + offset_store_->updateOffset(mq, offset, false); +} + +void DefaultLitePullConsumerImpl::persistConsumerOffset() { + if (isServiceStateOk()) { + std::vector allocated_mqs; + if (subscription_type_ == SubscriptionType::SUBSCRIBE) { + allocated_mqs = rebalance_impl_->getAllocatedMQ(); + } else if (subscription_type_ == SubscriptionType::ASSIGN) { + allocated_mqs = assigned_message_queue_->messageQueues(); + } + offset_store_->persistAll(allocated_mqs); + } +} + +std::vector DefaultLitePullConsumerImpl::fetchMessageQueues(const std::string& topic) { + std::vector result; + if (isServiceStateOk()) { + client_instance_->getMQAdminImpl()->fetchSubscribeMessageQueues(topic, result); + parseMessageQueues(result); + } + return result; +} + +void DefaultLitePullConsumerImpl::parseMessageQueues(std::vector& queueSet) { + const auto& name_space = client_config_->name_space(); + if (name_space.empty()) { + return; + } + for (auto& messageQueue : queueSet) { + auto user_topic = NamespaceUtil::withoutNamespace(messageQueue.topic(), name_space); + messageQueue.set_topic(user_topic); + } +} + +void DefaultLitePullConsumerImpl::assign(const std::vector& messageQueues) { + // TODO: +} + +void DefaultLitePullConsumerImpl::seek(const MQMessageQueue& messageQueue, int64_t offset) { + // TODO: +} + +void DefaultLitePullConsumerImpl::seekToBegin(const MQMessageQueue& message_queue) { + auto begin = minOffset(message_queue); + seek(message_queue, begin); +} + +void DefaultLitePullConsumerImpl::seekToEnd(const MQMessageQueue& message_queue) { + auto end = maxOffset(message_queue); + seek(message_queue, end); +} + +int64_t DefaultLitePullConsumerImpl::offsetForTimestamp(const MQMessageQueue& message_queue, int64_t timestamp) { + return searchOffset(message_queue, timestamp); +} + +void DefaultLitePullConsumerImpl::pause(const std::vector& message_queues) { + assigned_message_queue_->pause(message_queues); +} + +void DefaultLitePullConsumerImpl::resume(const std::vector& message_queues) { + assigned_message_queue_->resume(message_queues); +} + +void DefaultLitePullConsumerImpl::commitSync() { + commitAll(); +} + +int64_t DefaultLitePullConsumerImpl::committed(const MQMessageQueue& message_queue) { + // checkServiceState(); + auto offset = offset_store_->readOffset(message_queue, ReadOffsetType::MEMORY_FIRST_THEN_STORE); + if (offset == -2) { + THROW_MQEXCEPTION(MQClientException, "Fetch consume offset from broker exception", -1); + } + return offset; +} + +void DefaultLitePullConsumerImpl::registerTopicMessageQueueChangeListener( + const std::string& topic, + TopicMessageQueueChangeListener* topicMessageQueueChangeListener) { + std::lock_guard lock(mutex_); // synchronized + if (topic.empty() || nullptr == topicMessageQueueChangeListener) { + THROW_MQEXCEPTION(MQClientException, "Topic or listener is null", -1); + } + if (topic_message_queue_change_listener_map_.find(topic) != topic_message_queue_change_listener_map_.end()) { + LOG_WARN_NEW("Topic {} had been registered, new listener will overwrite the old one", topic); + } + + topic_message_queue_change_listener_map_[topic] = topicMessageQueueChangeListener; + if (service_state_ == ServiceState::RUNNING) { + auto messageQueues = fetchMessageQueues(topic); + message_queues_for_topic_[topic] = std::move(messageQueues); + } +} + +ConsumerRunningInfo* DefaultLitePullConsumerImpl::consumerRunningInfo() { + auto* info = new ConsumerRunningInfo(); + + info->setProperty(ConsumerRunningInfo::PROP_CONSUMER_START_TIMESTAMP, UtilAll::to_string(start_time_)); + + info->setSubscriptionSet(subscriptions()); + + auto processQueueTable = rebalance_impl_->getProcessQueueTable(); + for (const auto& it : processQueueTable) { + const auto& mq = it.first; + const auto& pq = it.second; + + ProcessQueueInfo pq_info; + pq_info.setCommitOffset(offset_store_->readOffset(mq, MEMORY_FIRST_THEN_STORE)); + pq->fillProcessQueueInfo(pq_info); + info->setMqTable(mq, pq_info); + } + + return info; +} + +bool DefaultLitePullConsumerImpl::isAutoCommit() const { + return auto_commit_; +} + +void DefaultLitePullConsumerImpl::setAutoCommit(bool auto_commit) { + auto_commit_ = auto_commit; +} + +const std::string& DefaultLitePullConsumerImpl::groupName() const { + return client_config_->group_name(); +} + +MessageModel DefaultLitePullConsumerImpl::messageModel() const { + return getDefaultLitePullConsumerConfig()->message_model(); +}; + +ConsumeType DefaultLitePullConsumerImpl::consumeType() const { + return CONSUME_ACTIVELY; +} + +ConsumeFromWhere DefaultLitePullConsumerImpl::consumeFromWhere() const { + return getDefaultLitePullConsumerConfig()->consume_from_where(); +} + +void DefaultLitePullConsumerImpl::set_subscription_type(SubscriptionType subscription_type) { + if (subscription_type_ == SubscriptionType::NONE) { + subscription_type_ = subscription_type; + } else if (subscription_type_ != subscription_type) { + THROW_MQEXCEPTION(MQClientException, "Subscribe and assign are mutually exclusive.", -1); + } +} + +} // namespace rocketmq diff --git a/src/consumer/DefaultLitePullConsumerImpl.h b/src/consumer/DefaultLitePullConsumerImpl.h new file mode 100755 index 000000000..6923799cf --- /dev/null +++ b/src/consumer/DefaultLitePullConsumerImpl.h @@ -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. + */ +#ifndef ROCKETMQ_DEFAULTLITEPULLCONSUMERIMPL_H_ +#define ROCKETMQ_DEFAULTLITEPULLCONSUMERIMPL_H_ + +#include // std::shared_ptr +#include // std::mutex +#include // std::string + +#include "concurrent/blocking_queue.hpp" +#include "concurrent/executor.hpp" +#include "DefaultLitePullConsumer.h" +#include "MessageQueueListener.h" +#include "MessageQueueLock.hpp" +#include "MQClientImpl.h" +#include "MQConsumerInner.h" +#include "TopicMessageQueueChangeListener.h" + +namespace rocketmq { + +class AssignedMessageQueue; +class OffsetStore; +class PullAPIWrapper; +class PullResult; +class RebalanceImpl; + +class DefaultLitePullConsumerImpl; +typedef std::shared_ptr DefaultLitePullConsumerImplPtr; + +enum SubscriptionType { NONE, SUBSCRIBE, ASSIGN }; + +class DefaultLitePullConsumerImpl : public std::enable_shared_from_this, + public LitePullConsumer, + public MQClientImpl, + public MQConsumerInner { + private: + class MessageQueueListenerImpl; + class ConsumeRequest; + class PullTaskImpl; + + public: + /** + * create() - Factory method for DefaultLitePullConsumerImpl, used to ensure that all objects of + * DefaultLitePullConsumerImpl are managed by std::share_ptr + */ + static DefaultLitePullConsumerImplPtr create(DefaultLitePullConsumerConfigPtr config, RPCHookPtr rpcHook = nullptr) { + if (nullptr == rpcHook) { + return DefaultLitePullConsumerImplPtr(new DefaultLitePullConsumerImpl(config)); + } else { + return DefaultLitePullConsumerImplPtr(new DefaultLitePullConsumerImpl(config, rpcHook)); + } + } + + private: + DefaultLitePullConsumerImpl(DefaultLitePullConsumerConfigPtr config); + DefaultLitePullConsumerImpl(DefaultLitePullConsumerConfigPtr config, RPCHookPtr rpcHook); + + public: + virtual ~DefaultLitePullConsumerImpl(); + + public: // LitePullConsumer + void start() override; + void shutdown() override; + + bool isAutoCommit() const override; + void setAutoCommit(bool auto_commit) override; + + void subscribe(const std::string& topic, const std::string& subExpression) override; + void subscribe(const std::string& topic, const MessageSelector& selector) override; + + void unsubscribe(const std::string& topic) override; + + std::vector poll() override; + std::vector poll(long timeout) override; + + std::vector fetchMessageQueues(const std::string& topic) override; + + void assign(const std::vector& messageQueues) override; + + void seek(const MQMessageQueue& messageQueue, int64_t offset) override; + void seekToBegin(const MQMessageQueue& messageQueue) override; + void seekToEnd(const MQMessageQueue& messageQueue) override; + + int64_t offsetForTimestamp(const MQMessageQueue& messageQueue, int64_t timestamp) override; + + void pause(const std::vector& messageQueues) override; + void resume(const std::vector& messageQueues) override; + + void commitSync() override; + + int64_t committed(const MQMessageQueue& messageQueue) override; + + void registerTopicMessageQueueChangeListener( + const std::string& topic, + TopicMessageQueueChangeListener* topicMessageQueueChangeListener) override; + + public: // MQConsumerInner + const std::string& groupName() const override; + MessageModel messageModel() const override; + ConsumeType consumeType() const override; + ConsumeFromWhere consumeFromWhere() const override; + + std::vector subscriptions() const override; + + // service discovery + void updateTopicSubscribeInfo(const std::string& topic, std::vector& info) override; + + // load balancing + void doRebalance() override; + + // offset persistence + void persistConsumerOffset() override; + + ConsumerRunningInfo* consumerRunningInfo() override; + + private: + void checkConfig(); + void startScheduleTask(); + void operateAfterRunning(); + + void fetchTopicMessageQueuesAndComparePeriodically(); + void fetchTopicMessageQueuesAndCompare(); + + bool isSetEqual(std::vector& newMessageQueues, std::vector& oldMessageQueues); + + void updateTopicSubscribeInfoWhenSubscriptionChanged(); + + void updateAssignPullTask(std::vector& mqNewSet); + + void updateAssignedMessageQueue(const std::string& topic, std::vector& assignedMessageQueue); + void updatePullTask(const std::string& topic, std::vector& mqNewSet); + + void startPullTask(std::vector& mqSet); + + int64_t nextPullOffset(const MQMessageQueue& messageQueue); + int64_t fetchConsumeOffset(const MQMessageQueue& messageQueue); + + PullResult* pull(const MQMessageQueue& mq, SubscriptionData* subscription_data, int64_t offset, int max_nums); + PullResult* pull(const MQMessageQueue& mq, + SubscriptionData* subscription_data, + int64_t offset, + int max_nums, + long timeout); + PullResult* pullSyncImpl(const MQMessageQueue& mq, + SubscriptionData* subscription_data, + int64_t offset, + int max_nums, + bool block, + long timeout); + + void submitConsumeRequest(ConsumeRequest* consume_request); + + void updatePullOffset(const MQMessageQueue& messageQueue, int64_t nextPullOffset); + + void maybeAutoCommit(); + + void resetTopic(std::vector& msg_list); + + void commitAll(); + + void updateConsumeOffset(const MQMessageQueue& mq, int64_t offset); + + void parseMessageQueues(std::vector& queueSet); + + public: + inline MessageQueueListener* getMessageQueueListener() const { return message_queue_listener_.get(); } + + inline OffsetStore* getOffsetStore() const { return offset_store_.get(); } + + inline DefaultLitePullConsumerConfig* getDefaultLitePullConsumerConfig() const { + return dynamic_cast(client_config_.get()); + } + + private: + void set_subscription_type(SubscriptionType subscription_type); + + private: + std::mutex mutex_; + + uint64_t start_time_; + + SubscriptionType subscription_type_; + + long consume_request_flow_control_times_; + long queue_flow_control_times_; + + int64_t next_auto_commit_deadline_; + + bool auto_commit_; + + std::unique_ptr message_queue_listener_; + + std::map topic_message_queue_change_listener_map_; + std::map> message_queues_for_topic_; + + std::unique_ptr assigned_message_queue_; + MessageQueueLock message_queue_lock_; + + std::map> task_table_; + std::mutex task_table_mutex_; + + blocking_queue consume_request_cache_; + + scheduled_thread_pool_executor scheduled_thread_pool_executor_; + scheduled_thread_pool_executor scheduled_executor_service_; + + std::unique_ptr rebalance_impl_; + std::unique_ptr pull_api_wrapper_; + std::unique_ptr offset_store_; +}; + +} // namespace rocketmq + +#endif // ROCKETMQ_DEFAULTLITEPULLCONSUMERIMPL_H_ diff --git a/src/consumer/DefaultMQPullConsumer.cpp b/src/consumer/DefaultMQPullConsumer.cpp deleted file mode 100644 index 166ed6913..000000000 --- a/src/consumer/DefaultMQPullConsumer.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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 "UtilAll.h" - -namespace rocketmq { - -DefaultMQPullConsumer::DefaultMQPullConsumer(const std::string& groupname) - : DefaultMQPullConsumer(groupname, nullptr) {} - -DefaultMQPullConsumer::DefaultMQPullConsumer(const std::string& groupname, RPCHookPtr rpcHook) - : DefaultMQPullConsumerConfigProxy(nullptr), m_pullConsumerDelegate(nullptr) { - // set default group name - if (groupname.empty()) { - set_group_name(DEFAULT_CONSUMER_GROUP); - } else { - set_group_name(groupname); - } - - // TODO: DefaultMQPullConsumerImpl -} - -DefaultMQPullConsumer::~DefaultMQPullConsumer() = default; - -void DefaultMQPullConsumer::start() { - m_pullConsumerDelegate->start(); -} - -void DefaultMQPullConsumer::shutdown() { - m_pullConsumerDelegate->shutdown(); -} - -bool DefaultMQPullConsumer::sendMessageBack(MessageExtPtr msg, int delayLevel) { - return m_pullConsumerDelegate->sendMessageBack(msg, delayLevel); -} - -bool DefaultMQPullConsumer::sendMessageBack(MessageExtPtr msg, int delayLevel, const std::string& brokerName) { - return m_pullConsumerDelegate->sendMessageBack(msg, delayLevel, brokerName); -} - -void DefaultMQPullConsumer::fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) { - m_pullConsumerDelegate->fetchMessageQueuesInBalance(topic, mqs); -} - -void DefaultMQPullConsumer::registerMessageQueueListener(const std::string& topic, MQueueListener* listener) { - m_pullConsumerDelegate->registerMessageQueueListener(topic, listener); -} - -PullResult DefaultMQPullConsumer::pull(const MQMessageQueue& mq, - const std::string& subExpression, - int64_t offset, - int maxNums) { - return m_pullConsumerDelegate->pull(mq, subExpression, offset, maxNums); -} - -void DefaultMQPullConsumer::pull(const MQMessageQueue& mq, - const std::string& subExpression, - int64_t offset, - int maxNums, - PullCallback* pullCallback) { - m_pullConsumerDelegate->pull(mq, subExpression, offset, maxNums, pullCallback); -} - -PullResult DefaultMQPullConsumer::pullBlockIfNotFound(const MQMessageQueue& mq, - const std::string& subExpression, - int64_t offset, - int maxNums) { - return m_pullConsumerDelegate->pullBlockIfNotFound(mq, subExpression, offset, maxNums); -} - -void DefaultMQPullConsumer::pullBlockIfNotFound(const MQMessageQueue& mq, - const std::string& subExpression, - int64_t offset, - int maxNums, - PullCallback* pullCallback) { - m_pullConsumerDelegate->pullBlockIfNotFound(mq, subExpression, offset, maxNums, pullCallback); -} - -void DefaultMQPullConsumer::updateConsumeOffset(const MQMessageQueue& mq, int64_t offset) { - m_pullConsumerDelegate->updateConsumeOffset(mq, offset); -} - -int64_t DefaultMQPullConsumer::fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore) { - return m_pullConsumerDelegate->fetchConsumeOffset(mq, fromStore); -} - -void DefaultMQPullConsumer::fetchMessageQueuesInBalance(const std::string& topic, std::vector& mqs) { - m_pullConsumerDelegate->fetchMessageQueuesInBalance(topic, mqs); -} - -void DefaultMQPullConsumer::setRPCHook(RPCHookPtr rpcHook) { - // dynamic_cast(m_pullConsumerDelegate.get())->setRPCHook(rpcHook); -} - -} // namespace rocketmq diff --git a/src/consumer/DefaultMQPullConsumerImpl.cpp b/src/consumer/DefaultMQPullConsumerImpl.cpp deleted file mode 100644 index 78845cf51..000000000 --- a/src/consumer/DefaultMQPullConsumerImpl.cpp +++ /dev/null @@ -1,375 +0,0 @@ -// /* -// * 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" - -// #ifndef WIN32 -// #include -// #endif - -// #include "AllocateMQAveragely.h" -// #include "CommunicationMode.h" -// #include "FilterAPI.h" -// #include "Logging.h" -// #include "MQAdminImpl.h" -// #include "MQClientAPIImpl.h" -// #include "MQClientInstance.h" -// #include "MQClientManager.h" -// #include "MQProtos.h" -// #include "OffsetStore.h" -// #include "PullAPIWrapper.h" -// #include "PullSysFlag.h" -// #include "RebalanceImpl.h" -// #include "Validators.h" - -// namespace rocketmq { - -// DefaultMQPullConsumer::DefaultMQPullConsumer(const string& groupname) : DefaultMQPullConsumer(groupname, nullptr) {} - -// DefaultMQPullConsumer::DefaultMQPullConsumer(const string& groupname, RPCHookPtr rpcHook) -// : MQClient(rpcHook), -// m_rebalanceImpl(new RebalancePullImpl(this)), -// m_pullAPIWrapper(nullptr), -// m_offsetStore(nullptr), -// m_messageQueueListener(nullptr) { -// // set default group name -// if (groupname.empty()) { -// setGroupName(DEFAULT_CONSUMER_GROUP); -// } else { -// setGroupName(groupname); -// } -// } - -// DefaultMQPullConsumer::~DefaultMQPullConsumer() = default; - -// void DefaultMQPullConsumer::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 -// switch (m_serviceState) { -// case CREATE_JUST: { -// m_serviceState = START_FAILED; - -// // data -// checkConfig(); - -// copySubscription(); - -// if (getMessageModel() == CLUSTERING) { -// changeInstanceNameToPID(); -// } - -// MQClient::start(); -// LOG_INFO_NEW("DefaultMQPullConsumer:{} start", getGroupName()); - -// // reset rebalance; -// m_rebalanceImpl->setConsumerGroup(getGroupName()); -// m_rebalanceImpl->setMessageModel(getMessageModel()); -// m_rebalanceImpl->setAllocateMQStrategy(getAllocateMQStrategy()); -// m_rebalanceImpl->setMQClientFactory(m_clientInstance.get()); - -// m_pullAPIWrapper.reset(new PullAPIWrapper(m_clientInstance.get(), getGroupName())); - -// // msg model -// switch (getMessageModel()) { -// case BROADCASTING: -// m_offsetStore.reset(new LocalFileOffsetStore(m_clientInstance.get(), getGroupName())); -// break; -// case CLUSTERING: -// m_offsetStore.reset(new RemoteBrokerOffsetStore(m_clientInstance.get(), getGroupName())); -// break; -// } -// m_offsetStore->load(); - -// // register consumer -// bool registerOK = m_clientInstance->registerConsumer(getGroupName(), this); -// if (!registerOK) { -// m_serviceState = CREATE_JUST; -// THROW_MQEXCEPTION( -// MQClientException, -// "The cousumer group[" + getGroupName() + "] has been created before, specify another name please.", -1); -// } - -// m_clientInstance->start(); -// LOG_INFO_NEW("the consumer [{}] start OK", getGroupName()); -// m_serviceState = RUNNING; -// break; -// } -// case RUNNING: -// case START_FAILED: -// case SHUTDOWN_ALREADY: -// break; -// default: -// break; -// } -// } - -// void DefaultMQPullConsumer::shutdown() { -// switch (m_serviceState) { -// case RUNNING: { -// LOG_INFO("DefaultMQPullConsumer:%s shutdown", m_groupName.c_str()); -// persistConsumerOffset(); -// m_clientInstance->unregisterConsumer(getGroupName()); -// m_clientInstance->shutdown(); -// m_serviceState = SHUTDOWN_ALREADY; -// break; -// } -// case SHUTDOWN_ALREADY: -// case CREATE_JUST: -// break; -// default: -// break; -// } -// } - -// bool DefaultMQPullConsumer::sendMessageBack(MQMessageExt& msg, int delayLevel) { -// return false; -// } - -// void DefaultMQPullConsumer::fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) { -// mqs.clear(); -// try { -// m_clientInstance->getMQAdminImpl()->fetchSubscribeMessageQueues(topic, mqs); -// } catch (MQException& e) { -// LOG_ERROR(e.what()); -// } -// } - -// void DefaultMQPullConsumer::updateTopicSubscribeInfo(const std::string& topic, std::vector& info) {} - -// void DefaultMQPullConsumer::registerMessageQueueListener(const std::string& topic, MQueueListener* listener) { -// m_registerTopics.insert(topic); -// if (listener != nullptr) { -// m_messageQueueListener = listener; -// } -// } - -// PullResult DefaultMQPullConsumer::pull(const MQMessageQueue& mq, -// const std::string& subExpression, -// int64_t offset, -// int maxNums) { -// return pullSyncImpl(mq, subExpression, offset, maxNums, false); -// } - -// void DefaultMQPullConsumer::pull(const MQMessageQueue& mq, -// const std::string& subExpression, -// int64_t offset, -// int maxNums, -// PullCallback* pPullCallback) { -// pullAsyncImpl(mq, subExpression, offset, maxNums, false, pPullCallback); -// } - -// PullResult DefaultMQPullConsumer::pullBlockIfNotFound(const MQMessageQueue& mq, -// const std::string& subExpression, -// int64_t offset, -// int maxNums) { -// return pullSyncImpl(mq, subExpression, offset, maxNums, true); -// } - -// void DefaultMQPullConsumer::pullBlockIfNotFound(const MQMessageQueue& mq, -// const std::string& subExpression, -// int64_t offset, -// int maxNums, -// PullCallback* pPullCallback) { -// pullAsyncImpl(mq, subExpression, offset, maxNums, true, pPullCallback); -// } - -// PullResult DefaultMQPullConsumer::pullSyncImpl(const MQMessageQueue& mq, -// const std::string& subExpression, -// int64_t 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 -// std::unique_ptr pSData(FilterAPI::buildSubscriptionData(mq.getTopic(), subExpression)); - -// int timeoutMillis = block ? 1000 * 30 : 1000 * 10; - -// try { -// std::unique_ptr pullResult(m_pullAPIWrapper->pullKernelImpl(mq, // 1 -// pSData->getSubString(), // 2 -// 0L, // 3 -// offset, // 4 -// maxNums, // 5 -// sysFlag, // 6 -// 0, // 7 -// 1000 * 20, // 8 -// timeoutMillis, // 9 -// ComMode_SYNC, // 10 -// nullptr)); // callback -// assert(pullResult != nullptr); -// return m_pullAPIWrapper->processPullResult(mq, *pullResult, pSData.get()); -// } catch (MQException& e) { -// LOG_ERROR(e.what()); -// } -// return PullResult(BROKER_TIMEOUT); -// } - -// void DefaultMQPullConsumer::pullAsyncImpl(const MQMessageQueue& mq, -// const std::string& subExpression, -// int64_t 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 -// std::unique_ptr pSData(FilterAPI::buildSubscriptionData(mq.getTopic(), subExpression)); - -// int timeoutMillis = block ? 1000 * 30 : 1000 * 10; - -// try { -// std::unique_ptr pullResult(m_pullAPIWrapper->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)); -// } catch (MQException& e) { -// LOG_ERROR(e.what()); -// } -// } - -// void DefaultMQPullConsumer::subscriptionAutomatically(const std::string& topic) { -// SubscriptionData* pSdata = m_rebalanceImpl->getSubscriptionData(topic); -// if (pSdata == nullptr) { -// std::unique_ptr subscriptionData(FilterAPI::buildSubscriptionData(topic, SUB_ALL)); -// m_rebalanceImpl->setSubscriptionData(topic, subscriptionData.release()); -// } -// } - -// void DefaultMQPullConsumer::updateConsumeOffset(const MQMessageQueue& mq, int64_t offset) { -// m_offsetStore->updateOffset(mq, offset, false); -// } - -// void DefaultMQPullConsumer::removeConsumeOffset(const MQMessageQueue& mq) { -// m_offsetStore->removeOffset(mq); -// } - -// int64_t DefaultMQPullConsumer::fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore) { -// return m_offsetStore->readOffset(mq, fromStore ? READ_FROM_STORE : MEMORY_FIRST_THEN_STORE); -// } - -// void DefaultMQPullConsumer::persistConsumerOffset() { -// /*As do not execute rebalance for pullConsumer now, requestTable is always -// empty -// map requestTable = -// m_pRebalance->getPullRequestTable(); -// map::iterator it = requestTable.begin(); -// vector mqs; -// for (; it != requestTable.end(); ++it) -// { -// if (it->second) -// { -// mqs.push_back(it->first); -// } -// } -// m_pOffsetStore->persistAll(mqs);*/ -// } - -// void DefaultMQPullConsumer::persistConsumerOffset4PullConsumer(const MQMessageQueue& mq) { -// if (isServiceStateOk()) { -// m_offsetStore->persist(mq); -// } -// } - -// void DefaultMQPullConsumer::fetchMessageQueuesInBalance(const std::string& topic, std::vector& mqs) -// {} - -// void DefaultMQPullConsumer::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 DefaultMQPullConsumer::doRebalance() {} - -// void DefaultMQPullConsumer::copySubscription() { -// std::set::iterator it = m_registerTopics.begin(); -// for (; it != m_registerTopics.end(); ++it) { -// std::unique_ptr subscriptionData(FilterAPI::buildSubscriptionData((*it), SUB_ALL)); -// m_rebalanceImpl->setSubscriptionData((*it), subscriptionData.release()); -// } -// } - -// std::string DefaultMQPullConsumer::groupName() const { -// return getGroupName(); -// } - -// MessageModel DefaultMQPullConsumer::messageModel() const { -// return getMessageModel(); -// } - -// ConsumeType DefaultMQPullConsumer::consumeType() const { -// return CONSUME_ACTIVELY; -// } - -// ConsumeFromWhere DefaultMQPullConsumer::consumeFromWhere() const { -// return CONSUME_FROM_LAST_OFFSET; -// } - -// std::vector DefaultMQPullConsumer::subscriptions() const { -// std::vector result; -// std::set::iterator it = m_registerTopics.begin(); -// for (; it != m_registerTopics.end(); ++it) { -// SubscriptionData ms(*it, SUB_ALL); -// result.push_back(ms); -// } -// return result; -// } - -// } // namespace rocketmq diff --git a/src/consumer/DefaultMQPullConsumerImpl.h b/src/consumer/DefaultMQPullConsumerImpl.h deleted file mode 100755 index dc39eb4d4..000000000 --- a/src/consumer/DefaultMQPullConsumerImpl.h +++ /dev/null @@ -1,173 +0,0 @@ -// /* -// * 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 __DEFAULT_MQ_PULL_CONSUMER_IMPL_H__ -// #define __DEFAULT_MQ_PULL_CONSUMER_IMPL_H__ - -// #include -// #include - -// #include "AllocateMQStrategy.h" -// #include "MQClientConfig.h" -// #include "MQConsumer.h" -// #include "MQueueListener.h" - -// namespace rocketmq { - -// class RebalanceImpl; -// class SubscriptionData; -// class OffsetStore; -// class PullAPIWrapper; - -// class ROCKETMQCLIENT_API DefaultMQPullConsumer : public MQPullConsumer, -// public MQClientImpl, -// public DefaultMQPullConsumerConfig { -// public: -// DefaultMQPullConsumer(const std::string& groupname); -// DefaultMQPullConsumer(const std::string& groupname, RPCHookPtr rpcHook); -// virtual ~DefaultMQPullConsumer(); - -// public: // MQClient -// void start() override; -// void shutdown() override; - -// public: // MQConsumer -// bool sendMessageBack(MQMessageExt& msg, int delayLevel) override; -// void fetchSubscribeMessageQueues(const std::string& topic, std::vector& mqs) override; - -// std::string groupName() const override; -// MessageModel messageModel() const override; -// ConsumeType consumeType() const override; -// ConsumeFromWhere consumeFromWhere() const override; -// std::vector subscriptions() const override; - -// void doRebalance() override; -// void persistConsumerOffset() override; -// void updateTopicSubscribeInfo(const std::string& topic, std::vector& info) override; -// ConsumerRunningInfo* consumerRunningInfo() override { return nullptr; } - -// public: // MQPullConsumer -// void pull(const MQMessageQueue& mq, -// const std::string& subExpression, -// int64_t offset, -// int maxNums, -// PullCallback* pullCallback) override; - -// /** -// * pull msg 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 -// * accroding to PullResult -// */ -// PullResult pull(const MQMessageQueue& mq, const std::string& subExpression, int64_t offset, int maxNums) override; - -// virtual void updateConsumeOffset(const MQMessageQueue& mq, int64_t offset); -// virtual void removeConsumeOffset(const MQMessageQueue& mq); - -// void registerMessageQueueListener(const std::string& topic, MQueueListener* pListener); - -// /** -// * 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_t offset, -// int maxNums); - -// void pullBlockIfNotFound(const MQMessageQueue& mq, -// const std::string& subExpression, -// int64_t offset, -// int maxNums, -// PullCallback* pullCallback); - -// /** -// * Fetch the offset -// * -// * @param mq -// * @param fromStore -// * @return -// */ -// int64_t fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore); - -// /** -// * Fetch the message queues according to the topic -// * -// * @param topic Message Topic -// * @return -// */ -// void fetchMessageQueuesInBalance(const std::string& topic, std::vector& mqs); - -// // temp persist consumer offset interface, only valid with -// // RemoteBrokerOffsetStore, updateConsumeOffset should be called before. -// void persistConsumerOffset4PullConsumer(const MQMessageQueue& mq); - -// public: -// OffsetStore* getOffsetStore() const { return m_offsetStore.get(); } - -// private: -// void checkConfig(); -// void copySubscription(); - -// PullResult pullSyncImpl(const MQMessageQueue& mq, -// const std::string& subExpression, -// int64_t offset, -// int maxNums, -// bool block); - -// void pullAsyncImpl(const MQMessageQueue& mq, -// const std::string& subExpression, -// int64_t offset, -// int maxNums, -// bool block, -// PullCallback* pPullCallback); - -// void subscriptionAutomatically(const std::string& topic); - -// private: -// std::set m_registerTopics; - -// std::unique_ptr m_rebalanceImpl; -// std::unique_ptr m_pullAPIWrapper; -// std::unique_ptr m_offsetStore; -// MQueueListener* m_messageQueueListener; -// }; - -// } // namespace rocketmq - -// #endif // __DEFAULT_MQ_PULL_CONSUMER_IMPL_H__ diff --git a/include/MQueueListener.h b/src/consumer/MessageQueueListener.h similarity index 80% rename from include/MQueueListener.h rename to src/consumer/MessageQueueListener.h index 11842aa1f..be65c3b60 100644 --- a/include/MQueueListener.h +++ b/src/consumer/MessageQueueListener.h @@ -14,19 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __MQ_LISTENER_H__ -#define __MQ_LISTENER_H__ +#ifndef ROCKETMQ_MESSAGEQUEUELISTENER_H_ +#define ROCKETMQ_MESSAGEQUEUELISTENER_H_ -#include -#include +#include // std::string +#include // std::vector #include "MQMessageQueue.h" namespace rocketmq { -class ROCKETMQCLIENT_API MQueueListener { +class MessageQueueListener { public: - virtual ~MQueueListener() = default; + virtual ~MessageQueueListener() = default; virtual void messageQueueChanged(const std::string& topic, std::vector& mqAll, @@ -35,4 +35,4 @@ class ROCKETMQCLIENT_API MQueueListener { } // namespace rocketmq -#endif // __MQ_LISTENER_H__ +#endif // ROCKETMQ_MESSAGESELECTOR_H_ diff --git a/src/consumer/RebalanceImpl.cpp b/src/consumer/RebalanceImpl.cpp index 1454584a4..ddb39e8d2 100644 --- a/src/consumer/RebalanceImpl.cpp +++ b/src/consumer/RebalanceImpl.cpp @@ -52,21 +52,21 @@ void RebalanceImpl::unlock(MQMessageQueue mq, const bool oneway) { ProcessQueuePtr processQueue = getProcessQueue(mq); if (processQueue) { processQueue->set_locked(false); - LOG_INFO("the message queue unlock OK, mq:%s", mq.toString().c_str()); + LOG_INFO_NEW("the message queue unlock OK, mq:{}", mq.toString()); } else { - LOG_ERROR("the message queue unlock Failed, mq:%s", mq.toString().c_str()); + LOG_ERROR_NEW("the message queue unlock Failed, mq:{}", mq.toString()); } } catch (MQException& e) { - LOG_ERROR("unlockBatchMQ exception, mq:%s", mq.toString().c_str()); + LOG_ERROR_NEW("unlockBatchMQ exception, mq:{}", mq.toString()); } } else { - LOG_WARN("unlock findBrokerAddressInSubscribe ret null for broker:%s", mq.broker_name().data()); + LOG_WARN("unlock findBrokerAddressInSubscribe ret null for broker:{}", mq.broker_name()); } } void RebalanceImpl::unlockAll(const bool oneway) { auto brokerMqs = buildProcessQueueTableByBrokerName(); - LOG_INFO("unLockAll " SIZET_FMT " broker mqs", brokerMqs->size()); + LOG_INFO_NEW("unLockAll {} broker mqs", brokerMqs->size()); for (const auto& it : *brokerMqs) { const std::string& brokerName = it.first; @@ -91,16 +91,16 @@ void RebalanceImpl::unlockAll(const bool oneway) { ProcessQueuePtr processQueue = getProcessQueue(mq); if (processQueue) { processQueue->set_locked(false); - LOG_INFO("the message queue unlock OK, mq:%s", mq.toString().c_str()); + LOG_INFO_NEW("the message queue unlock OK, mq:{}", mq.toString()); } else { - LOG_ERROR("the message queue unlock Failed, mq:%s", mq.toString().c_str()); + LOG_ERROR_NEW("the message queue unlock Failed, mq:{}", mq.toString()); } } } catch (MQException& e) { - LOG_ERROR("unlockBatchMQ exception"); + LOG_ERROR_NEW("unlockBatchMQ exception"); } } else { - LOG_ERROR("unlockAll findBrokerAddressInSubscribe ret null for broker:%s", brokerName.data()); + LOG_ERROR_NEW("unlockAll findBrokerAddressInSubscribe ret null for broker:{}", brokerName); } } } @@ -129,7 +129,7 @@ bool RebalanceImpl::lock(MQMessageQueue mq) { lockBatchRequest->mq_set().push_back(mq); try { - LOG_DEBUG("try to lock mq:%s", mq.toString().c_str()); + LOG_DEBUG_NEW("try to lock mq:{}", mq.toString()); std::vector lockedMq; client_instance_->getMQClientAPIImpl()->lockBatchMQ(findBrokerResult->broker_addr(), lockBatchRequest.get(), @@ -143,23 +143,23 @@ bool RebalanceImpl::lock(MQMessageQueue mq) { processQueue->set_locked(true); processQueue->set_last_lock_timestamp(UtilAll::currentTimeMillis()); lockOK = true; - LOG_INFO("the message queue locked OK, mq:%s", mmqq.toString().c_str()); + LOG_INFO_NEW("the message queue locked OK, mq:{}", mmqq.toString()); } else { - LOG_WARN("the message queue locked OK, but it is released, mq:%s", mmqq.toString().c_str()); + LOG_WARN_NEW("the message queue locked OK, but it is released, mq:{}", mmqq.toString()); } } lockedMq.clear(); } else { - LOG_ERROR("the message queue locked Failed, mq:%s", mq.toString().c_str()); + LOG_ERROR_NEW("the message queue locked Failed, mq:{}", mq.toString()); } return lockOK; } catch (MQException& e) { - LOG_ERROR("lockBatchMQ exception, mq:%s", mq.toString().c_str()); + LOG_ERROR_NEW("lockBatchMQ exception, mq:{}", mq.toString()); } } else { - LOG_ERROR("lock findBrokerAddressInSubscribe ret null for broker:%s", mq.broker_name().data()); + LOG_ERROR_NEW("lock findBrokerAddressInSubscribe ret null for broker:{}", mq.broker_name()); } return false; @@ -167,7 +167,7 @@ bool RebalanceImpl::lock(MQMessageQueue mq) { void RebalanceImpl::lockAll() { auto brokerMqs = buildProcessQueueTableByBrokerName(); - LOG_INFO("LockAll " SIZET_FMT " broker mqs", brokerMqs->size()); + LOG_INFO_NEW("LockAll {} broker mqs", brokerMqs->size()); for (const auto& it : *brokerMqs) { const std::string& brokerName = it.first; @@ -185,7 +185,7 @@ void RebalanceImpl::lockAll() { lockBatchRequest->set_client_id(client_instance_->getClientId()); lockBatchRequest->set_mq_set(mqs); - LOG_INFO("try to lock:" SIZET_FMT " mqs of broker:%s", mqs.size(), brokerName.c_str()); + LOG_INFO_NEW("try to lock:{} mqs of broker:{}", mqs.size(), brokerName); try { std::vector lockOKMQVec; client_instance_->getMQClientAPIImpl()->lockBatchMQ(findBrokerResult->broker_addr(), lockBatchRequest.get(), @@ -199,9 +199,9 @@ void RebalanceImpl::lockAll() { if (processQueue) { processQueue->set_locked(true); processQueue->set_last_lock_timestamp(UtilAll::currentTimeMillis()); - LOG_INFO("the message queue locked OK, mq:%s", mq.toString().c_str()); + LOG_INFO_NEW("the message queue locked OK, mq:{}", mq.toString()); } else { - LOG_WARN("the message queue locked OK, but it is released, mq:%s", mq.toString().c_str()); + LOG_WARN_NEW("the message queue locked OK, but it is released, mq:{}", mq.toString()); } } @@ -209,29 +209,29 @@ void RebalanceImpl::lockAll() { if (lockOKMQSet.find(mq) == lockOKMQSet.end()) { ProcessQueuePtr processQueue = getProcessQueue(mq); if (processQueue) { - LOG_WARN("the message queue locked Failed, mq:%s", mq.toString().c_str()); + LOG_WARN_NEW("the message queue locked Failed, mq:{}", mq.toString()); processQueue->set_locked(false); } } } } catch (MQException& e) { - LOG_ERROR("lockBatchMQ fails"); + LOG_ERROR_NEW("lockBatchMQ fails"); } } else { - LOG_ERROR("lockAll findBrokerAddressInSubscribe ret null for broker:%s", brokerName.c_str()); + LOG_ERROR_NEW("lockAll findBrokerAddressInSubscribe ret null for broker:{}", brokerName); } } } void RebalanceImpl::doRebalance(const bool isOrder) { - LOG_DEBUG("start doRebalance"); + LOG_DEBUG_NEW("start doRebalance"); for (const auto& it : subscription_inner_) { const std::string& topic = it.first; - LOG_INFO("current topic is:%s", topic.c_str()); + LOG_INFO_NEW("current topic is:{}", topic); try { rebalanceByTopic(topic, isOrder); } catch (MQException& e) { - LOG_ERROR(e.what()); + LOG_ERROR_NEW("{}", e.what()); } } @@ -249,14 +249,14 @@ void RebalanceImpl::rebalanceByTopic(const std::string& topic, const bool isOrde messageQueueChanged(topic, mqSet, mqSet); } } else { - LOG_WARN("doRebalance, %s, but the topic[%s] not exist.", consumer_group_.c_str(), topic.c_str()); + LOG_WARN_NEW("doRebalance, {}, but the topic[{}] not exist.", consumer_group_, topic); } } break; case CLUSTERING: { std::vector mqAll; if (!getTopicSubscribeInfo(topic, mqAll)) { if (!UtilAll::isRetryTopic(topic)) { - LOG_WARN("doRebalance, %s, but the topic[%s] not exist.", consumer_group_.c_str(), topic.c_str()); + LOG_WARN_NEW("doRebalance, {}, but the topic[{}] not exist.", consumer_group_, topic); } return; } @@ -265,13 +265,13 @@ void RebalanceImpl::rebalanceByTopic(const std::string& topic, const bool isOrde client_instance_->findConsumerIds(topic, consumer_group_, cidAll); if (cidAll.empty()) { - LOG_WARN("doRebalance, %s %s, get consumer id list failed", consumer_group_.c_str(), topic.c_str()); + LOG_WARN_NEW("doRebalance, {} {}, get consumer id list failed", consumer_group_, topic); return; } // log for (auto& cid : cidAll) { - LOG_INFO("client id:%s of topic:%s", cid.c_str(), topic.c_str()); + LOG_INFO_NEW("client id:{} of topic:{}", cid, topic); } // sort @@ -283,19 +283,20 @@ void RebalanceImpl::rebalanceByTopic(const std::string& topic, const bool isOrde try { allocate_mq_strategy_->allocate(client_instance_->getClientId(), mqAll, cidAll, allocateResult); } catch (MQException& e) { - LOG_ERROR("AllocateMessageQueueStrategy.allocate Exception: %s", e.what()); + LOG_ERROR_NEW("AllocateMessageQueueStrategy.allocate Exception: {}", e.what()); return; } // update local bool changed = updateProcessQueueTableInRebalance(topic, allocateResult, isOrder); if (changed) { - LOG_INFO("rebalanced result changed. group=%s, topic=%s, clientId=%s, mqAllSize=" SIZET_FMT - ", cidAllSize=" SIZET_FMT ", rebalanceResultSize=" SIZET_FMT ", rebalanceResultSet:", - consumer_group_.c_str(), topic.c_str(), client_instance_->getClientId().c_str(), mqAll.size(), - cidAll.size(), allocateResult.size()); + LOG_INFO_NEW( + "rebalanced result changed. group={}, topic={}, clientId={}, mqAllSize={}, cidAllSize={}, " + "rebalanceResultSize={}, rebalanceResultSet:", + consumer_group_, topic, client_instance_->getClientId(), mqAll.size(), cidAll.size(), + allocateResult.size()); for (auto& mq : allocateResult) { - LOG_INFO("allocate mq:%s", mq.toString().c_str()); + LOG_INFO_NEW("allocate mq:{}", mq.toString()); } messageQueueChanged(topic, mqAll, allocateResult); } @@ -313,8 +314,8 @@ void RebalanceImpl::truncateMessageQueueNotMyTopic() { auto pq = removeProcessQueueDirectly(mq); if (pq != nullptr) { pq->set_dropped(true); - LOG_INFO("doRebalance, %s, truncateMessageQueueNotMyTopic remove unnecessary mq, {}", consumer_group_.c_str(), - mq.toString().c_str()); + LOG_INFO_NEW("doRebalance, {}, truncateMessageQueueNotMyTopic remove unnecessary mq, {}", consumer_group_, + mq.toString()); } } } @@ -339,7 +340,7 @@ bool RebalanceImpl::updateProcessQueueTableInRebalance(const std::string& topic, if (removeUnnecessaryMessageQueue(mq, pq)) { removeProcessQueueDirectly(mq); changed = true; - LOG_INFO("doRebalance, %s, remove unnecessary mq, %s", consumer_group_.c_str(), mq.toString().c_str()); + LOG_INFO_NEW("doRebalance, {}, remove unnecessary mq, {}", consumer_group_, mq.toString()); } } else if (pq->isPullExpired()) { switch (consumeType()) { @@ -350,8 +351,9 @@ bool RebalanceImpl::updateProcessQueueTableInRebalance(const std::string& topic, if (removeUnnecessaryMessageQueue(mq, pq)) { removeProcessQueueDirectly(mq); changed = true; - LOG_ERROR("[BUG]doRebalance, %s, remove unnecessary mq, %s, because pull is pause, so try to fixed it", - consumer_group_.c_str(), mq.toString().c_str()); + LOG_ERROR_NEW( + "[BUG]doRebalance, {}, remove unnecessary mq, {}, because pull is pause, so try to fixed it", + consumer_group_, mq.toString()); } break; default: @@ -367,8 +369,7 @@ bool RebalanceImpl::updateProcessQueueTableInRebalance(const std::string& topic, ProcessQueuePtr pq = getProcessQueue(mq); if (nullptr == pq) { if (isOrder && !lock(mq)) { - LOG_WARN("doRebalance, %s, add a new mq failed, %s, because lock failed", consumer_group_.c_str(), - mq.toString().c_str()); + LOG_WARN_NEW("doRebalance, {}, add a new mq failed, {}, because lock failed", consumer_group_, mq.toString()); continue; } @@ -378,9 +379,9 @@ bool RebalanceImpl::updateProcessQueueTableInRebalance(const std::string& topic, if (nextOffset >= 0) { auto pre = putProcessQueueIfAbsent(mq, pq); if (pre) { - LOG_INFO("doRebalance, %s, mq already exists, %s", consumer_group_.c_str(), mq.toString().c_str()); + LOG_INFO_NEW("doRebalance, {}, mq already exists, {}", consumer_group_, mq.toString()); } else { - LOG_INFO("doRebalance, %s, add a new mq, %s", consumer_group_.c_str(), mq.toString().c_str()); + LOG_INFO_NEW("doRebalance, {}, add a new mq, {}", consumer_group_, mq.toString()); PullRequestPtr pullRequest(new PullRequest()); pullRequest->set_consumer_group(consumer_group_); pullRequest->set_next_offset(nextOffset); @@ -390,14 +391,14 @@ bool RebalanceImpl::updateProcessQueueTableInRebalance(const std::string& topic, changed = true; } } else { - LOG_WARN("doRebalance, %s, add new mq failed, %s", consumer_group_.c_str(), mq.toString().c_str()); + LOG_WARN_NEW("doRebalance, {}, add new mq failed, {}", consumer_group_, mq.toString()); } } } dispatchPullRequest(pullRequestList); - LOG_DEBUG("updateRequestTableInRebalance exit"); + LOG_DEBUG_NEW("updateRequestTableInRebalance exit"); return changed; } @@ -411,8 +412,8 @@ void RebalanceImpl::removeProcessQueue(const MQMessageQueue& mq) { bool dropped = prev->dropped(); prev->set_dropped(true); removeUnnecessaryMessageQueue(mq, prev); - LOG_INFO("Fix Offset, {}, remove unnecessary mq, {} Dropped: {}", consumer_group_, mq.toString(), - UtilAll::to_string(dropped)); + LOG_INFO_NEW("Fix Offset, {}, remove unnecessary mq, {} Dropped: {}", consumer_group_, mq.toString(), + UtilAll::to_string(dropped)); } } @@ -514,7 +515,7 @@ void RebalanceImpl::setTopicSubscribeInfo(const std::string& topic, std::vector< // log for (const auto& mq : mqs) { - LOG_DEBUG("topic [%s] has :%s", topic.c_str(), mq.toString().c_str()); + LOG_DEBUG_NEW("topic [{}] has :{}", topic, mq.toString()); } } diff --git a/src/consumer/RebalanceImpl.h b/src/consumer/RebalanceImpl.h index 0ef1a9a97..194fd48f4 100755 --- a/src/consumer/RebalanceImpl.h +++ b/src/consumer/RebalanceImpl.h @@ -102,7 +102,7 @@ class RebalanceImpl { TOPIC2MQS topic_subscribe_info_table_; std::mutex topic_subscribe_info_table_mutex_; - TOPIC2SD subscription_inner_; // don't modify subscription_inner_ after consumer start. + TOPIC2SD subscription_inner_; // don't modify subscription_inner_ after the consumer started. std::string consumer_group_; MessageModel message_model_; diff --git a/src/consumer/RebalanceLitePullImpl.cpp b/src/consumer/RebalanceLitePullImpl.cpp new file mode 100644 index 000000000..4956d148a --- /dev/null +++ b/src/consumer/RebalanceLitePullImpl.cpp @@ -0,0 +1,119 @@ +/* + * 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 "RebalanceLitePullImpl.h" + +#include "OffsetStore.h" +#include "UtilAll.h" + +namespace rocketmq { + +RebalanceLitePullImpl::RebalanceLitePullImpl(DefaultLitePullConsumerImpl* consumerImpl) + : RebalanceImpl(null, CLUSTERING, nullptr, nullptr), lite_pull_consumer_impl_(consumerImpl) {} + +bool RebalanceLitePullImpl::removeUnnecessaryMessageQueue(const MQMessageQueue& mq, ProcessQueuePtr pq) { + lite_pull_consumer_impl_->getOffsetStore()->persist(mq); + lite_pull_consumer_impl_->getOffsetStore()->removeOffset(mq); + return true; +} + +void RebalanceLitePullImpl::removeDirtyOffset(const MQMessageQueue& mq) { + lite_pull_consumer_impl_->getOffsetStore()->removeOffset(mq); +} + +int64_t RebalanceLitePullImpl::computePullFromWhere(const MQMessageQueue& mq) { + int64_t result = -1; + ConsumeFromWhere consumeFromWhere = + lite_pull_consumer_impl_->getDefaultLitePullConsumerConfig()->consume_from_where(); + OffsetStore* offsetStore = lite_pull_consumer_impl_->getOffsetStore(); + switch (consumeFromWhere) { + default: + case CONSUME_FROM_LAST_OFFSET: { + long lastOffset = offsetStore->readOffset(mq, ReadOffsetType::MEMORY_FIRST_THEN_STORE); + if (lastOffset >= 0) { + result = lastOffset; + } else if (-1 == lastOffset) { + if (UtilAll::isRetryTopic(mq.topic())) { // First start, no offset + result = 0; + } else { + try { + result = lite_pull_consumer_impl_->maxOffset(mq); + } catch (MQClientException& e) { + result = -1; + } + } + } else { + result = -1; + } + break; + } + case CONSUME_FROM_FIRST_OFFSET: { + long lastOffset = offsetStore->readOffset(mq, ReadOffsetType::MEMORY_FIRST_THEN_STORE); + if (lastOffset >= 0) { + result = lastOffset; + } else if (-1 == lastOffset) { + result = 0L; + } else { + result = -1; + } + break; + } + case CONSUME_FROM_TIMESTAMP: { + long lastOffset = offsetStore->readOffset(mq, ReadOffsetType::MEMORY_FIRST_THEN_STORE); + if (lastOffset >= 0) { + result = lastOffset; + } else if (-1 == lastOffset) { + if (UtilAll::isRetryTopic(mq.topic())) { + try { + result = lite_pull_consumer_impl_->maxOffset(mq); + } catch (MQClientException& e) { + result = -1; + } + } else { + try { + // FIXME: parseDate by YYYYMMDDHHMMSS + auto timestamp = + std::stoull(lite_pull_consumer_impl_->getDefaultLitePullConsumerConfig()->consume_timestamp()); + result = lite_pull_consumer_impl_->searchOffset(mq, timestamp); + } catch (MQClientException& e) { + result = -1; + } + } + } else { + result = -1; + } + break; + } + } + return result; +} + +void RebalanceLitePullImpl::dispatchPullRequest(const std::vector& pullRequestList) {} + +void RebalanceLitePullImpl::messageQueueChanged(const std::string& topic, + std::vector& mqAll, + std::vector& mqDivided) { + auto* messageQueueListener = lite_pull_consumer_impl_->getMessageQueueListener(); + if (messageQueueListener != nullptr) { + try { + messageQueueListener->messageQueueChanged(topic, mqAll, mqDivided); + } catch (std::exception& e) { + LOG_ERROR_NEW("messageQueueChanged exception {}", e.what()); + } + } +} + +} // namespace rocketmq diff --git a/src/consumer/RebalancePullImpl.h b/src/consumer/RebalanceLitePullImpl.h similarity index 82% rename from src/consumer/RebalancePullImpl.h rename to src/consumer/RebalanceLitePullImpl.h index d4f106c51..56b6189ac 100755 --- a/src/consumer/RebalancePullImpl.h +++ b/src/consumer/RebalanceLitePullImpl.h @@ -14,10 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __REBALANCE_PULL_IMPL_H__ -#define __REBALANCE_PULL_IMPL_H__ +#ifndef ROCKETMQ_CONSUMER_REBALANCELITEPULLIMPL_H_ +#define ROCKETMQ_CONSUMER_REBALANCELITEPULLIMPL_H_ -#include "DefaultMQPullConsumer.h" +#include "DefaultLitePullConsumerImpl.h" #include "RebalanceImpl.h" namespace rocketmq { @@ -27,9 +27,9 @@ typedef std::map> TOPIC2MQS; typedef std::map TOPIC2SD; typedef std::map> BROKER2MQS; -class RebalancePullImpl : public RebalanceImpl { +class RebalanceLitePullImpl : public RebalanceImpl { public: - RebalancePullImpl(DefaultMQPullConsumer* consumer); + RebalanceLitePullImpl(DefaultLitePullConsumerImpl* consumerImpl); ConsumeType consumeType() override final { return CONSUME_ACTIVELY; } @@ -46,9 +46,9 @@ class RebalancePullImpl : public RebalanceImpl { std::vector& mqDivided) override; private: - DefaultMQPullConsumer* m_defaultMQPullConsumer; + DefaultLitePullConsumerImpl* lite_pull_consumer_impl_; }; } // namespace rocketmq -#endif // __REBALANCE_PULL_IMPL_H__ +#endif // ROCKETMQ_CONSUMER_REBALANCELITEPULLIMPL_H_ diff --git a/src/consumer/RebalancePullImpl.cpp b/src/consumer/RebalancePullImpl.cpp deleted file mode 100644 index 15184eaa1..000000000 --- a/src/consumer/RebalancePullImpl.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 "RebalancePullImpl.h" - -#include "OffsetStore.h" - -namespace rocketmq { - - -RebalancePullImpl::RebalancePullImpl(DefaultMQPullConsumer* consumer) - : RebalanceImpl("", CLUSTERING, nullptr, nullptr), m_defaultMQPullConsumer(consumer) {} - -bool RebalancePullImpl::removeUnnecessaryMessageQueue(const MQMessageQueue& mq, ProcessQueuePtr pq) { - // m_defaultMQPullConsumer->getOffsetStore()->persist(mq); - // m_defaultMQPullConsumer->getOffsetStore()->removeOffset(mq); - // return true; - return false; -} - -void RebalancePullImpl::removeDirtyOffset(const MQMessageQueue& mq) { - // m_defaultMQPullConsumer->removeConsumeOffset(mq); -} - -int64_t RebalancePullImpl::computePullFromWhere(const MQMessageQueue& mq) { - return 0; -} - -void RebalancePullImpl::dispatchPullRequest(const std::vector& pullRequestList) {} - -void RebalancePullImpl::messageQueueChanged(const std::string& topic, - std::vector& mqAll, - std::vector& mqDivided) {} - -} // namespace rocketmq diff --git a/src/extern/CPullConsumer.cpp b/src/extern/CPullConsumer.cpp index b4ed9ac6e..f3d5085ad 100644 --- a/src/extern/CPullConsumer.cpp +++ b/src/extern/CPullConsumer.cpp @@ -1,252 +1,252 @@ -/* - * 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 "c/CPullConsumer.h" - -#include - -#include "CErrorContainer.h" -#include "ClientRPCHook.h" -#include "DefaultMQPullConsumer.h" -#include "Logging.h" - -using namespace rocketmq; - -CPullConsumer* CreatePullConsumer(const char* groupId) { - if (groupId == NULL) { - return NULL; - } - auto* defaultMQPullConsumer = new DefaultMQPullConsumer(groupId); - return reinterpret_cast(defaultMQPullConsumer); -} - -int DestroyPullConsumer(CPullConsumer* consumer) { - if (consumer == NULL) { - return NULL_POINTER; - } - delete reinterpret_cast(consumer); - return OK; -} - -int StartPullConsumer(CPullConsumer* consumer) { - if (consumer == NULL) { - return NULL_POINTER; - } - try { - reinterpret_cast(consumer)->start(); - } catch (std::exception& e) { - CErrorContainer::setErrorMessage(e.what()); - return PULLCONSUMER_START_FAILED; - } - return OK; -} - -int ShutdownPullConsumer(CPullConsumer* consumer) { - if (consumer == NULL) { - return NULL_POINTER; - } - reinterpret_cast(consumer)->shutdown(); - return OK; -} - -int SetPullConsumerGroupID(CPullConsumer* consumer, const char* groupId) { - if (consumer == NULL || groupId == NULL) { - return NULL_POINTER; - } - reinterpret_cast(consumer)->set_group_name(groupId); - return OK; -} - -const char* GetPullConsumerGroupID(CPullConsumer* consumer) { - if (consumer == NULL) { - return NULL; - } - return reinterpret_cast(consumer)->group_name().c_str(); -} - -int SetPullConsumerNameServerAddress(CPullConsumer* consumer, const char* namesrv) { - if (consumer == NULL) { - return NULL_POINTER; - } - reinterpret_cast(consumer)->set_namesrv_addr(namesrv); - return OK; -} - -// Deprecated -int SetPullConsumerNameServerDomain(CPullConsumer* consumer, const char* domain) { - if (consumer == NULL) { - return NULL_POINTER; - } - return NOT_SUPPORT_NOW; -} - -int SetPullConsumerSessionCredentials(CPullConsumer* consumer, - const char* accessKey, - const char* secretKey, - const char* channel) { - if (consumer == NULL) { - return NULL_POINTER; - } - auto rpcHook = std::make_shared(SessionCredentials(accessKey, secretKey, channel)); - reinterpret_cast(consumer)->setRPCHook(rpcHook); - 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; - } - DEFAULT_LOG_ADAPTER->setLogFileNumAndSize(fileNum, fileSize); - return OK; -} - -int SetPullConsumerLogLevel(CPullConsumer* consumer, CLogLevel level) { - if (consumer == NULL) { - return NULL_POINTER; - } - DEFAULT_LOG_ADAPTER->set_log_level((LogLevel)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 fullMQ; - try { - reinterpret_cast(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->topic().c_str(), MAX_TOPIC_LENGTH - 1); - strncpy(temMQ[index].brokerName, iter->broker_name().c_str(), MAX_BROKER_NAME_ID_LENGTH - 1); - temMQ[index].queueId = iter->queue_id(); - } - *mqs = temMQ; - } catch (MQException& e) { - *size = 0; - *mqs = NULL; - CErrorContainer::setErrorMessage(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)); - MQMessageQueue messageQueue(mq->topic, mq->brokerName, mq->queueId); - PullResult cppPullResult; - try { - cppPullResult = - reinterpret_cast(consumer)->pull(messageQueue, subExpression, offset, maxNums); - } catch (std::exception& e) { - CErrorContainer::setErrorMessage(e.what()); - cppPullResult.set_pull_status(BROKER_TIMEOUT); - } - - if (cppPullResult.pull_status() != BROKER_TIMEOUT) { - pullResult.maxOffset = cppPullResult.max_offset(); - pullResult.minOffset = cppPullResult.min_offset(); - pullResult.nextBeginOffset = cppPullResult.next_begin_offset(); - } - - switch (cppPullResult.pull_status()) { - case FOUND: { - pullResult.pullStatus = E_FOUND; - pullResult.size = cppPullResult.msg_found_list().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.msg_found_list().size(); i++) { - auto msg = tmpPullResult->msg_found_list()[i]; - pullResult.msgFoundList[i] = reinterpret_cast(&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 (std::exception& e) { - CErrorContainer::setErrorMessage(e.what()); - return NULL_POINTER; - } - } - free((void*)pullResult.msgFoundList); - pullResult.msgFoundList = NULL; - return OK; -} +// /* +// * 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 "c/CPullConsumer.h" + +// #include + +// #include "CErrorContainer.h" +// #include "ClientRPCHook.h" +// #include "DefaultMQPullConsumer.h" +// #include "Logging.h" + +// using namespace rocketmq; + +// CPullConsumer* CreatePullConsumer(const char* groupId) { +// if (groupId == NULL) { +// return NULL; +// } +// auto* defaultMQPullConsumer = new DefaultMQPullConsumer(groupId); +// return reinterpret_cast(defaultMQPullConsumer); +// } + +// int DestroyPullConsumer(CPullConsumer* consumer) { +// if (consumer == NULL) { +// return NULL_POINTER; +// } +// delete reinterpret_cast(consumer); +// return OK; +// } + +// int StartPullConsumer(CPullConsumer* consumer) { +// if (consumer == NULL) { +// return NULL_POINTER; +// } +// try { +// reinterpret_cast(consumer)->start(); +// } catch (std::exception& e) { +// CErrorContainer::setErrorMessage(e.what()); +// return PULLCONSUMER_START_FAILED; +// } +// return OK; +// } + +// int ShutdownPullConsumer(CPullConsumer* consumer) { +// if (consumer == NULL) { +// return NULL_POINTER; +// } +// reinterpret_cast(consumer)->shutdown(); +// return OK; +// } + +// int SetPullConsumerGroupID(CPullConsumer* consumer, const char* groupId) { +// if (consumer == NULL || groupId == NULL) { +// return NULL_POINTER; +// } +// reinterpret_cast(consumer)->setGroupName(groupId); +// return OK; +// } + +// const char* GetPullConsumerGroupID(CPullConsumer* consumer) { +// if (consumer == NULL) { +// return NULL; +// } +// return reinterpret_cast(consumer)->getGroupName().c_str(); +// } + +// int SetPullConsumerNameServerAddress(CPullConsumer* consumer, const char* namesrv) { +// if (consumer == NULL) { +// return NULL_POINTER; +// } +// reinterpret_cast(consumer)->setNamesrvAddr(namesrv); +// return OK; +// } + +// // Deprecated +// int SetPullConsumerNameServerDomain(CPullConsumer* consumer, const char* domain) { +// if (consumer == NULL) { +// return NULL_POINTER; +// } +// return NOT_SUPPORT_NOW; +// } + +// int SetPullConsumerSessionCredentials(CPullConsumer* consumer, +// const char* accessKey, +// const char* secretKey, +// const char* channel) { +// if (consumer == NULL) { +// return NULL_POINTER; +// } +// auto rpcHook = std::make_shared(SessionCredentials(accessKey, secretKey, channel)); +// reinterpret_cast(consumer)->setRPCHook(rpcHook); +// 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; +// } +// DEFAULT_LOG_ADAPTER->setLogFileNumAndSize(fileNum, fileSize); +// return OK; +// } + +// int SetPullConsumerLogLevel(CPullConsumer* consumer, CLogLevel level) { +// if (consumer == NULL) { +// return NULL_POINTER; +// } +// DEFAULT_LOG_ADAPTER->set_log_level((LogLevel)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 fullMQ; +// try { +// reinterpret_cast(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->topic().c_str(), MAX_TOPIC_LENGTH - 1); +// strncpy(temMQ[index].brokerName, iter->broker_name().c_str(), MAX_BROKER_NAME_ID_LENGTH - 1); +// temMQ[index].queueId = iter->queue_id(); +// } +// *mqs = temMQ; +// } catch (MQException& e) { +// *size = 0; +// *mqs = NULL; +// CErrorContainer::setErrorMessage(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)); +// MQMessageQueue messageQueue(mq->topic, mq->brokerName, mq->queueId); +// PullResult cppPullResult; +// try { +// cppPullResult = +// reinterpret_cast(consumer)->pull(messageQueue, subExpression, offset, maxNums); +// } catch (std::exception& e) { +// CErrorContainer::setErrorMessage(e.what()); +// cppPullResult.set_pull_status(BROKER_TIMEOUT); +// } + +// if (cppPullResult.pull_status() != BROKER_TIMEOUT) { +// pullResult.maxOffset = cppPullResult.max_offset(); +// pullResult.minOffset = cppPullResult.min_offset(); +// pullResult.nextBeginOffset = cppPullResult.next_begin_offset(); +// } + +// switch (cppPullResult.pull_status()) { +// case FOUND: { +// pullResult.pullStatus = E_FOUND; +// pullResult.size = cppPullResult.msg_found_list().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.msg_found_list().size(); i++) { +// auto msg = tmpPullResult->msg_found_list()[i]; +// pullResult.msgFoundList[i] = reinterpret_cast(&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 (std::exception& e) { +// CErrorContainer::setErrorMessage(e.what()); +// return NULL_POINTER; +// } +// } +// free((void*)pullResult.msgFoundList); +// pullResult.msgFoundList = NULL; +// return OK; +// } diff --git a/test/src/extern/CPullConsumerTest.cpp b/test/src/extern/CPullConsumerTest.cpp.bak similarity index 99% rename from test/src/extern/CPullConsumerTest.cpp rename to test/src/extern/CPullConsumerTest.cpp.bak index 51b79dcc8..996659d7c 100644 --- a/test/src/extern/CPullConsumerTest.cpp +++ b/test/src/extern/CPullConsumerTest.cpp.bak @@ -20,7 +20,7 @@ #include #include -#include "DefaultMQPullConsumer.h" +#include "DefaultLitePullConsumer.h" #include "MQClientInstance.h" #include "MessageExtImpl.h" #include "MQMessageQueue.h" From 4ace548e2af6efb013a016c539e3ffa2f93b85e6 Mon Sep 17 00:00:00 2001 From: James Yin Date: Wed, 21 Oct 2020 13:02:24 +0800 Subject: [PATCH 31/62] style: fix GET_ROUTEINFO_BY_TOPIC --- src/MQClientAPIImpl.cpp | 2 +- src/protocol/RequestCode.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index 2d35354dd..b25f672bb 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -634,7 +634,7 @@ void MQClientAPIImpl::unlockBatchMQ(const std::string& addr, } TopicRouteData* MQClientAPIImpl::getTopicRouteInfoFromNameServer(const std::string& topic, int timeoutMillis) { - RemotingCommand request(GET_ROUTEINTO_BY_TOPIC, new GetRouteInfoRequestHeader(topic)); + RemotingCommand request(GET_ROUTEINFO_BY_TOPIC, new GetRouteInfoRequestHeader(topic)); std::unique_ptr response(remoting_client_->invokeSync(null, request, timeoutMillis)); assert(response != nullptr); diff --git a/src/protocol/RequestCode.h b/src/protocol/RequestCode.h index 68b8f3100..40180ddea 100644 --- a/src/protocol/RequestCode.h +++ b/src/protocol/RequestCode.h @@ -122,7 +122,7 @@ enum MQRequestCode { DELETE_KV_CONFIG = 102, REGISTER_BROKER = 103, UNREGISTER_BROKER = 104, - GET_ROUTEINTO_BY_TOPIC = 105, + GET_ROUTEINFO_BY_TOPIC = 105, GET_BROKER_CLUSTER_INFO = 106, WIPE_WRITE_PERM_OF_BROKER = 205, GET_ALL_TOPIC_LIST_FROM_NAMESERVER = 206, From 9a30e84c26d8d9c904a5a8cec348aabaaa5f4dc5 Mon Sep 17 00:00:00 2001 From: James Yin Date: Thu, 22 Oct 2020 14:54:15 +0800 Subject: [PATCH 32/62] refactor: lock/unlock in RebalanceImpl --- src/consumer/RebalanceImpl.cpp | 4 ++-- src/consumer/RebalanceImpl.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/consumer/RebalanceImpl.cpp b/src/consumer/RebalanceImpl.cpp index ddb39e8d2..505ce46c7 100644 --- a/src/consumer/RebalanceImpl.cpp +++ b/src/consumer/RebalanceImpl.cpp @@ -36,7 +36,7 @@ RebalanceImpl::~RebalanceImpl() { } } -void RebalanceImpl::unlock(MQMessageQueue mq, const bool oneway) { +void RebalanceImpl::unlock(const MQMessageQueue& mq, const bool oneway) { std::unique_ptr findBrokerResult( client_instance_->findBrokerAddressInSubscribe(mq.broker_name(), MASTER_ID, true)); if (findBrokerResult) { @@ -119,7 +119,7 @@ std::shared_ptr RebalanceImpl::buildProcessQueueTableByBrokerName() return brokerMqs; } -bool RebalanceImpl::lock(MQMessageQueue mq) { +bool RebalanceImpl::lock(const MQMessageQueue& mq) { std::unique_ptr findBrokerResult( client_instance_->findBrokerAddressInSubscribe(mq.broker_name(), MASTER_ID, true)); if (findBrokerResult) { diff --git a/src/consumer/RebalanceImpl.h b/src/consumer/RebalanceImpl.h index 194fd48f4..a44784e07 100755 --- a/src/consumer/RebalanceImpl.h +++ b/src/consumer/RebalanceImpl.h @@ -43,10 +43,10 @@ class RebalanceImpl { MQClientInstance* clientInstance); virtual ~RebalanceImpl(); - void unlock(MQMessageQueue mq, const bool oneway = false); + void unlock(const MQMessageQueue& mq, const bool oneway = false); void unlockAll(const bool oneway = false); - bool lock(MQMessageQueue mq); + bool lock(const MQMessageQueue& mq); void lockAll(); void doRebalance(const bool isOrder = false); From 8402eb0d51264d22060552a1a78bd1bf29713ab3 Mon Sep 17 00:00:00 2001 From: James Yin Date: Fri, 25 Dec 2020 17:53:19 +0800 Subject: [PATCH 33/62] chore: update for clangd --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 327bb7c61..f223ccad7 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,9 @@ # cmake cmake-build-debug/ +# clangd +.cache/ + # project bin build From 2cf4836defad2e17d69a7e149ea2cb7598a8e38d Mon Sep 17 00:00:00 2001 From: James Yin Date: Fri, 8 Jan 2021 18:35:01 +0800 Subject: [PATCH 34/62] fix: header of std::bad_alloc --- include/Array.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Array.h b/include/Array.h index c1059cffa..20fd7b352 100644 --- a/include/Array.h +++ b/include/Array.h @@ -20,7 +20,7 @@ #include // std::calloc, std::free #include // std::memcpy -#include // std::bad_alloc +#include // std::bad_alloc #include // std::enable_if, std::is_arithmetic, std::is_pointer, std::is_class #include "RocketMQClient.h" From 1c868a720e78b8af43df28618d5ff997c7cd6e17 Mon Sep 17 00:00:00 2001 From: James Yin Date: Fri, 8 Jan 2021 18:35:40 +0800 Subject: [PATCH 35/62] feat: support async send for batch message --- include/DefaultMQProducer.h | 5 +++++ include/MQProducer.h | 5 +++++ src/producer/DefaultMQProducer.cpp | 16 ++++++++++++++++ src/producer/DefaultMQProducerImpl.cpp | 20 ++++++++++++++++++++ src/producer/DefaultMQProducerImpl.h | 7 ++++++- 5 files changed, 52 insertions(+), 1 deletion(-) diff --git a/include/DefaultMQProducer.h b/include/DefaultMQProducer.h index ec5e5dfca..5339db185 100644 --- a/include/DefaultMQProducer.h +++ b/include/DefaultMQProducer.h @@ -75,6 +75,11 @@ class ROCKETMQCLIENT_API DefaultMQProducer : public DefaultMQProducerConfigProxy SendResult send(std::vector& msgs, const MQMessageQueue& mq) override; SendResult send(std::vector& msgs, const MQMessageQueue& mq, long timeout) override; + void send(std::vector& msgs, SendCallback* sendCallback) override; + void send(std::vector& msgs, SendCallback* sendCallback, long timeout) override; + void send(std::vector& msgs, const MQMessageQueue& mq, SendCallback* sendCallback) override; + void send(std::vector& msgs, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) override; + // RPC MQMessage request(MQMessage& msg, long timeout) override; void request(MQMessage& msg, RequestCallback* requestCallback, long timeout) override; diff --git a/include/MQProducer.h b/include/MQProducer.h index 6fc281e81..c8226a576 100644 --- a/include/MQProducer.h +++ b/include/MQProducer.h @@ -72,6 +72,11 @@ class ROCKETMQCLIENT_API MQProducer { virtual SendResult send(std::vector& msgs, const MQMessageQueue& mq) = 0; virtual SendResult send(std::vector& msgs, const MQMessageQueue& mq, long timeout) = 0; + virtual void send(std::vector& msgs, SendCallback* sendCallback) = 0; + virtual void send(std::vector& msgs, SendCallback* sendCallback, long timeout) = 0; + virtual void send(std::vector& msgs, const MQMessageQueue& mq, SendCallback* sendCallback) = 0; + virtual void send(std::vector& msgs, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) = 0; + // RPC virtual MQMessage request(MQMessage& msg, long timeout) = 0; virtual void request(MQMessage& msg, RequestCallback* requestCallback, long timeout) = 0; diff --git a/src/producer/DefaultMQProducer.cpp b/src/producer/DefaultMQProducer.cpp index 89fd57a8d..75deff0d0 100644 --- a/src/producer/DefaultMQProducer.cpp +++ b/src/producer/DefaultMQProducer.cpp @@ -143,6 +143,22 @@ SendResult DefaultMQProducer::send(std::vector& msgs, const MQMessage return producer_impl_->send(msgs, mq, timeout); } +void DefaultMQProducer::send(std::vector& msgs, SendCallback* sendCallback) { + producer_impl_->send(msgs, sendCallback); +} + +void DefaultMQProducer::send(std::vector& msgs, SendCallback* sendCallback, long timeout) { + producer_impl_->send(msgs, sendCallback, timeout); +} + +void DefaultMQProducer::send(std::vector& msgs, const MQMessageQueue& mq, SendCallback* sendCallback) { + producer_impl_->send(msgs, mq, sendCallback); +} + +void DefaultMQProducer::send(std::vector& msgs, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) { + producer_impl_->send(msgs, mq, sendCallback, timeout); +} + MQMessage DefaultMQProducer::request(MQMessage& msg, long timeout) { return producer_impl_->request(msg, timeout); } diff --git a/src/producer/DefaultMQProducerImpl.cpp b/src/producer/DefaultMQProducerImpl.cpp index b33d05262..dd686cd80 100644 --- a/src/producer/DefaultMQProducerImpl.cpp +++ b/src/producer/DefaultMQProducerImpl.cpp @@ -358,6 +358,26 @@ SendResult DefaultMQProducerImpl::send(std::vector& msgs, const MQMes return send(batchMessage, mq, timeout); } +void DefaultMQProducerImpl::send(std::vector& msgs, SendCallback* sendCallback) { + MQMessage batchMessage(batch(msgs)); + send(batchMessage, sendCallback); +} + +void DefaultMQProducerImpl::send(std::vector& msgs, SendCallback* sendCallback, long timeout) { + MQMessage batchMessage(batch(msgs)); + send(batchMessage, sendCallback, timeout); +} + +void DefaultMQProducerImpl::send(std::vector& msgs, const MQMessageQueue& mq, SendCallback* sendCallback) { + MQMessage batchMessage(batch(msgs)); + send(batchMessage, mq, sendCallback); +} + +void DefaultMQProducerImpl::send(std::vector& msgs, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) { + MQMessage batchMessage(batch(msgs)); + send(batchMessage, mq, sendCallback, timeout); +} + MessagePtr DefaultMQProducerImpl::batch(std::vector& msgs) { if (msgs.size() < 1) { THROW_MQEXCEPTION(MQClientException, "msgs need one message at least", -1); diff --git a/src/producer/DefaultMQProducerImpl.h b/src/producer/DefaultMQProducerImpl.h index d93d5ea33..f1325655a 100644 --- a/src/producer/DefaultMQProducerImpl.h +++ b/src/producer/DefaultMQProducerImpl.h @@ -93,12 +93,17 @@ class DefaultMQProducerImpl : public std::enable_shared_from_this& msgs) override; SendResult send(std::vector& msgs, long timeout) override; SendResult send(std::vector& msgs, const MQMessageQueue& mq) override; SendResult send(std::vector& msgs, const MQMessageQueue& mq, long timeout) override; + void send(std::vector& msgs, SendCallback* sendCallback) override; + void send(std::vector& msgs, SendCallback* sendCallback, long timeout) override; + void send(std::vector& msgs, const MQMessageQueue& mq, SendCallback* sendCallback) override; + void send(std::vector& msgs, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) override; + // RPC MQMessage request(MQMessage& msg, long timeout) override; void request(MQMessage& msg, RequestCallback* requestCallback, long timeout) override; From 8c0e76111f0620fbd0b8e1ec1424f53cddd6281d Mon Sep 17 00:00:00 2001 From: James Yin Date: Mon, 11 Jan 2021 15:02:07 +0800 Subject: [PATCH 36/62] fix: UtilAll::createDirectory --- example/common.h | 4 ++-- include/RocketMQClient.h | 4 ++-- src/common/UtilAll.cpp | 30 ++++++++++++++------------- src/consumer/LocalFileOffsetStore.cpp | 4 ++-- src/log/Logging.cpp | 4 ++-- 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/example/common.h b/example/common.h index 4834987a8..8daec4fc5 100644 --- a/example/common.h +++ b/example/common.h @@ -132,7 +132,7 @@ static void PrintRocketmqSendAndConsumerArgs(const RocketmqSendAndConsumerArgs& static void help() { std::cout << "need option, like follow:\n" - "-n nameserver addr, if not set -n and -i ,no nameSrv will be got\n" + "-n nameserver addr, if not set -n, no namesrv will be got\n" "-g groupname\n" "-t msg topic\n" "-m messagecout(default value: 1)\n" @@ -148,7 +148,7 @@ static void help() { static bool ParseArgs(int argc, char* argv[], RocketmqSendAndConsumerArgs* info) { #ifndef WIN32 int ch; - while ((ch = getopt(argc, argv, "n:g:t:m:c:b:h:r:T:bu")) != -1) { + while ((ch = getopt(argc, argv, "n:g:t:m:c:br:uT:vh")) != -1) { switch (ch) { case 'n': info->namesrv.insert(0, optarg); diff --git a/include/RocketMQClient.h b/include/RocketMQClient.h index 39d5ccc39..a4bb3af70 100644 --- a/include/RocketMQClient.h +++ b/include/RocketMQClient.h @@ -50,9 +50,9 @@ #endif #ifdef WIN32 -#define FILE_SEPARATOR "\\" +#define FILE_SEPARATOR '\\' #else -#define FILE_SEPARATOR "/" +#define FILE_SEPARATOR '/' #endif #endif // ROCKETMQ_ROCKETMQCLIENT_H_ diff --git a/src/common/UtilAll.cpp b/src/common/UtilAll.cpp index 7da66f255..2cbe00a0c 100644 --- a/src/common/UtilAll.cpp +++ b/src/common/UtilAll.cpp @@ -291,16 +291,16 @@ std::string UtilAll::getHomeDirectory() { return home_dir; } -static bool createDirectoryInner(const char* dir) { - if (dir == nullptr) { - std::cerr << "directory is nullptr" << std::endl; +static bool createDirectoryInner(const std::string& dir) { + if (dir.empty()) { + std::cerr << "directory is empty" << std::endl; return false; } - if (access(dir, F_OK) == -1) { + if (access(dir.c_str(), F_OK) == -1) { #ifdef _WIN32 - int flag = mkdir(dir); + int flag = mkdir(dir.c_str()); #else - int flag = mkdir(dir, 0755); + int flag = mkdir(dir.c_str(), 0755); #endif return flag == 0; } @@ -308,18 +308,20 @@ static bool createDirectoryInner(const char* dir) { } void UtilAll::createDirectory(std::string const& dir) { - const char* ptr = dir.c_str(); - if (access(ptr, F_OK) == 0) { + if (dir.empty()) { return; } - char buff[2048] = {0}; - for (unsigned int i = 0; i < dir.size(); i++) { - if (i != 0 && (*(ptr + i) == '/' || *(ptr + i) == '\\')) { - memcpy(buff, ptr, i); - createDirectoryInner(buff); - memset(buff, 0, 1024); + if (access(dir.c_str(), F_OK) == 0) { + return; + } + for (size_t i = 0; i < dir.size(); i++) { + if (i != 0 && dir[i] == FILE_SEPARATOR) { + createDirectoryInner(dir.substr(0, i)); } } + if (dir[dir.size() - 1] != FILE_SEPARATOR) { + createDirectoryInner(dir); + } return; } diff --git a/src/consumer/LocalFileOffsetStore.cpp b/src/consumer/LocalFileOffsetStore.cpp index 1046c41f9..ba9581003 100644 --- a/src/consumer/LocalFileOffsetStore.cpp +++ b/src/consumer/LocalFileOffsetStore.cpp @@ -38,8 +38,8 @@ LocalFileOffsetStore::LocalFileOffsetStore(MQClientInstance* instance, const std if (!UtilAll::existDirectory(storeDir)) { UtilAll::createDirectory(storeDir); if (!UtilAll::existDirectory(storeDir)) { - LOG_ERROR("create offset store dir:%s error", storeDir.c_str()); - std::string errorMsg("create offset store dir failed: "); + LOG_ERROR_NEW("create offset store directory failed: {}", storeDir); + std::string errorMsg("create offset store directory failed: "); errorMsg.append(storeDir); THROW_MQEXCEPTION(MQClientException, errorMsg, -1); } diff --git a/src/log/Logging.cpp b/src/log/Logging.cpp index 3fc2b9cdf..7d291707f 100644 --- a/src/log/Logging.cpp +++ b/src/log/Logging.cpp @@ -62,8 +62,8 @@ void Logger::init_log_dir_() { log_dir = UtilAll::getHomeDirectory(); log_dir.append("/logs/rocketmq-cpp/"); } - if (log_dir[log_dir.size() - 1] != '/') { - log_dir.append("/"); + if (log_dir[log_dir.size() - 1] != FILE_SEPARATOR) { + log_dir += FILE_SEPARATOR; } std::string log_file_name = UtilAll::to_string(UtilAll::getProcessId()) + "_" + "rocketmq-cpp.log"; log_file_ = log_dir + log_file_name; From 3ddb50a684d472452f2a0f830548a113089a78dd Mon Sep 17 00:00:00 2001 From: James Yin Date: Mon, 11 Jan 2021 16:23:57 +0800 Subject: [PATCH 37/62] fix: BROADCASTING mode --- src/consumer/RebalanceImpl.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/consumer/RebalanceImpl.cpp b/src/consumer/RebalanceImpl.cpp index 505ce46c7..75c6646a9 100644 --- a/src/consumer/RebalanceImpl.cpp +++ b/src/consumer/RebalanceImpl.cpp @@ -244,12 +244,12 @@ void RebalanceImpl::rebalanceByTopic(const std::string& topic, const bool isOrde case BROADCASTING: { std::vector mqSet; if (!getTopicSubscribeInfo(topic, mqSet)) { - bool changed = updateProcessQueueTableInRebalance(topic, mqSet, isOrder); - if (changed) { - messageQueueChanged(topic, mqSet, mqSet); - } - } else { LOG_WARN_NEW("doRebalance, {}, but the topic[{}] not exist.", consumer_group_, topic); + return; + } + bool changed = updateProcessQueueTableInRebalance(topic, mqSet, isOrder); + if (changed) { + messageQueueChanged(topic, mqSet, mqSet); } } break; case CLUSTERING: { From f1ae40ad46bd038753b724096b121bd8344fa741 Mon Sep 17 00:00:00 2001 From: James Yin Date: Tue, 12 Jan 2021 18:03:18 +0800 Subject: [PATCH 38/62] feat: fetchPublishMessageQueues for producer --- include/DefaultMQProducer.h | 2 ++ include/MQProducer.h | 8 +++++++- src/producer/DefaultMQProducer.cpp | 9 ++++++++- src/producer/DefaultMQProducerImpl.cpp | 11 +++++++++++ src/producer/DefaultMQProducerImpl.h | 2 ++ 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/include/DefaultMQProducer.h b/include/DefaultMQProducer.h index 5339db185..a847282c5 100644 --- a/include/DefaultMQProducer.h +++ b/include/DefaultMQProducer.h @@ -39,6 +39,8 @@ class ROCKETMQCLIENT_API DefaultMQProducer : public DefaultMQProducerConfigProxy void start() override; void shutdown() override; + std::vector fetchPublishMessageQueues(const std::string& topic) override; + // Sync: caller will be responsible for the lifecycle of messages. SendResult send(MQMessage& msg) override; SendResult send(MQMessage& msg, long timeout) override; diff --git a/include/MQProducer.h b/include/MQProducer.h index c8226a576..74ea634bf 100644 --- a/include/MQProducer.h +++ b/include/MQProducer.h @@ -17,6 +17,7 @@ #ifndef ROCKETMQ_MQPRODUCER_H_ #define ROCKETMQ_MQPRODUCER_H_ +#include "MQMessageQueue.h" #include "MQSelector.h" #include "RequestCallback.h" #include "SendCallback.h" @@ -36,6 +37,8 @@ class ROCKETMQCLIENT_API MQProducer { virtual void start() = 0; virtual void shutdown() = 0; + virtual std::vector fetchPublishMessageQueues(const std::string& topic) = 0; + // Sync virtual SendResult send(MQMessage& msg) = 0; virtual SendResult send(MQMessage& msg, long timeout) = 0; @@ -75,7 +78,10 @@ class ROCKETMQCLIENT_API MQProducer { virtual void send(std::vector& msgs, SendCallback* sendCallback) = 0; virtual void send(std::vector& msgs, SendCallback* sendCallback, long timeout) = 0; virtual void send(std::vector& msgs, const MQMessageQueue& mq, SendCallback* sendCallback) = 0; - virtual void send(std::vector& msgs, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) = 0; + virtual void send(std::vector& msgs, + const MQMessageQueue& mq, + SendCallback* sendCallback, + long timeout) = 0; // RPC virtual MQMessage request(MQMessage& msg, long timeout) = 0; diff --git a/src/producer/DefaultMQProducer.cpp b/src/producer/DefaultMQProducer.cpp index 75deff0d0..9e4dedba9 100644 --- a/src/producer/DefaultMQProducer.cpp +++ b/src/producer/DefaultMQProducer.cpp @@ -52,6 +52,10 @@ void DefaultMQProducer::shutdown() { producer_impl_->shutdown(); } +std::vector DefaultMQProducer::fetchPublishMessageQueues(const std::string& topic) { + return producer_impl_->fetchPublishMessageQueues(topic); +} + SendResult DefaultMQProducer::send(MQMessage& msg) { return producer_impl_->send(msg); } @@ -155,7 +159,10 @@ void DefaultMQProducer::send(std::vector& msgs, const MQMessageQueue& producer_impl_->send(msgs, mq, sendCallback); } -void DefaultMQProducer::send(std::vector& msgs, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) { +void DefaultMQProducer::send(std::vector& msgs, + const MQMessageQueue& mq, + SendCallback* sendCallback, + long timeout) { producer_impl_->send(msgs, mq, sendCallback, timeout); } diff --git a/src/producer/DefaultMQProducerImpl.cpp b/src/producer/DefaultMQProducerImpl.cpp index dd686cd80..4a2b69c38 100644 --- a/src/producer/DefaultMQProducerImpl.cpp +++ b/src/producer/DefaultMQProducerImpl.cpp @@ -18,6 +18,7 @@ #include #include +#include "MQMessageQueue.h" #ifndef WIN32 #include @@ -40,6 +41,7 @@ #include "RequestFutureTable.h" #include "TopicPublishInfo.hpp" #include "TransactionMQProducer.h" +#include "UtilAll.h" #include "Validators.h" #include "protocol/header/CommandHeader.h" @@ -159,6 +161,15 @@ void DefaultMQProducerImpl::shutdown() { } } +std::vector DefaultMQProducerImpl::fetchPublishMessageQueues(const std::string& topic) { + auto topicPublishInfo = client_instance_->tryToFindTopicPublishInfo(topic); + if (topicPublishInfo != nullptr) { + return topicPublishInfo->getMessageQueueList(); + } else { + return std::vector{}; + } +} + SendResult DefaultMQProducerImpl::send(MQMessage& msg) { return send(msg, dynamic_cast(client_config_.get())->send_msg_timeout()); } diff --git a/src/producer/DefaultMQProducerImpl.h b/src/producer/DefaultMQProducerImpl.h index f1325655a..da96df5ee 100644 --- a/src/producer/DefaultMQProducerImpl.h +++ b/src/producer/DefaultMQProducerImpl.h @@ -63,6 +63,8 @@ class DefaultMQProducerImpl : public std::enable_shared_from_this fetchPublishMessageQueues(const std::string& topic) override; + // Sync: caller will be responsible for the lifecycle of messages. SendResult send(MQMessage& msg) override; SendResult send(MQMessage& msg, long timeout) override; From 88d4eebe933f2f96daf01f25828057066fa722bf Mon Sep 17 00:00:00 2001 From: James Yin Date: Wed, 20 Jan 2021 16:48:55 +0800 Subject: [PATCH 39/62] fix: RebalanceImpl::lock --- src/consumer/RebalanceImpl.cpp | 48 ++++++++++++++++------------------ 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/src/consumer/RebalanceImpl.cpp b/src/consumer/RebalanceImpl.cpp index 75c6646a9..f890ea9e5 100644 --- a/src/consumer/RebalanceImpl.cpp +++ b/src/consumer/RebalanceImpl.cpp @@ -47,15 +47,15 @@ void RebalanceImpl::unlock(const MQMessageQueue& mq, const bool oneway) { try { client_instance_->getMQClientAPIImpl()->unlockBatchMQ(findBrokerResult->broker_addr(), unlockBatchRequest.get(), - 1000); + 1000, oneway); ProcessQueuePtr processQueue = getProcessQueue(mq); - if (processQueue) { + if (processQueue != nullptr) { processQueue->set_locked(false); - LOG_INFO_NEW("the message queue unlock OK, mq:{}", mq.toString()); - } else { - LOG_ERROR_NEW("the message queue unlock Failed, mq:{}", mq.toString()); } + + LOG_WARN_NEW("unlock messageQueue. group:{}, clientId:{}, mq:{}", consumer_group_, + client_instance_->getClientId(), mq.toString()); } catch (MQException& e) { LOG_ERROR_NEW("unlockBatchMQ exception, mq:{}", mq.toString()); } @@ -86,14 +86,12 @@ void RebalanceImpl::unlockAll(const bool oneway) { try { client_instance_->getMQClientAPIImpl()->unlockBatchMQ(findBrokerResult->broker_addr(), unlockBatchRequest.get(), - 1000); + 1000, oneway); for (const auto& mq : mqs) { ProcessQueuePtr processQueue = getProcessQueue(mq); - if (processQueue) { + if (processQueue != nullptr) { processQueue->set_locked(false); - LOG_INFO_NEW("the message queue unlock OK, mq:{}", mq.toString()); - } else { - LOG_ERROR_NEW("the message queue unlock Failed, mq:{}", mq.toString()); + LOG_INFO_NEW("the message queue unlock OK, Group: {} {}", consumer_group_, mq.toString()); } } } catch (MQException& e) { @@ -139,27 +137,24 @@ bool RebalanceImpl::lock(const MQMessageQueue& mq) { if (!lockedMq.empty()) { for (const auto& mmqq : lockedMq) { ProcessQueuePtr processQueue = getProcessQueue(mq); - if (processQueue) { + if (processQueue != nullptr) { processQueue->set_locked(true); processQueue->set_last_lock_timestamp(UtilAll::currentTimeMillis()); + } + + if (mmqq == mq) { lockOK = true; - LOG_INFO_NEW("the message queue locked OK, mq:{}", mmqq.toString()); - } else { - LOG_WARN_NEW("the message queue locked OK, but it is released, mq:{}", mmqq.toString()); } } - - lockedMq.clear(); - } else { - LOG_ERROR_NEW("the message queue locked Failed, mq:{}", mq.toString()); } + LOG_INFO_NEW("the message queue lock {}, {} {}", lockOK ? "OK" : "Failed", consumer_group_, mq.toString()); return lockOK; } catch (MQException& e) { LOG_ERROR_NEW("lockBatchMQ exception, mq:{}", mq.toString()); } } else { - LOG_ERROR_NEW("lock findBrokerAddressInSubscribe ret null for broker:{}", mq.broker_name()); + LOG_ERROR_NEW("lock: findBrokerAddressInSubscribe() returen null for broker:{}", mq.broker_name()); } return false; @@ -196,21 +191,22 @@ void RebalanceImpl::lockAll() { lockOKMQSet.insert(mq); ProcessQueuePtr processQueue = getProcessQueue(mq); - if (processQueue) { + if (processQueue != nullptr) { + if (!processQueue->locked()) { + LOG_INFO_NEW("the message queue locked OK, Group: {} {}", consumer_group_, mq.toString()); + } + processQueue->set_locked(true); processQueue->set_last_lock_timestamp(UtilAll::currentTimeMillis()); - LOG_INFO_NEW("the message queue locked OK, mq:{}", mq.toString()); - } else { - LOG_WARN_NEW("the message queue locked OK, but it is released, mq:{}", mq.toString()); } } for (const auto& mq : mqs) { if (lockOKMQSet.find(mq) == lockOKMQSet.end()) { ProcessQueuePtr processQueue = getProcessQueue(mq); - if (processQueue) { - LOG_WARN_NEW("the message queue locked Failed, mq:{}", mq.toString()); + if (processQueue != nullptr) { processQueue->set_locked(false); + LOG_WARN_NEW("the message queue locked Failed, Group: {} {}", consumer_group_, mq.toString()); } } } @@ -218,7 +214,7 @@ void RebalanceImpl::lockAll() { LOG_ERROR_NEW("lockBatchMQ fails"); } } else { - LOG_ERROR_NEW("lockAll findBrokerAddressInSubscribe ret null for broker:{}", brokerName); + LOG_ERROR_NEW("lockAll: findBrokerAddressInSubscribe() return null for broker:{}", brokerName); } } } From bfae5c2f10a9f7dd5c73c07c57adb229e467c99f Mon Sep 17 00:00:00 2001 From: James Yin Date: Fri, 29 Jan 2021 18:45:20 +0800 Subject: [PATCH 40/62] fix(example): error timeout in OrderlyProducer --- example/OrderlyProducer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/example/OrderlyProducer.cpp b/example/OrderlyProducer.cpp index 5c555ee2f..e69eb047a 100644 --- a/example/OrderlyProducer.cpp +++ b/example/OrderlyProducer.cpp @@ -15,6 +15,7 @@ * limitations under the License. */ #include "common.h" + #include "DefaultMQProducer.h" using namespace rocketmq; @@ -40,7 +41,7 @@ void ProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* produc try { auto start = std::chrono::system_clock::now(); int orderId = 1; - SendResult sendResult = producer->send(msg, &g_mySelector, static_cast(&orderId), info->retrytimes); + SendResult sendResult = producer->send(msg, &g_mySelector, static_cast(&orderId)); auto end = std::chrono::system_clock::now(); g_tps.Increment(); From 6ebfe4ce2e8dd815a36f0a76777f63acaebf4b10 Mon Sep 17 00:00:00 2001 From: James Yin Date: Fri, 26 Feb 2021 15:28:23 +0800 Subject: [PATCH 41/62] fix: re-throw exception --- example/AsyncProducer.cpp | 2 +- src/MQClientAPIImpl.cpp | 4 ++-- src/producer/DefaultMQProducerImpl.cpp | 10 +++++----- src/transport/TcpRemotingClient.cpp | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/example/AsyncProducer.cpp b/example/AsyncProducer.cpp index cee48edae..6fe5459a6 100644 --- a/example/AsyncProducer.cpp +++ b/example/AsyncProducer.cpp @@ -58,7 +58,7 @@ void AsyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* p producer->send(msg, callback); // auto delete } catch (std::exception& e) { std::cout << "[BUG]:" << e.what() << std::endl; - throw e; + throw; } } } diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index b25f672bb..91c6dc1e5 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -167,7 +167,7 @@ void MQClientAPIImpl::sendMessageAsync(const std::string& addr, sendMessageAsyncImpl(cbw, timeoutMillis); } catch (RemotingException& e) { deleteAndZero(cbw); - throw e; + throw; } } @@ -268,7 +268,7 @@ void MQClientAPIImpl::pullMessageAsync(const std::string& addr, remoting_client_->invokeAsync(addr, request, cbw, timeoutMillis); } catch (RemotingException& e) { deleteAndZero(cbw); - throw e; + throw; } } diff --git a/src/producer/DefaultMQProducerImpl.cpp b/src/producer/DefaultMQProducerImpl.cpp index 4a2b69c38..d3ab73ccd 100644 --- a/src/producer/DefaultMQProducerImpl.cpp +++ b/src/producer/DefaultMQProducerImpl.cpp @@ -180,7 +180,7 @@ SendResult DefaultMQProducerImpl::send(MQMessage& msg, long timeout) { return *sendResult; } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); - throw e; + throw; } } @@ -200,7 +200,7 @@ SendResult DefaultMQProducerImpl::send(MQMessage& msg, const MQMessageQueue& mq, return *sendResult; } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); - throw e; + throw; } } @@ -292,7 +292,7 @@ SendResult DefaultMQProducerImpl::send(MQMessage& msg, MessageQueueSelector* sel return *result.get(); } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); - throw e; + throw; } } @@ -345,7 +345,7 @@ TransactionSendResult DefaultMQProducerImpl::sendMessageInTransaction(MQMessage& return *sendResult; } catch (MQException& e) { LOG_ERROR_NEW("sendMessageInTransaction failed, exception:{}", e.what()); - throw e; + throw; } } @@ -774,7 +774,7 @@ SendResult* DefaultMQProducerImpl::sendKernelImpl(MessagePtr msg, return sendResult; } catch (MQException& e) { - throw e; + throw; } } diff --git a/src/transport/TcpRemotingClient.cpp b/src/transport/TcpRemotingClient.cpp index 7c3b5c241..c6c222d7c 100644 --- a/src/transport/TcpRemotingClient.cpp +++ b/src/transport/TcpRemotingClient.cpp @@ -231,7 +231,7 @@ std::unique_ptr TcpRemotingClient::invokeSync(const std::string } catch (const RemotingSendRequestException& e) { LOG_WARN_NEW("invokeSync: send request exception, so close the channel[{}]", channel->getPeerAddrAndPort()); CloseTransport(addr, channel); - throw e; + throw; } catch (const RemotingTimeoutException& e) { int code = request.code(); if (code != GET_CONSUMER_LIST_BY_GROUP) { @@ -240,7 +240,7 @@ std::unique_ptr TcpRemotingClient::invokeSync(const std::string channel->getPeerAddrAndPort()); } LOG_WARN_NEW("invokeSync: wait response timeout exception, the channel[{}]", channel->getPeerAddrAndPort()); - throw e; + throw; } } else { THROW_MQEXCEPTION(RemotingConnectException, "connect to <" + addr + "> failed", -1); @@ -294,7 +294,7 @@ void TcpRemotingClient::invokeAsync(const std::string& addr, } catch (const RemotingSendRequestException& e) { LOG_WARN_NEW("invokeAsync: send request exception, so close the channel[{}]", channel->getPeerAddrAndPort()); CloseTransport(addr, channel); - throw e; + throw; } } else { THROW_MQEXCEPTION(RemotingConnectException, "connect to <" + addr + "> failed", -1); @@ -343,7 +343,7 @@ void TcpRemotingClient::invokeOneway(const std::string& addr, RemotingCommand& r } catch (const RemotingSendRequestException& e) { LOG_WARN_NEW("invokeOneway: send request exception, so close the channel[{}]", channel->getPeerAddrAndPort()); CloseTransport(addr, channel); - throw e; + throw; } } else { THROW_MQEXCEPTION(RemotingConnectException, "connect to <" + addr + "> failed", -1); From 5d66df7d840e5675f3e4151e554adbe924320e78 Mon Sep 17 00:00:00 2001 From: James Yin Date: Wed, 3 Mar 2021 04:55:15 +0800 Subject: [PATCH 42/62] refactor: auto delete callback after invokes it --- include/PullCallback.h | 17 +++++++++++++++ include/RequestCallback.h | 17 +++++++++++++++ include/SendCallback.h | 17 +++++++++++++++ src/common/PullCallbackWrap.cpp | 11 +++------- src/common/SendCallbackWrap.cpp | 30 +++++--------------------- src/producer/DefaultMQProducerImpl.cpp | 15 +++---------- src/producer/RequestResponseFuture.cpp | 9 ++------ 7 files changed, 64 insertions(+), 52 deletions(-) diff --git a/include/PullCallback.h b/include/PullCallback.h index 7eb63ef00..08deacab9 100755 --- a/include/PullCallback.h +++ b/include/PullCallback.h @@ -35,6 +35,23 @@ class ROCKETMQCLIENT_API PullCallback { virtual void onException(MQException& e) noexcept = 0; virtual PullCallbackType getPullCallbackType() const { return PULL_CALLBACK_TYPE_SIMPLE; } + + public: + inline void invokeOnSuccess(std::unique_ptr pull_result) { + auto type = getPullCallbackType(); + onSuccess(std::move(pull_result)); + if (type == PULL_CALLBACK_TYPE_AUTO_DELETE && getPullCallbackType() == PULL_CALLBACK_TYPE_AUTO_DELETE) { + delete this; + } + } + + inline void invokeOnException(MQException& exception) noexcept { + auto type = getPullCallbackType(); + onException(exception); + if (type == PULL_CALLBACK_TYPE_AUTO_DELETE && getPullCallbackType() == PULL_CALLBACK_TYPE_AUTO_DELETE) { + delete this; + } + } }; /** diff --git a/include/RequestCallback.h b/include/RequestCallback.h index a6dfec4ed..c666ccc1a 100644 --- a/include/RequestCallback.h +++ b/include/RequestCallback.h @@ -35,6 +35,23 @@ class ROCKETMQCLIENT_API RequestCallback { virtual void onException(MQException& e) noexcept = 0; virtual RequestCallbackType getRequestCallbackType() const { return REQUEST_CALLBACK_TYPE_SIMPLE; } + + public: + inline void invokeOnSuccess(MQMessage message) { + auto type = getRequestCallbackType(); + onSuccess(std::move(message)); + if (type == REQUEST_CALLBACK_TYPE_AUTO_DELETE && getRequestCallbackType() == REQUEST_CALLBACK_TYPE_AUTO_DELETE) { + delete this; + } + } + + inline void invokeOnException(MQException& exception) noexcept { + auto type = getRequestCallbackType(); + onException(exception); + if (type == REQUEST_CALLBACK_TYPE_AUTO_DELETE && getRequestCallbackType() == REQUEST_CALLBACK_TYPE_AUTO_DELETE) { + delete this; + } + } }; /** diff --git a/include/SendCallback.h b/include/SendCallback.h index 480189142..9191c2572 100755 --- a/include/SendCallback.h +++ b/include/SendCallback.h @@ -35,6 +35,23 @@ class ROCKETMQCLIENT_API SendCallback { virtual void onException(MQException& e) noexcept = 0; virtual SendCallbackType getSendCallbackType() const { return SEND_CALLBACK_TYPE_SIMPLE; } + + public: + inline void invokeOnSuccess(SendResult& send_result) { + auto type = getSendCallbackType(); + onSuccess(send_result); + if (type == SEND_CALLBACK_TYPE_AUTO_DELETE && getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { + delete this; + } + } + + inline void invokeOnException(MQException& exception) noexcept { + auto type = getSendCallbackType(); + onException(exception); + if (type == SEND_CALLBACK_TYPE_AUTO_DELETE && getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { + delete this; + } + } }; /** diff --git a/src/common/PullCallbackWrap.cpp b/src/common/PullCallbackWrap.cpp index b23970b0f..bc915a410 100644 --- a/src/common/PullCallbackWrap.cpp +++ b/src/common/PullCallbackWrap.cpp @@ -33,9 +33,9 @@ void PullCallbackWrap::operationComplete(ResponseFuture* responseFuture) noexcep try { std::unique_ptr pull_result(client_api_impl_->processPullResponse(response.get())); assert(pull_result != nullptr); - pull_callback_->onSuccess(std::move(pull_result)); + pull_callback_->invokeOnSuccess(std::move(pull_result)); } catch (MQException& e) { - pull_callback_->onException(e); + pull_callback_->invokeOnException(e); } } else { std::string err; @@ -47,12 +47,7 @@ void PullCallbackWrap::operationComplete(ResponseFuture* responseFuture) noexcep err = "unknown reason"; } MQException exception(err, -1, __FILE__, __LINE__); - pull_callback_->onException(exception); - } - - // auto delete callback - if (pull_callback_->getPullCallbackType() == PULL_CALLBACK_TYPE_AUTO_DELETE) { - deleteAndZero(pull_callback_); + pull_callback_->invokeOnException(exception); } } diff --git a/src/common/SendCallbackWrap.cpp b/src/common/SendCallbackWrap.cpp index 8763be157..92fd6e10f 100644 --- a/src/common/SendCallbackWrap.cpp +++ b/src/common/SendCallbackWrap.cpp @@ -22,9 +22,9 @@ #include "Logging.h" #include "MQClientAPIImpl.h" #include "MQClientInstance.h" -#include "MessageDecoder.h" #include "MQMessageQueue.h" #include "MQProtos.h" +#include "MessageDecoder.h" #include "PullAPIWrapper.h" #include "PullResultExt.hpp" #include "TopicPublishInfo.hpp" @@ -57,12 +57,7 @@ void SendCallbackWrap::operationComplete(ResponseFuture* responseFuture) noexcep auto producer = producer_.lock(); if (nullptr == producer) { MQException exception("DefaultMQProducer is released.", -1, __FILE__, __LINE__); - send_callback_->onException(exception); - - // auto delete callback - if (send_callback_->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { - deleteAndZero(send_callback_); - } + send_callback_->invokeOnException(exception); return; } @@ -99,16 +94,11 @@ void SendCallbackWrap::operationComplete(ResponseFuture* responseFuture) noexcep // } try { - send_callback_->onSuccess(*sendResult); + send_callback_->invokeOnSuccess(*sendResult); } catch (...) { } producer->updateFaultItem(broker_name_, UtilAll::currentTimeMillis() - responseFuture->begin_timestamp(), false); - - // auto delete callback - if (send_callback_->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { - deleteAndZero(send_callback_); - } } catch (MQException& e) { producer->updateFaultItem(broker_name_, UtilAll::currentTimeMillis() - responseFuture->begin_timestamp(), true); LOG_ERROR("operationComplete: processSendResponse exception: %s", e.what()); @@ -136,12 +126,7 @@ void SendCallbackWrap::onExceptionImpl(ResponseFuture* responseFuture, auto producer = producer_.lock(); if (nullptr == producer) { MQException exception("DefaultMQProducer is released.", -1, __FILE__, __LINE__); - send_callback_->onException(exception); - - // auto delete callback - if (send_callback_->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { - deleteAndZero(send_callback_); - } + send_callback_->invokeOnException(exception); return; } @@ -180,12 +165,7 @@ void SendCallbackWrap::onExceptionImpl(ResponseFuture* responseFuture, return onExceptionImpl(responseFuture, responseFuture->leftTime(), e1, true); } } else { - send_callback_->onException(e); - - // auto delete callback - if (send_callback_->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { - deleteAndZero(send_callback_); - } + send_callback_->invokeOnException(e); } } diff --git a/src/producer/DefaultMQProducerImpl.cpp b/src/producer/DefaultMQProducerImpl.cpp index d3ab73ccd..20704f8f4 100644 --- a/src/producer/DefaultMQProducerImpl.cpp +++ b/src/producer/DefaultMQProducerImpl.cpp @@ -213,10 +213,7 @@ void DefaultMQProducerImpl::send(MQMessage& msg, SendCallback* sendCallback, lon (void)sendDefaultImpl(msg.getMessageImpl(), ASYNC, sendCallback, timeout); } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); - sendCallback->onException(e); - if (sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { - deleteAndZero(sendCallback); - } + sendCallback->invokeOnException(e); } catch (std::exception& e) { LOG_FATAL_NEW("[BUG] encounter unexcepted exception: {}", e.what()); exit(-1); @@ -246,10 +243,7 @@ void DefaultMQProducerImpl::send(MQMessage& msg, } } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); - sendCallback->onException(e); - if (sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { - deleteAndZero(sendCallback); - } + sendCallback->invokeOnException(e); } catch (std::exception& e) { LOG_FATAL_NEW("[BUG] encounter unexcepted exception: {}", e.what()); exit(-1); @@ -318,10 +312,7 @@ void DefaultMQProducerImpl::send(MQMessage& msg, } } catch (MQException& e) { LOG_ERROR_NEW("send failed, exception:{}", e.what()); - sendCallback->onException(e); - if (sendCallback->getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { - deleteAndZero(sendCallback); - } + sendCallback->invokeOnException(e); } catch (std::exception& e) { LOG_FATAL_NEW("[BUG] encounter unexcepted exception: {}", e.what()); exit(-1); diff --git a/src/producer/RequestResponseFuture.cpp b/src/producer/RequestResponseFuture.cpp index 5bdcd61cc..615d27b33 100644 --- a/src/producer/RequestResponseFuture.cpp +++ b/src/producer/RequestResponseFuture.cpp @@ -42,7 +42,7 @@ void RequestResponseFuture::executeRequestCallback() noexcept { if (request_callback_ != nullptr) { if (send_request_ok_ && cause_ == nullptr) { try { - request_callback_->onSuccess(std::move(response_msg_)); + request_callback_->invokeOnSuccess(std::move(response_msg_)); } catch (const std::exception& e) { LOG_WARN_NEW("RequestCallback throw an exception: {}", e.what()); } @@ -50,16 +50,11 @@ void RequestResponseFuture::executeRequestCallback() noexcept { try { std::rethrow_exception(cause_); } catch (MQException& e) { - request_callback_->onException(e); + request_callback_->invokeOnException(e); } catch (const std::exception& e) { LOG_WARN_NEW("unexpected exception in RequestResponseFuture: {}", e.what()); } } - - // auto delete callback - if (request_callback_->getRequestCallbackType() == REQUEST_CALLBACK_TYPE_AUTO_DELETE) { - deleteAndZero(request_callback_); - } } } From 726b7dc424e798d917d4f29b2639242633e3bd56 Mon Sep 17 00:00:00 2001 From: James Yin Date: Wed, 10 Mar 2021 15:34:49 +0800 Subject: [PATCH 43/62] refactor: invoke async send in executor --- include/DefaultMQProducerConfig.h | 25 ++-- include/DefaultMQProducerConfigProxy.h | 41 ++++--- src/producer/DefaultMQProducerConfigImpl.hpp | 34 ++++-- src/producer/DefaultMQProducerImpl.cpp | 119 ++++++++++++------- src/producer/DefaultMQProducerImpl.h | 2 + 5 files changed, 136 insertions(+), 85 deletions(-) diff --git a/include/DefaultMQProducerConfig.h b/include/DefaultMQProducerConfig.h index 46f9c2f86..67c723192 100644 --- a/include/DefaultMQProducerConfig.h +++ b/include/DefaultMQProducerConfig.h @@ -32,36 +32,39 @@ class ROCKETMQCLIENT_API DefaultMQProducerConfig : virtual public MQClientConfig public: virtual ~DefaultMQProducerConfig() = default; - // if msgbody size larger than maxMsgBodySize, exception will be throwed + virtual int async_send_thread_nums() const = 0; + virtual void set_async_send_thread_nums(int async_send_thread_nums) = 0; + + // if msgbody size larger than max_message_size, exception will be throwed virtual int max_message_size() const = 0; - virtual void set_max_message_size(int maxMessageSize) = 0; + virtual void set_max_message_size(int max_message_size) = 0; /* - * if msgBody size is large than m_compressMsgBodyOverHowmuch - * rocketmq cpp will compress msgBody according to compressLevel + * if msgBody size is large than compress_msg_body_over_howmuch, + * sdk will compress message body according to compress_level */ virtual int compress_msg_body_over_howmuch() const = 0; - virtual void set_compress_msg_body_over_howmuch(int compressMsgBodyOverHowmuch) = 0; + virtual void set_compress_msg_body_over_howmuch(int compress_msg_body_over_howmuch) = 0; virtual int compress_level() const = 0; - virtual void set_compress_level(int compressLevel) = 0; + virtual void set_compress_level(int compress_level) = 0; // set and get timeout of per msg virtual int send_msg_timeout() const = 0; - virtual void set_send_msg_timeout(int sendMsgTimeout) = 0; + virtual void set_send_msg_timeout(int send_msg_timeout) = 0; // set msg max retry times, default retry times is 5 virtual int retry_times() const = 0; - virtual void set_retry_times(int times) = 0; + virtual void set_retry_times(int retry_times) = 0; virtual int retry_times_for_async() const = 0; - virtual void set_retry_times_for_async(int times) = 0; + virtual void set_retry_times_for_async(int retry_times) = 0; virtual bool retry_another_broker_when_not_store_ok() const = 0; - virtual void set_retry_another_broker_when_not_store_ok(bool retryAnotherBrokerWhenNotStoreOK) = 0; + virtual void set_retry_another_broker_when_not_store_ok(bool retry_another_broker_when_not_store_ok) = 0; virtual bool send_latency_fault_enable() const { return false; }; - virtual void set_send_latency_fault_enable(bool sendLatencyFaultEnable){}; + virtual void set_send_latency_fault_enable(bool send_latency_fault_enable){}; }; } // namespace rocketmq diff --git a/include/DefaultMQProducerConfigProxy.h b/include/DefaultMQProducerConfigProxy.h index b879b43f6..8870e989a 100644 --- a/include/DefaultMQProducerConfigProxy.h +++ b/include/DefaultMQProducerConfigProxy.h @@ -32,70 +32,79 @@ class ROCKETMQCLIENT_API DefaultMQProducerConfigProxy : public MQClientConfigPro DefaultMQProducerConfigProxy(DefaultMQProducerConfigPtr producerConfig) : MQClientConfigProxy(producerConfig) {} virtual ~DefaultMQProducerConfigProxy() = default; + int async_send_thread_nums() const override { + return dynamic_cast(client_config_.get())->async_send_thread_nums(); + } + + void set_async_send_thread_nums(int async_send_thread_nums) override { + dynamic_cast(client_config_.get())->set_async_send_thread_nums(async_send_thread_nums); + } + int max_message_size() const override { return dynamic_cast(client_config_.get())->max_message_size(); } - void set_max_message_size(int maxMessageSize) override { - dynamic_cast(client_config_.get())->set_max_message_size(maxMessageSize); + void set_max_message_size(int max_message_size) override { + dynamic_cast(client_config_.get())->set_max_message_size(max_message_size); } int compress_msg_body_over_howmuch() const override { return dynamic_cast(client_config_.get())->compress_msg_body_over_howmuch(); } - void set_compress_msg_body_over_howmuch(int compressMsgBodyOverHowmuch) override { + void set_compress_msg_body_over_howmuch(int compress_msg_body_over_howmuch) override { dynamic_cast(client_config_.get()) - ->set_compress_msg_body_over_howmuch(compressMsgBodyOverHowmuch); + ->set_compress_msg_body_over_howmuch(compress_msg_body_over_howmuch); } int compress_level() const override { return dynamic_cast(client_config_.get())->compress_level(); } - void set_compress_level(int compressLevel) override { - dynamic_cast(client_config_.get())->set_compress_level(compressLevel); + void set_compress_level(int compress_level) override { + dynamic_cast(client_config_.get())->set_compress_level(compress_level); } int send_msg_timeout() const override { return dynamic_cast(client_config_.get())->send_msg_timeout(); } - void set_send_msg_timeout(int sendMsgTimeout) override { - dynamic_cast(client_config_.get())->set_send_msg_timeout(sendMsgTimeout); + void set_send_msg_timeout(int send_msg_timeout) override { + dynamic_cast(client_config_.get())->set_send_msg_timeout(send_msg_timeout); } int retry_times() const override { return dynamic_cast(client_config_.get())->retry_times(); } - void set_retry_times(int times) override { - dynamic_cast(client_config_.get())->set_retry_times(times); + void set_retry_times(int retry_times) override { + dynamic_cast(client_config_.get())->set_retry_times(retry_times); } int retry_times_for_async() const override { return dynamic_cast(client_config_.get())->retry_times_for_async(); } - void set_retry_times_for_async(int times) override { - dynamic_cast(client_config_.get())->set_retry_times_for_async(times); + void set_retry_times_for_async(int retry_times) override { + dynamic_cast(client_config_.get())->set_retry_times_for_async(retry_times); } bool retry_another_broker_when_not_store_ok() const override { return dynamic_cast(client_config_.get())->retry_another_broker_when_not_store_ok(); } - void set_retry_another_broker_when_not_store_ok(bool retryAnotherBrokerWhenNotStoreOK) override { + void set_retry_another_broker_when_not_store_ok(bool retry_another_broker_when_not_store_ok) override { dynamic_cast(client_config_.get()) - ->set_retry_another_broker_when_not_store_ok(retryAnotherBrokerWhenNotStoreOK); + ->set_retry_another_broker_when_not_store_ok(retry_another_broker_when_not_store_ok); } bool send_latency_fault_enable() const override { return dynamic_cast(client_config_.get())->send_latency_fault_enable(); } - void set_send_latency_fault_enable(bool sendLatencyFaultEnable) override { - dynamic_cast(client_config_.get())->set_send_latency_fault_enable(sendLatencyFaultEnable); + void set_send_latency_fault_enable(bool send_latency_fault_enable) override { + dynamic_cast(client_config_.get()) + ->set_send_latency_fault_enable(send_latency_fault_enable); } inline DefaultMQProducerConfigPtr real_config() const { diff --git a/src/producer/DefaultMQProducerConfigImpl.hpp b/src/producer/DefaultMQProducerConfigImpl.hpp index 5b1f78d3b..00f3efffc 100644 --- a/src/producer/DefaultMQProducerConfigImpl.hpp +++ b/src/producer/DefaultMQProducerConfigImpl.hpp @@ -18,6 +18,7 @@ #define ROCKETMQ_PRODUCER_DEFAULTMQPRODUCERCONFIGIMPL_HPP_ #include // std::min, std::max +#include #include "DefaultMQProducerConfig.h" #include "MQClientConfigImpl.hpp" @@ -30,7 +31,8 @@ namespace rocketmq { class DefaultMQProducerConfigImpl : virtual public DefaultMQProducerConfig, public MQClientConfigImpl { public: DefaultMQProducerConfigImpl() - : max_message_size_(1024 * 1024 * 4), // 4MB + : async_send_thread_nums_(std::min(4, (int)std::thread::hardware_concurrency())), + max_message_size_(1024 * 1024 * 4), // 4MB compress_msg_body_over_howmuch_(1024 * 4), // 4KB compress_level_(5), send_msg_timeout_(3000), @@ -40,36 +42,44 @@ class DefaultMQProducerConfigImpl : virtual public DefaultMQProducerConfig, publ virtual ~DefaultMQProducerConfigImpl() = default; + int async_send_thread_nums() const override { return async_send_thread_nums_; } + void set_async_send_thread_nums(int async_send_thread_nums) override { + async_send_thread_nums_ = async_send_thread_nums; + } + int max_message_size() const override { return max_message_size_; } - void set_max_message_size(int maxMessageSize) override { max_message_size_ = maxMessageSize; } + void set_max_message_size(int max_message_size) override { max_message_size_ = max_message_size; } int compress_msg_body_over_howmuch() const override { return compress_msg_body_over_howmuch_; } - void set_compress_msg_body_over_howmuch(int compressMsgBodyOverHowmuch) override { - compress_msg_body_over_howmuch_ = compressMsgBodyOverHowmuch; + void set_compress_msg_body_over_howmuch(int compress_msg_body_over_howmuch) override { + compress_msg_body_over_howmuch_ = compress_msg_body_over_howmuch; } int compress_level() const override { return compress_level_; } - void set_compress_level(int compressLevel) override { - if ((compressLevel >= 0 && compressLevel <= 9) || compressLevel == -1) { - compress_level_ = compressLevel; + void set_compress_level(int compress_level) override { + if ((compress_level >= 0 && compress_level <= 9) || compress_level == -1) { + compress_level_ = compress_level; } } int send_msg_timeout() const override { return send_msg_timeout_; } - void set_send_msg_timeout(int sendMsgTimeout) override { send_msg_timeout_ = sendMsgTimeout; } + void set_send_msg_timeout(int send_msg_timeout) override { send_msg_timeout_ = send_msg_timeout; } int retry_times() const override { return retry_times_; } - void set_retry_times(int times) override { retry_times_ = std::min(std::max(0, times), 15); } + void set_retry_times(int retry_times) override { retry_times_ = std::min(std::max(0, retry_times), 15); } int retry_times_for_async() const override { return retry_times_for_async_; } - void set_retry_times_for_async(int times) override { retry_times_for_async_ = std::min(std::max(0, times), 15); } + void set_retry_times_for_async(int retry_times) override { + retry_times_for_async_ = std::min(std::max(0, retry_times), 15); + } bool retry_another_broker_when_not_store_ok() const override { return retry_another_broker_when_not_store_ok_; } - void set_retry_another_broker_when_not_store_ok(bool retryAnotherBrokerWhenNotStoreOK) override { - retry_another_broker_when_not_store_ok_ = retryAnotherBrokerWhenNotStoreOK; + void set_retry_another_broker_when_not_store_ok(bool retry_another_broker_when_not_store_ok) override { + retry_another_broker_when_not_store_ok_ = retry_another_broker_when_not_store_ok; } protected: + int async_send_thread_nums_; int max_message_size_; // default: 4 MB int compress_msg_body_over_howmuch_; // default: 4 KB int compress_level_; diff --git a/src/producer/DefaultMQProducerImpl.cpp b/src/producer/DefaultMQProducerImpl.cpp index 20704f8f4..ade43d1ac 100644 --- a/src/producer/DefaultMQProducerImpl.cpp +++ b/src/producer/DefaultMQProducerImpl.cpp @@ -29,14 +29,14 @@ #include "CorrelationIdUtil.hpp" #include "Logging.h" #include "MQClientAPIImpl.h" -#include "MQException.h" #include "MQClientInstance.h" #include "MQClientManager.h" -#include "MessageDecoder.h" +#include "MQException.h" #include "MQFaultStrategy.h" #include "MQProtos.h" #include "MessageBatch.h" #include "MessageClientIDSetter.h" +#include "MessageDecoder.h" #include "MessageSysFlag.h" #include "RequestFutureTable.h" #include "TopicPublishInfo.hpp" @@ -92,7 +92,10 @@ DefaultMQProducerImpl::DefaultMQProducerImpl(DefaultMQProducerConfigPtr config) : DefaultMQProducerImpl(config, nullptr) {} DefaultMQProducerImpl::DefaultMQProducerImpl(DefaultMQProducerConfigPtr config, RPCHookPtr rpcHook) - : MQClientImpl(config, rpcHook), mq_fault_strategy_(new MQFaultStrategy()), check_transaction_executor_(nullptr) {} + : MQClientImpl(config, rpcHook), + mq_fault_strategy_(new MQFaultStrategy()), + async_send_executor_(nullptr), + check_transaction_executor_(nullptr) {} DefaultMQProducerImpl::~DefaultMQProducerImpl() = default; @@ -120,11 +123,19 @@ void DefaultMQProducerImpl::start() { dynamic_cast(client_config_.get())->group_name(), this); if (!registerOK) { service_state_ = CREATE_JUST; - THROW_MQEXCEPTION(MQClientException, "The producer group[" + client_config_->group_name() + - "] has been created before, specify another name please.", + THROW_MQEXCEPTION(MQClientException, + "The producer group[" + client_config_->group_name() + + "] has been created before, specify another name please.", -1); } + if (nullptr == async_send_executor_) { + async_send_executor_.reset(new thread_pool_executor( + "AsyncSendThread", dynamic_cast(client_config_.get())->async_send_thread_nums(), + false)); + } + async_send_executor_->startup(); + client_instance_->start(); LOG_INFO_NEW("the producer [{}] start OK.", client_config_->group_name()); @@ -147,6 +158,9 @@ void DefaultMQProducerImpl::shutdown() { switch (service_state_) { case RUNNING: { LOG_INFO("DefaultMQProducerImpl shutdown"); + + async_send_executor_->shutdown(); + client_instance_->unregisterProducer(client_config_->group_name()); client_instance_->shutdown(); @@ -209,15 +223,18 @@ void DefaultMQProducerImpl::send(MQMessage& msg, SendCallback* sendCallback) noe } void DefaultMQProducerImpl::send(MQMessage& msg, SendCallback* sendCallback, long timeout) noexcept { - try { - (void)sendDefaultImpl(msg.getMessageImpl(), ASYNC, sendCallback, timeout); - } catch (MQException& e) { - LOG_ERROR_NEW("send failed, exception:{}", e.what()); - sendCallback->invokeOnException(e); - } catch (std::exception& e) { - LOG_FATAL_NEW("[BUG] encounter unexcepted exception: {}", e.what()); - exit(-1); - } + auto msg_impl = msg.getMessageImpl(); + async_send_executor_->submit([this, msg_impl, sendCallback, timeout] { + try { + (void)sendDefaultImpl(msg_impl, ASYNC, sendCallback, timeout); + } catch (MQException& e) { + LOG_ERROR_NEW("send failed, exception:{}", e.what()); + sendCallback->invokeOnException(e); + } catch (std::exception& e) { + LOG_FATAL_NEW("[BUG] encounter unexcepted exception: {}", e.what()); + exit(-1); + } + }); } void DefaultMQProducerImpl::send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept { @@ -228,26 +245,30 @@ void DefaultMQProducerImpl::send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) noexcept { - try { - Validators::checkMessage(msg, dynamic_cast(client_config_.get())->max_message_size()); + auto msg_impl = msg.getMessageImpl(); + async_send_executor_->submit([this, msg_impl, mq, sendCallback, timeout] { + try { + Validators::checkMessage(*msg_impl, + dynamic_cast(client_config_.get())->max_message_size()); - if (msg.topic() != mq.topic()) { - THROW_MQEXCEPTION(MQClientException, "message's topic not equal mq's topic", -1); - } + if (msg_impl->topic() != mq.topic()) { + THROW_MQEXCEPTION(MQClientException, "message's topic not equal mq's topic", -1); + } - try { - sendKernelImpl(msg.getMessageImpl(), mq, ASYNC, sendCallback, nullptr, timeout); - } catch (MQBrokerException& e) { - std::string info = std::string("unknown exception, ") + e.what(); - THROW_MQEXCEPTION(MQClientException, info, e.GetError()); + try { + sendKernelImpl(msg_impl, mq, ASYNC, sendCallback, nullptr, timeout); + } catch (MQBrokerException& e) { + std::string info = std::string("unknown exception, ") + e.what(); + THROW_MQEXCEPTION(MQClientException, info, e.GetError()); + } + } catch (MQException& e) { + LOG_ERROR_NEW("send failed, exception:{}", e.what()); + sendCallback->invokeOnException(e); + } catch (std::exception& e) { + LOG_FATAL_NEW("[BUG] encounter unexcepted exception: {}", e.what()); + exit(-1); } - } catch (MQException& e) { - LOG_ERROR_NEW("send failed, exception:{}", e.what()); - sendCallback->invokeOnException(e); - } catch (std::exception& e) { - LOG_FATAL_NEW("[BUG] encounter unexcepted exception: {}", e.what()); - exit(-1); - } + }); } void DefaultMQProducerImpl::sendOneway(MQMessage& msg) { @@ -303,20 +324,23 @@ void DefaultMQProducerImpl::send(MQMessage& msg, void* arg, SendCallback* sendCallback, long timeout) noexcept { - try { + auto msg_impl = msg.getMessageImpl(); + async_send_executor_->submit([this, msg_impl, selector, arg, sendCallback, timeout] { try { - sendSelectImpl(msg.getMessageImpl(), selector, arg, ASYNC, sendCallback, timeout); - } catch (MQBrokerException& e) { - std::string info = std::string("unknown exception, ") + e.what(); - THROW_MQEXCEPTION(MQClientException, info, e.GetError()); + try { + sendSelectImpl(msg_impl, selector, arg, ASYNC, sendCallback, timeout); + } catch (MQBrokerException& e) { + std::string info = std::string("unknown exception, ") + e.what(); + THROW_MQEXCEPTION(MQClientException, info, e.GetError()); + } + } catch (MQException& e) { + LOG_ERROR_NEW("send failed, exception:{}", e.what()); + sendCallback->invokeOnException(e); + } catch (std::exception& e) { + LOG_FATAL_NEW("[BUG] encounter unexcepted exception: {}", e.what()); + exit(-1); } - } catch (MQException& e) { - LOG_ERROR_NEW("send failed, exception:{}", e.what()); - sendCallback->invokeOnException(e); - } catch (std::exception& e) { - LOG_FATAL_NEW("[BUG] encounter unexcepted exception: {}", e.what()); - exit(-1); - } + }); } void DefaultMQProducerImpl::sendOneway(MQMessage& msg, MessageQueueSelector* selector, void* arg) { @@ -375,7 +399,10 @@ void DefaultMQProducerImpl::send(std::vector& msgs, const MQMessageQu send(batchMessage, mq, sendCallback); } -void DefaultMQProducerImpl::send(std::vector& msgs, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) { +void DefaultMQProducerImpl::send(std::vector& msgs, + const MQMessageQueue& mq, + SendCallback* sendCallback, + long timeout) { MQMessage batchMessage(batch(msgs)); send(batchMessage, mq, sendCallback, timeout); } @@ -655,8 +682,8 @@ SendResult* DefaultMQProducerImpl::sendDefaultImpl(MessagePtr msg, } std::string info = "Send [" + UtilAll::to_string(times) + "] times, still failed, cost [" + - UtilAll::to_string(UtilAll::currentTimeMillis() - beginTimestampFirst) + "]ms, Topic: " + - msg->topic(); + UtilAll::to_string(UtilAll::currentTimeMillis() - beginTimestampFirst) + + "]ms, Topic: " + msg->topic(); THROW_MQEXCEPTION(MQClientException, info, -1); } diff --git a/src/producer/DefaultMQProducerImpl.h b/src/producer/DefaultMQProducerImpl.h index da96df5ee..57eef515d 100644 --- a/src/producer/DefaultMQProducerImpl.h +++ b/src/producer/DefaultMQProducerImpl.h @@ -22,6 +22,7 @@ #include "MQClientImpl.h" #include "MQProducerInner.h" #include "MessageBatch.h" +#include "concurrent/executor.hpp" namespace rocketmq { @@ -178,6 +179,7 @@ class DefaultMQProducerImpl : public std::enable_shared_from_this mq_fault_strategy_; + std::unique_ptr async_send_executor_; std::unique_ptr check_transaction_executor_; }; From 487dfeea6ba9974c9cead5b2e7037a63eb24b34e Mon Sep 17 00:00:00 2001 From: James Yin Date: Wed, 10 Mar 2021 19:14:58 +0800 Subject: [PATCH 44/62] refactor: Logging --- src/extern/CProducer.cpp | 7 +- src/extern/CPushConsumer.cpp | 7 +- src/log/Logging.cpp | 121 ++++++++++------------- src/log/Logging.h | 184 ++++++++++++++++++++++++++--------- 4 files changed, 201 insertions(+), 118 deletions(-) diff --git a/src/extern/CProducer.cpp b/src/extern/CProducer.cpp index 7629594a8..893143a8f 100644 --- a/src/extern/CProducer.cpp +++ b/src/extern/CProducer.cpp @@ -511,7 +511,9 @@ int SetProducerLogFileNumAndSize(CProducer* producer, int fileNum, long fileSize if (producer == NULL) { return NULL_POINTER; } - DEFAULT_LOGGER_INSTANCE->setLogFileNumAndSize(fileNum, fileSize); + auto& default_logger_config = GetDefaultLoggerConfig(); + default_logger_config.set_file_count(fileNum); + default_logger_config.set_file_size(fileSize); return OK; } @@ -519,7 +521,8 @@ int SetProducerLogLevel(CProducer* producer, CLogLevel level) { if (producer == NULL) { return NULL_POINTER; } - DEFAULT_LOGGER_INSTANCE->set_log_level((LogLevel)level); + auto& default_logger_config = GetDefaultLoggerConfig(); + default_logger_config.set_level(static_cast(level)); return OK; } diff --git a/src/extern/CPushConsumer.cpp b/src/extern/CPushConsumer.cpp index f90802e82..4beee3520 100644 --- a/src/extern/CPushConsumer.cpp +++ b/src/extern/CPushConsumer.cpp @@ -258,7 +258,9 @@ int SetPushConsumerLogFileNumAndSize(CPushConsumer* consumer, int fileNum, long if (consumer == NULL) { return NULL_POINTER; } - DEFAULT_LOGGER_INSTANCE->setLogFileNumAndSize(fileNum, fileSize); + auto& default_logger_config = GetDefaultLoggerConfig(); + default_logger_config.set_file_count(fileNum); + default_logger_config.set_file_size(fileSize); return OK; } @@ -266,6 +268,7 @@ int SetPushConsumerLogLevel(CPushConsumer* consumer, CLogLevel level) { if (consumer == NULL) { return NULL_POINTER; } - DEFAULT_LOGGER_INSTANCE->set_log_level((LogLevel)level); + auto& default_logger_config = GetDefaultLoggerConfig(); + default_logger_config.set_level(static_cast(level)); return OK; } diff --git a/src/log/Logging.cpp b/src/log/Logging.cpp index 7d291707f..6eb958ebd 100644 --- a/src/log/Logging.cpp +++ b/src/log/Logging.cpp @@ -17,6 +17,8 @@ #include "Logging.h" #include // std::cerr, std::endl +#include +#include #if SPDLOG_VER_MAJOR >= 1 #include @@ -29,30 +31,35 @@ namespace rocketmq { -Logger* Logger::getLoggerInstance() { - static Logger singleton_("default"); - return &singleton_; +static void ConfigSpdlog() { + spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [thread@%t] - %v [%@ (%!)]"); + // when an error occurred, flush disk immediately + spdlog::flush_on(spdlog::level::err); +#if SPDLOG_VER_MAJOR >= 1 + spdlog::init_thread_pool(spdlog::details::default_async_q_size, 1); + spdlog::flush_every(std::chrono::seconds(3)); +#else + spdlog::set_async_mode(8192, async_overflow_policy::block_retry, nullptr, std::chrono::milliseconds(3000), nullptr); +#endif } -Logger::Logger(const std::string& name) : log_level_(LOG_LEVEL_INFO) { - try { - init_log_dir_(); - init_spdlog_env_(); - logger_ = create_rotating_logger_(name, log_file_, 1024 * 1024 * 100, 3); - set_log_level_(log_level_); - } catch (std::exception& e) { - std::cerr << "initialite logger failed" << std::endl; - exit(-1); - } +static std::shared_ptr CreateRotatingLogger(const std::string& name, + const std::string& filepath, + std::size_t max_size, + std::size_t max_files) { +#if SPDLOG_VER_MAJOR >= 1 + return spdlog::create_async(name, filepath, max_size, max_files); +#else + return spdlog::rotating_logger_mt(name, filepath, max_size, max_files); +#endif } -Logger::~Logger() { - if (logger_ != nullptr) { - spdlog::drop(logger_->name()); - } +static spdlog::level::level_enum ConvertLogLevel(LogLevel log_level) { + int level = static_cast(log_level); + return static_cast(6 - level); } -void Logger::init_log_dir_() { +static std::string GetDefaultLogDir() { std::string log_dir; const char* dir = std::getenv(ROCKETMQ_CPP_LOG_DIR_ENV.c_str()); if (dir != nullptr && dir[0] != '\0') { @@ -66,64 +73,44 @@ void Logger::init_log_dir_() { log_dir += FILE_SEPARATOR; } std::string log_file_name = UtilAll::to_string(UtilAll::getProcessId()) + "_" + "rocketmq-cpp.log"; - log_file_ = log_dir + log_file_name; + return log_dir + log_file_name; } -void Logger::init_spdlog_env_() { - spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [thread@%t] - %v"); - // when an error occurred, flush disk immediately - spdlog::flush_on(spdlog::level::err); -#if SPDLOG_VER_MAJOR >= 1 - spdlog::init_thread_pool(spdlog::details::default_async_q_size, 1); - spdlog::flush_every(std::chrono::seconds(3)); -#else - spdlog::set_async_mode(8192, async_overflow_policy::block_retry, nullptr, std::chrono::milliseconds(3000), nullptr); -#endif +LoggerConfig& GetDefaultLoggerConfig() { + static LoggerConfig default_logger_config("default", GetDefaultLogDir()); + return default_logger_config; } -std::shared_ptr Logger::create_rotating_logger_(const std::string& name, - const std::string& filepath, - std::size_t max_size, - std::size_t max_files) { -#if SPDLOG_VER_MAJOR >= 1 - return spdlog::create_async(name, filepath, max_size, max_files); -#else - return spdlog::rotating_logger_mt(name, filepath, max_size, max_files); -#endif +static std::once_flag default_logger_init_flag; +static std::unique_ptr default_logger; + +Logger& GetDefaultLogger() { + if (default_logger == nullptr) { + std::call_once(default_logger_init_flag, [] { + auto& default_logger_config = GetDefaultLoggerConfig(); + if (default_logger_config.config_spdlog()) { + ConfigSpdlog(); + } + default_logger.reset(new Logger(default_logger_config)); + }); + } + return *default_logger; } -void Logger::set_log_level_(LogLevel log_level) { - switch (log_level) { - case LOG_LEVEL_FATAL: - logger_->set_level(spdlog::level::critical); - break; - case LOG_LEVEL_ERROR: - logger_->set_level(spdlog::level::err); - break; - case LOG_LEVEL_WARN: - logger_->set_level(spdlog::level::warn); - break; - case LOG_LEVEL_INFO: - logger_->set_level(spdlog::level::info); - break; - case LOG_LEVEL_DEBUG: - logger_->set_level(spdlog::level::debug); - break; - case LOG_LEVEL_TRACE: - logger_->set_level(spdlog::level::trace); - break; - default: - logger_->set_level(spdlog::level::info); - break; +Logger::Logger(const LoggerConfig& config) { + try { + logger_ = CreateRotatingLogger(config.name(), config.path(), config.file_size(), config.file_count()); + logger_->set_level(ConvertLogLevel(config.level())); + } catch (std::exception& e) { + std::cerr << "initialite logger failed" << std::endl; + exit(-1); } } -void Logger::setLogFileNumAndSize(int logNum, int sizeOfPerFile) { - // FIXME: set after clients started - auto name = logger_->name(); - spdlog::drop(name); - logger_ = create_rotating_logger_(name, log_file_, sizeOfPerFile, logNum); - set_log_level_(log_level_); +Logger::~Logger() { + if (logger_ != nullptr) { + spdlog::drop(logger_->name()); + } } } // namespace rocketmq diff --git a/src/log/Logging.h b/src/log/Logging.h index 42b1f3b42..24bbd95d8 100644 --- a/src/log/Logging.h +++ b/src/log/Logging.h @@ -19,6 +19,7 @@ #include // std::shared_ptr #include // std::string +#include #include // std::vector // clang-format off @@ -42,70 +43,159 @@ enum LogLevel { LOG_LEVEL_LEVEL_NUM = 7 }; -class Logger { +class LoggerConfig { public: - static Logger* getLoggerInstance(); + LoggerConfig(const std::string& name, const std::string& path) + : LoggerConfig(name, LOG_LEVEL_INFO, path, 1024 * 1024 * 100, 3) {} + LoggerConfig(const std::string& name, LogLevel level, const std::string& path, int file_size, int file_count) + : name_(name), level_(level), path_(path), file_size_(file_size), file_count_(file_count) {} public: + inline const std::string& name() const { return name_; } + inline void set_name(const std::string& name) { name_ = name; } + + inline LogLevel level() const { return level_; } + inline void set_level(LogLevel level) { level_ = level; } + + inline const std::string& path() const { return path_; } + inline void set_path(const std::string& path) { path_ = path; } + + inline int file_size() const { return file_size_; } + inline void set_file_size(int file_size) { file_size_ = file_size; } + + inline int file_count() const { return file_count_; } + inline void set_file_count(int file_count) { file_count_ = file_count; } + + inline bool config_spdlog() const { return config_spdlog_; } + inline void set_config_spdlog(bool config_spdlog) { config_spdlog_ = config_spdlog; } + + private: + std::string name_; + LogLevel level_; + std::string path_; + int file_size_; + int file_count_; + bool config_spdlog_{true}; +}; + +class Logger { + public: + Logger(const LoggerConfig& config); + virtual ~Logger(); - inline spdlog::logger* getSeverityLogger() { return logger_.get(); } + template + inline void Log(spdlog::source_loc&& location, + spdlog::level::level_enum level, + FormatString&& format, + Args&&... args) { + logger_->log(std::forward(location), level, format, std::forward(args)...); + } - void setLogFileNumAndSize(int logNum, int sizeOfPerFile); + template + inline void Trace(spdlog::source_loc&& location, FormatString&& format, Args&&... args) { + Log(std::forward(location), spdlog::level::trace, std::forward(format), + std::forward(args)...); + } - inline LogLevel log_level() const { return log_level_; } - inline void set_log_level(LogLevel log_level) { - log_level_ = log_level; - set_log_level_(log_level); + template + inline void Debug(spdlog::source_loc&& location, FormatString&& format, Args&&... args) { + Log(std::forward(location), spdlog::level::debug, std::forward(format), + std::forward(args)...); } - private: - Logger(const std::string& name); + template + inline void Info(spdlog::source_loc&& location, FormatString&& format, Args&&... args) { + Log(std::forward(location), spdlog::level::info, std::forward(format), + std::forward(args)...); + } + + template + inline void Warn(spdlog::source_loc&& location, FormatString&& format, Args&&... args) { + Log(std::forward(location), spdlog::level::warn, std::forward(format), + std::forward(args)...); + } - void init_log_dir_(); - void init_spdlog_env_(); + template + inline void Error(spdlog::source_loc&& location, FormatString&& format, Args&&... args) { + Log(std::forward(location), spdlog::level::err, std::forward(format), + std::forward(args)...); + } - std::shared_ptr create_rotating_logger_(const std::string& name, - const std::string& filepath, - std::size_t max_size, - std::size_t max_files); + template + inline void Fatal(spdlog::source_loc&& location, FormatString&& format, Args&&... args) { + Log(std::forward(location), spdlog::level::critical, std::forward(format), + std::forward(args)...); + } - void set_log_level_(LogLevel log_level); + template + inline void Printf(spdlog::source_loc&& location, + spdlog::level::level_enum level, + FormatString&& format, + Args&&... args) { + if (logger_->should_log(level)) { + std::string message = fmt::sprintf(format, std::forward(args)...); + logger_->log(std::forward(location), level, message); + } + } - private: - LogLevel log_level_; - std::string log_file_; + template + inline void TracePrintf(spdlog::source_loc&& location, FormatString&& format, Args&&... args) { + Printf(std::forward(location), spdlog::level::trace, std::forward(format), + std::forward(args)...); + } + template + inline void DebugPrintf(spdlog::source_loc&& location, FormatString&& format, Args&&... args) { + Printf(std::forward(location), spdlog::level::debug, std::forward(format), + std::forward(args)...); + } + + template + inline void InfoPrintf(spdlog::source_loc&& location, FormatString&& format, Args&&... args) { + Printf(std::forward(location), spdlog::level::info, std::forward(format), + std::forward(args)...); + } + + template + inline void WarnPrintf(spdlog::source_loc&& location, FormatString&& format, Args&&... args) { + Printf(std::forward(location), spdlog::level::warn, std::forward(format), + std::forward(args)...); + } + + template + inline void ErrorPrintf(spdlog::source_loc&& location, FormatString&& format, Args&&... args) { + Printf(std::forward(location), spdlog::level::err, std::forward(format), + std::forward(args)...); + } + + template + inline void FatalPrintf(spdlog::source_loc&& location, FormatString&& format, Args&&... args) { + Printf(std::forward(location), spdlog::level::critical, std::forward(format), + std::forward(args)...); + } + + private: std::shared_ptr logger_; }; -#define DEFAULT_LOGGER_INSTANCE Logger::getLoggerInstance() -#define DEFAULT_LOGGER DEFAULT_LOGGER_INSTANCE->getSeverityLogger() - -#define SPDLOG_PRINTF(logger, level, format, ...) \ - do { \ - if (logger->should_log(level)) { \ - std::string message = fmt::sprintf(format, ##__VA_ARGS__); \ - logger->log(level, "{} [{}:{}]", message, __FUNCTION__, __LINE__); \ - } \ - } while (0) - -#define LOG_FATAL(...) SPDLOG_PRINTF(DEFAULT_LOGGER, spdlog::level::critical, __VA_ARGS__) -#define LOG_ERROR(...) SPDLOG_PRINTF(DEFAULT_LOGGER, spdlog::level::err, __VA_ARGS__) -#define LOG_WARN(...) SPDLOG_PRINTF(DEFAULT_LOGGER, spdlog::level::warn, __VA_ARGS__) -#define LOG_INFO(...) SPDLOG_PRINTF(DEFAULT_LOGGER, spdlog::level::info, __VA_ARGS__) -#define LOG_DEBUG(...) SPDLOG_PRINTF(DEFAULT_LOGGER, spdlog::level::debug, __VA_ARGS__) - -#define SPDLOG_EXT(logger, level, format, ...) \ - do { \ - logger->log(level, format " [{}:{}]", ##__VA_ARGS__, __FUNCTION__, __LINE__); \ - } while (0) - -#define LOG_FATAL_NEW(...) SPDLOG_EXT(DEFAULT_LOGGER, spdlog::level::critical, __VA_ARGS__) -#define LOG_ERROR_NEW(...) SPDLOG_EXT(DEFAULT_LOGGER, spdlog::level::err, __VA_ARGS__) -#define LOG_WARN_NEW(...) SPDLOG_EXT(DEFAULT_LOGGER, spdlog::level::warn, __VA_ARGS__) -#define LOG_INFO_NEW(...) SPDLOG_EXT(DEFAULT_LOGGER, spdlog::level::info, __VA_ARGS__) -#define LOG_DEBUG_NEW(...) SPDLOG_EXT(DEFAULT_LOGGER, spdlog::level::debug, __VA_ARGS__) +LoggerConfig& GetDefaultLoggerConfig(); +Logger& GetDefaultLogger(); + +#define LOG_SOURCE_LOCATION \ + spdlog::source_loc { __FILE__, __LINE__, SPDLOG_FUNCTION } + +#define LOG_FATAL(...) GetDefaultLogger().FatalPrintf(LOG_SOURCE_LOCATION, __VA_ARGS__) +#define LOG_ERROR(...) GetDefaultLogger().ErrorPrintf(LOG_SOURCE_LOCATION, __VA_ARGS__) +#define LOG_WARN(...) GetDefaultLogger().WarnPrintf(LOG_SOURCE_LOCATION, __VA_ARGS__) +#define LOG_INFO(...) GetDefaultLogger().InfoPrintf(LOG_SOURCE_LOCATION, __VA_ARGS__) +#define LOG_DEBUG(...) GetDefaultLogger().DebugPrintf(LOG_SOURCE_LOCATION, __VA_ARGS__) + +#define LOG_FATAL_NEW(...) GetDefaultLogger().Fatal(LOG_SOURCE_LOCATION, __VA_ARGS__) +#define LOG_ERROR_NEW(...) GetDefaultLogger().Error(LOG_SOURCE_LOCATION, __VA_ARGS__) +#define LOG_WARN_NEW(...) GetDefaultLogger().Warn(LOG_SOURCE_LOCATION, __VA_ARGS__) +#define LOG_INFO_NEW(...) GetDefaultLogger().Info(LOG_SOURCE_LOCATION, __VA_ARGS__) +#define LOG_DEBUG_NEW(...) GetDefaultLogger().Debug(LOG_SOURCE_LOCATION, __VA_ARGS__) } // namespace rocketmq From 3bd226ee201a8e924e88420ba35de911f530ac60 Mon Sep 17 00:00:00 2001 From: James Yin Date: Thu, 11 Mar 2021 01:32:53 +0800 Subject: [PATCH 45/62] fix: leak of InvokeCallback --- src/MQClientAPIImpl.cpp | 32 ++++++++----------------- src/MQClientAPIImpl.h | 8 +++---- src/common/SendCallbackWrap.cpp | 4 +--- src/transport/ResponseFuture.cpp | 11 ++++----- src/transport/ResponseFuture.h | 11 ++++++--- src/transport/TcpRemotingClient.cpp | 36 ++++++++++++----------------- src/transport/TcpRemotingClient.h | 6 ++--- 7 files changed, 46 insertions(+), 62 deletions(-) diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index 91c6dc1e5..e5372d023 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -159,21 +159,16 @@ void MQClientAPIImpl::sendMessageAsync(const std::string& addr, int64_t timeoutMillis, int retryTimesWhenSendFailed, DefaultMQProducerImplPtr producer) { - // delete in future - auto* cbw = new SendCallbackWrap(addr, brokerName, msg, std::forward(request), sendCallback, - topicPublishInfo, instance, retryTimesWhenSendFailed, 0, producer); - - try { - sendMessageAsyncImpl(cbw, timeoutMillis); - } catch (RemotingException& e) { - deleteAndZero(cbw); - throw; - } + std::unique_ptr cbw( + new SendCallbackWrap(addr, brokerName, msg, std::forward(request), sendCallback, + topicPublishInfo, instance, retryTimesWhenSendFailed, 0, producer)); + sendMessageAsyncImpl(cbw, timeoutMillis); } -void MQClientAPIImpl::sendMessageAsyncImpl(SendCallbackWrap* cbw, int64_t timeoutMillis) { - const auto& addr = cbw->getAddr(); - auto& request = cbw->getRemotingCommand(); +void MQClientAPIImpl::sendMessageAsyncImpl(std::unique_ptr& cbw, int64_t timeoutMillis) { + auto* scbw = static_cast(cbw.get()); + const auto& addr = scbw->getAddr(); + auto& request = scbw->getRemotingCommand(); remoting_client_->invokeAsync(addr, request, cbw, timeoutMillis); } @@ -261,15 +256,8 @@ void MQClientAPIImpl::pullMessageAsync(const std::string& addr, RemotingCommand& request, int timeoutMillis, PullCallback* pullCallback) { - // delete in future - auto* cbw = new PullCallbackWrap(pullCallback, this); - - try { - remoting_client_->invokeAsync(addr, request, cbw, timeoutMillis); - } catch (RemotingException& e) { - deleteAndZero(cbw); - throw; - } + std::unique_ptr cbw(new PullCallbackWrap(pullCallback, this)); + remoting_client_->invokeAsync(addr, request, cbw, timeoutMillis); } PullResult* MQClientAPIImpl::pullMessageSync(const std::string& addr, RemotingCommand& request, int timeoutMillis) { diff --git a/src/MQClientAPIImpl.h b/src/MQClientAPIImpl.h index 143a6a5db..535f33d8a 100644 --- a/src/MQClientAPIImpl.h +++ b/src/MQClientAPIImpl.h @@ -20,8 +20,8 @@ #include "CommunicationMode.h" #include "DefaultMQProducerImpl.h" #include "KVTable.h" -#include "MQException.h" #include "MQClientInstance.h" +#include "MQException.h" #include "MQMessageExt.h" #include "PullCallback.h" #include "SendCallback.h" @@ -29,8 +29,8 @@ #include "TopicConfig.h" #include "TopicList.h" #include "TopicPublishInfo.hpp" -#include "protocol/body/TopicRouteData.hpp" #include "protocol/body/LockBatchRequestBody.hpp" +#include "protocol/body/TopicRouteData.hpp" #include "protocol/body/UnlockBatchRequestBody.hpp" #include "protocol/header/CommandHeader.h" #include "protocol/heartbeat/HeartbeatData.hpp" @@ -40,7 +40,7 @@ namespace rocketmq { class TcpRemotingClient; class ClientRemotingProcessor; class RPCHook; -class SendCallbackWrap; +class InvokeCallback; /** * wrap all RPC API @@ -182,7 +182,7 @@ class MQClientAPIImpl { int retryTimesWhenSendFailed, DefaultMQProducerImplPtr producer); - void sendMessageAsyncImpl(SendCallbackWrap* cbw, int64_t timeoutMillis); + void sendMessageAsyncImpl(std::unique_ptr& cbw, int64_t timeoutMillis); PullResult* pullMessageSync(const std::string& addr, RemotingCommand& request, int timeoutMillis); diff --git a/src/common/SendCallbackWrap.cpp b/src/common/SendCallbackWrap.cpp index 92fd6e10f..562b30fe1 100644 --- a/src/common/SendCallbackWrap.cpp +++ b/src/common/SendCallbackWrap.cpp @@ -156,9 +156,7 @@ void SendCallbackWrap::onExceptionImpl(ResponseFuture* responseFuture, // resend addr_ = std::move(addr); broker_name_ = std::move(retryBrokerName); - instance_->getMQClientAPIImpl()->sendMessageAsyncImpl(this, timeoutMillis); - - responseFuture->releaseInvokeCallback(); // for avoid delete this SendCallbackWrap + instance_->getMQClientAPIImpl()->sendMessageAsyncImpl(responseFuture->invoke_callback(), timeoutMillis); return; } catch (MQException& e1) { producer->updateFaultItem(broker_name_, 3000, true); diff --git a/src/transport/ResponseFuture.cpp b/src/transport/ResponseFuture.cpp index 938413509..a2887be48 100755 --- a/src/transport/ResponseFuture.cpp +++ b/src/transport/ResponseFuture.cpp @@ -20,11 +20,14 @@ namespace rocketmq { -ResponseFuture::ResponseFuture(int requestCode, int opaque, int64_t timeoutMillis, InvokeCallback* invokeCallback) +ResponseFuture::ResponseFuture(int requestCode, + int opaque, + int64_t timeoutMillis, + std::unique_ptr invokeCallback) : request_code_(requestCode), opaque_(opaque), timeout_millis_(timeoutMillis), - invoke_callback_(invokeCallback), + invoke_callback_(std::move(invokeCallback)), begin_timestamp_(UtilAll::currentTimeMillis()), send_request_ok_(false), response_command_(nullptr), @@ -47,10 +50,6 @@ bool ResponseFuture::hasInvokeCallback() { return invoke_callback_ != nullptr; } -InvokeCallback* ResponseFuture::releaseInvokeCallback() { - return invoke_callback_.release(); -} - void ResponseFuture::executeInvokeCallback() noexcept { if (invoke_callback_ != nullptr) { invoke_callback_->operationComplete(this); diff --git a/src/transport/ResponseFuture.h b/src/transport/ResponseFuture.h index 56ffc67ed..f950743f2 100755 --- a/src/transport/ResponseFuture.h +++ b/src/transport/ResponseFuture.h @@ -17,9 +17,10 @@ #ifndef ROCKETMQ_TRANSPORT_RESPONSEFUTURE_H_ #define ROCKETMQ_TRANSPORT_RESPONSEFUTURE_H_ -#include "concurrent/latch.hpp" +#include #include "InvokeCallback.h" #include "RemotingCommand.h" +#include "concurrent/latch.hpp" namespace rocketmq { @@ -28,13 +29,15 @@ typedef std::shared_ptr ResponseFuturePtr; class ResponseFuture { public: - ResponseFuture(int requestCode, int opaque, int64_t timeoutMillis, InvokeCallback* invokeCallback = nullptr); + ResponseFuture(int requestCode, + int opaque, + int64_t timeoutMillis, + std::unique_ptr invokeCallback = nullptr); virtual ~ResponseFuture(); void releaseThreadCondition(); bool hasInvokeCallback(); - InvokeCallback* releaseInvokeCallback(); void executeInvokeCallback() noexcept; @@ -59,6 +62,8 @@ class ResponseFuture { inline bool send_request_ok() const { return send_request_ok_; } inline void set_send_request_ok(bool sendRequestOK = true) { send_request_ok_ = sendRequestOK; }; + inline std::unique_ptr& invoke_callback() { return invoke_callback_; } + private: int request_code_; int opaque_; diff --git a/src/transport/TcpRemotingClient.cpp b/src/transport/TcpRemotingClient.cpp index c6c222d7c..655a8110f 100644 --- a/src/transport/TcpRemotingClient.cpp +++ b/src/transport/TcpRemotingClient.cpp @@ -279,7 +279,7 @@ std::unique_ptr TcpRemotingClient::invokeSyncImpl(TcpTransportP void TcpRemotingClient::invokeAsync(const std::string& addr, RemotingCommand& request, - InvokeCallback* invokeCallback, + std::unique_ptr& invokeCallback, int64_t timeoutMillis) { auto beginStartTime = UtilAll::currentTimeMillis(); auto channel = GetTransport(addr); @@ -304,33 +304,27 @@ void TcpRemotingClient::invokeAsync(const std::string& addr, void TcpRemotingClient::invokeAsyncImpl(TcpTransportPtr channel, RemotingCommand& request, int64_t timeoutMillis, - InvokeCallback* invokeCallback) { + std::unique_ptr& invokeCallback) { int code = request.code(); int opaque = request.opaque(); // delete in callback - auto responseFuture = std::make_shared(code, opaque, timeoutMillis, invokeCallback); + auto responseFuture = std::make_shared(code, opaque, timeoutMillis, std::move(invokeCallback)); putResponseFuture(channel, opaque, responseFuture); - try { - if (SendCommand(channel, request)) { - responseFuture->set_send_request_ok(true); - } else { - // requestFail - responseFuture = popResponseFuture(channel, opaque); - if (responseFuture != nullptr) { - responseFuture->set_send_request_ok(false); - if (responseFuture->hasInvokeCallback()) { - handle_executor_.submit(std::bind(&ResponseFuture::executeInvokeCallback, responseFuture)); - } + if (SendCommand(channel, request)) { + responseFuture->set_send_request_ok(true); + } else { + // request fail + responseFuture = popResponseFuture(channel, opaque); + if (responseFuture != nullptr) { + responseFuture->set_send_request_ok(false); + if (responseFuture->hasInvokeCallback()) { + handle_executor_.submit(std::bind(&ResponseFuture::executeInvokeCallback, responseFuture)); } - - LOG_WARN_NEW("send a request command to channel <{}> failed.", channel->getPeerAddrAndPort()); } - } catch (const std::exception& e) { - LOG_WARN_NEW("send a request command to channel <{}> Exception.\n{}", channel->getPeerAddrAndPort(), e.what()); - THROW_MQEXCEPTION(RemotingSendRequestException, "send request to <" + channel->getPeerAddrAndPort() + "> failed", - -1); + + LOG_WARN_NEW("send a request command to channel <{}> failed.", channel->getPeerAddrAndPort()); } } @@ -553,7 +547,7 @@ bool TcpRemotingClient::CloseNameServerTransport(TcpTransportPtr channel) { return removeItemFromTable; } -bool TcpRemotingClient::SendCommand(TcpTransportPtr channel, RemotingCommand& msg) { +bool TcpRemotingClient::SendCommand(TcpTransportPtr channel, RemotingCommand& msg) noexcept { auto package = msg.encode(); return channel->sendMessage(package->array(), package->size()); } diff --git a/src/transport/TcpRemotingClient.h b/src/transport/TcpRemotingClient.h index 3ffbb664c..7d8606003 100755 --- a/src/transport/TcpRemotingClient.h +++ b/src/transport/TcpRemotingClient.h @@ -52,7 +52,7 @@ class TcpRemotingClient { void invokeAsync(const std::string& addr, RemotingCommand& request, - InvokeCallback* invokeCallback, + std::unique_ptr& invokeCallback, int64_t timeoutMillis); void invokeOneway(const std::string& addr, RemotingCommand& request); @@ -62,7 +62,7 @@ class TcpRemotingClient { std::vector getNameServerAddressList() const { return namesrv_addr_list_; } private: - static bool SendCommand(TcpTransportPtr channel, RemotingCommand& msg); + static bool SendCommand(TcpTransportPtr channel, RemotingCommand& msg) noexcept; void channelClosed(TcpTransportPtr channel); @@ -88,7 +88,7 @@ class TcpRemotingClient { void invokeAsyncImpl(TcpTransportPtr channel, RemotingCommand& request, int64_t timeoutMillis, - InvokeCallback* invokeCallback); + std::unique_ptr& invokeCallback); void invokeOnewayImpl(TcpTransportPtr channel, RemotingCommand& request); // rpc hook From cebb202022a280c7da890f4a15f09559db058b55 Mon Sep 17 00:00:00 2001 From: James Yin Date: Thu, 11 Mar 2021 18:29:26 +0800 Subject: [PATCH 46/62] fix: leak of AsyncPullCallback --- src/consumer/DefaultMQPushConsumerImpl.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/consumer/DefaultMQPushConsumerImpl.cpp b/src/consumer/DefaultMQPushConsumerImpl.cpp index 79bcdf5cc..11a12a174 100644 --- a/src/consumer/DefaultMQPushConsumerImpl.cpp +++ b/src/consumer/DefaultMQPushConsumerImpl.cpp @@ -478,7 +478,9 @@ void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pull_request) { false); // class filter try { - auto* callback = new AsyncPullCallback(shared_from_this(), pull_request, subscription_data); + std::unique_ptr callback( + new AsyncPullCallback(shared_from_this(), pull_request, subscription_data)); + pull_api_wrapper_->pullKernelImpl(message_queue, // mq subExpression, // subExpression subscription_data->expression_type(), // expressionType @@ -490,7 +492,9 @@ void DefaultMQPushConsumerImpl::pullMessage(PullRequestPtr pull_request) { BROKER_SUSPEND_MAX_TIME_MILLIS, // brokerSuspendMaxTimeMillis CONSUMER_TIMEOUT_MILLIS_WHEN_SUSPEND, // timeoutMillis CommunicationMode::ASYNC, // communicationMode - callback); // pullCallback + callback.get()); // pullCallback + + (void)callback.release(); } catch (MQException& e) { LOG_ERROR_NEW("pullKernelImpl exception: {}", e.what()); executePullRequestLater(pull_request, getDefaultMQPushConsumerConfig()->pull_time_delay_millis_when_exception()); From 40882dc35e8f6bc62edd2fb03864ef031e72c8b3 Mon Sep 17 00:00:00 2001 From: James Yin Date: Thu, 11 Mar 2021 15:59:04 +0800 Subject: [PATCH 47/62] feat: support ipv6 --- src/ClientRemotingProcessor.cpp | 6 +- src/MQClientConfigImpl.hpp | 3 +- src/common/UtilAll.cpp | 53 +---- src/common/UtilAll.h | 8 - src/consumer/DefaultMQPushConsumerImpl.cpp | 4 +- src/message/MessageBatch.cpp | 3 +- src/message/MessageClientIDSetter.cpp | 40 ++-- src/message/MessageClientIDSetter.h | 2 +- src/message/MessageDecoder.cpp | 42 ++-- src/message/MessageDecoder.h | 7 +- src/message/MessageExtImpl.cpp | 26 +-- src/message/MessageExtImpl.h | 4 +- src/message/MessageId.h | 16 +- src/transport/EventLoop.cpp | 6 +- src/transport/SocketUtil.cpp | 217 +++++++++++++-------- src/transport/SocketUtil.h | 45 +++-- 16 files changed, 258 insertions(+), 224 deletions(-) diff --git a/src/ClientRemotingProcessor.cpp b/src/ClientRemotingProcessor.cpp index cf973067f..32366d60e 100644 --- a/src/ClientRemotingProcessor.cpp +++ b/src/ClientRemotingProcessor.cpp @@ -16,9 +16,9 @@ */ #include "ClientRemotingProcessor.h" -#include "MessageDecoder.h" #include "MQProtos.h" #include "MessageAccessor.hpp" +#include "MessageDecoder.h" #include "MessageSysFlag.h" #include "RequestFutureTable.h" #include "SocketUtil.h" @@ -153,11 +153,11 @@ RemotingCommand* ClientRemotingProcessor::receiveReplyMessage(RemotingCommand* r msg->set_store_timestamp(requestHeader->store_timestamp()); if (!requestHeader->born_host().empty()) { - msg->set_born_host(string2SocketAddress(requestHeader->born_host())); + msg->set_born_host(StringToSockaddr(requestHeader->born_host())); } if (!requestHeader->store_host().empty()) { - msg->set_store_host(string2SocketAddress(requestHeader->store_host())); + msg->set_store_host(StringToSockaddr(requestHeader->store_host())); } auto body = request->body(); diff --git a/src/MQClientConfigImpl.hpp b/src/MQClientConfigImpl.hpp index 59b46018a..b9ad503bc 100644 --- a/src/MQClientConfigImpl.hpp +++ b/src/MQClientConfigImpl.hpp @@ -22,6 +22,7 @@ #include "MQClientConfig.h" #include "NamespaceUtil.h" +#include "SocketUtil.h" #include "UtilAll.h" namespace rocketmq { @@ -45,7 +46,7 @@ class MQClientConfigImpl : virtual public MQClientConfig { std::string buildMQClientId() const override { std::string clientId; - clientId.append(UtilAll::getLocalAddress()); // clientIP + clientId.append(GetLocalAddress()); // clientIP clientId.append("@"); clientId.append(instance_name_); // instanceName if (!unit_name_.empty()) { diff --git a/src/common/UtilAll.cpp b/src/common/UtilAll.cpp index 2cbe00a0c..731d8aa1a 100644 --- a/src/common/UtilAll.cpp +++ b/src/common/UtilAll.cpp @@ -40,9 +40,6 @@ namespace rocketmq { -std::string UtilAll::sLocalHostName; -std::string UtilAll::sLocalIpAddress; - bool UtilAll::try_lock_for(std::timed_mutex& mutex, long timeout) { auto now = std::chrono::steady_clock::now(); auto deadline = now + std::chrono::milliseconds(timeout); @@ -157,7 +154,7 @@ bool UtilAll::isBlank(const std::string& str) { } bool UtilAll::SplitURL(const std::string& serverURL, std::string& addr, short& nPort) { - auto pos = serverURL.find(':'); + auto pos = serverURL.find_last_of(':'); if (pos == std::string::npos) { return false; } @@ -228,54 +225,6 @@ int UtilAll::Split(std::vector& ret_, const std::string& strIn, con return ret_.size(); } -std::string UtilAll::getLocalHostName() { - if (sLocalHostName.empty()) { - char name[1024]; - if (::gethostname(name, sizeof(name)) != 0) { - return null; - } - sLocalHostName.append(name, strlen(name)); - } - return sLocalHostName; -} - -std::string UtilAll::getLocalAddress() { - if (sLocalIpAddress.empty()) { - auto hostname = getLocalHostName(); - if (!hostname.empty()) { - try { - sLocalIpAddress = socketAddress2String(lookupNameServers(hostname)); - } catch (std::exception& e) { - LOG_WARN(e.what()); - sLocalIpAddress = "127.0.0.1"; - } - } - } - return sLocalIpAddress; -} - -uint32_t UtilAll::getIP() { - std::string ip = UtilAll::getLocalAddress(); - if (ip.empty()) { - return 0; - } - - char* ip_str = new char[ip.length() + 1]; - std::strncpy(ip_str, ip.c_str(), ip.length()); - ip_str[ip.length()] = '\0'; - - int i = 3; - uint32_t nResult = 0; - for (char* token = std::strtok(ip_str, "."); token != nullptr && i >= 0; token = std::strtok(nullptr, ".")) { - uint32_t n = std::atoi(token); - nResult |= n << (8 * i--); - } - - delete[] ip_str; - - return nResult; -} - std::string UtilAll::getHomeDirectory() { #ifndef WIN32 char* home_env = std::getenv("HOME"); diff --git a/src/common/UtilAll.h b/src/common/UtilAll.h index 8ad49b00f..63989f749 100644 --- a/src/common/UtilAll.h +++ b/src/common/UtilAll.h @@ -112,10 +112,6 @@ class UtilAll { static int Split(std::vector& ret_, const std::string& strIn, const char sep); static int Split(std::vector& ret_, const std::string& strIn, const std::string& sep); - static std::string getLocalHostName(); - static std::string getLocalAddress(); - static uint32_t getIP(); - static std::string getHomeDirectory(); static void createDirectory(std::string const& dir); static bool existDirectory(std::string const& dir); @@ -138,10 +134,6 @@ class UtilAll { // Returns true on success. // Returns false on failure.. static bool ReplaceFile(const std::string& from_path, const std::string& to_path); - - private: - static std::string sLocalHostName; - static std::string sLocalIpAddress; }; template diff --git a/src/consumer/DefaultMQPushConsumerImpl.cpp b/src/consumer/DefaultMQPushConsumerImpl.cpp index 11a12a174..bf00cc279 100644 --- a/src/consumer/DefaultMQPushConsumerImpl.cpp +++ b/src/consumer/DefaultMQPushConsumerImpl.cpp @@ -536,8 +536,8 @@ bool DefaultMQPushConsumerImpl::sendMessageBack(MessageExtPtr msg, int delay_lev try { msg->set_topic(NamespaceUtil::wrapNamespace(client_config_->name_space(), msg->topic())); - std::string brokerAddr = brokerName.empty() ? socketAddress2String(msg->store_host()) - : client_instance_->findBrokerAddressInPublish(brokerName); + std::string brokerAddr = + brokerName.empty() ? msg->store_host_string() : client_instance_->findBrokerAddressInPublish(brokerName); client_instance_->getMQClientAPIImpl()->consumerSendMessageBack( brokerAddr, msg, getDefaultMQPushConsumerConfig()->group_name(), delay_level, 5000, diff --git a/src/message/MessageBatch.cpp b/src/message/MessageBatch.cpp index 4030fd6db..2ba0c184b 100644 --- a/src/message/MessageBatch.cpp +++ b/src/message/MessageBatch.cpp @@ -16,8 +16,9 @@ */ #include "MessageBatch.h" -#include "MessageDecoder.h" +#include "MQException.h" #include "MessageClientIDSetter.h" +#include "MessageDecoder.h" namespace rocketmq { diff --git a/src/message/MessageClientIDSetter.cpp b/src/message/MessageClientIDSetter.cpp index dda45df62..5560ba1e2 100644 --- a/src/message/MessageClientIDSetter.cpp +++ b/src/message/MessageClientIDSetter.cpp @@ -25,7 +25,8 @@ #include #endif -#include "ByteOrder.h" +#include "ByteBuffer.hpp" +#include "SocketUtil.h" #include "UtilAll.h" namespace rocketmq { @@ -33,16 +34,28 @@ namespace rocketmq { MessageClientIDSetter::MessageClientIDSetter() { std::srand((uint32_t)std::time(NULL)); - uint32_t pid = ByteOrderUtil::NorminalBigEndian(static_cast(UtilAll::getProcessId())); - uint32_t ip = ByteOrderUtil::NorminalBigEndian(UtilAll::getIP()); - uint32_t random_num = ByteOrderUtil::NorminalBigEndian(static_cast(std::rand())); - - char bin_buf[10]; - std::memcpy(bin_buf + 2, &pid, 4); - std::memcpy(bin_buf, &ip, 4); - std::memcpy(bin_buf + 6, &random_num, 4); + std::unique_ptr buffer; + sockaddr* addr = GetSelfIP(); + if (addr != nullptr) { + buffer.reset(ByteBuffer::allocate(SockaddrSize(addr) + 2 + 4)); + if (addr->sa_family == AF_INET) { + auto* sin = (struct sockaddr_in*)addr; + buffer->put(ByteArray(reinterpret_cast(&sin->sin_addr), kIPv4AddrSize)); + } else if (addr->sa_family == AF_INET6) { + auto* sin6 = (struct sockaddr_in6*)addr; + buffer->put(ByteArray(reinterpret_cast(&sin6->sin6_addr), kIPv6AddrSize)); + } else { + (void)buffer.release(); + } + } + if (buffer == nullptr) { + buffer.reset(ByteBuffer::allocate(4 + 2 + 4)); + buffer->putInt(UtilAll::currentTimeMillis()); + } + buffer->putShort(UtilAll::getProcessId()); + buffer->putInt(std::rand()); - fix_string_ = UtilAll::bytes2string(bin_buf, 10); + fixed_string_ = UtilAll::bytes2string(buffer->array(), buffer->position()); setStartTime(UtilAll::currentTimeMillis()); @@ -93,11 +106,8 @@ std::string MessageClientIDSetter::createUniqueID() { uint32_t period = ByteOrderUtil::NorminalBigEndian(static_cast(current - start_time_)); uint16_t seqid = ByteOrderUtil::NorminalBigEndian(counter_++); - char bin_buf[6]; - std::memcpy(bin_buf, &period, 4); - std::memcpy(bin_buf + 4, &seqid, 2); - - return fix_string_ + UtilAll::bytes2string(bin_buf, 6); + return fixed_string_ + UtilAll::bytes2string(reinterpret_cast(&period), sizeof(period)) + + UtilAll::bytes2string(reinterpret_cast(&seqid), sizeof(seqid)); } } // namespace rocketmq diff --git a/src/message/MessageClientIDSetter.h b/src/message/MessageClientIDSetter.h index 222115ebd..e6887863a 100644 --- a/src/message/MessageClientIDSetter.h +++ b/src/message/MessageClientIDSetter.h @@ -68,7 +68,7 @@ class MessageClientIDSetter { uint64_t next_start_time_; std::atomic counter_; - std::string fix_string_; + std::string fixed_string_; }; } // namespace rocketmq diff --git a/src/message/MessageDecoder.cpp b/src/message/MessageDecoder.cpp index a36d3bf96..08df4070a 100644 --- a/src/message/MessageDecoder.cpp +++ b/src/message/MessageDecoder.cpp @@ -20,14 +20,18 @@ #include // std::stringstream #ifndef WIN32 -#include // struct sockaddr, sockaddr_in, sockaddr_in6 +#include // htons +#include // sockaddr_in, sockaddr_in6 +#else +#include "Winsock2.h" #endif #include "ByteOrder.h" #include "Logging.h" -#include "MessageExtImpl.h" #include "MessageAccessor.hpp" +#include "MessageExtImpl.h" #include "MessageSysFlag.h" +#include "SocketUtil.h" #include "UtilAll.h" static const char NAME_VALUE_SEPARATOR = 1; @@ -36,37 +40,35 @@ static const char PROPERTY_SEPARATOR = 2; namespace rocketmq { std::string MessageDecoder::createMessageId(const struct sockaddr* sa, int64_t offset) { - int msgIDLength = sa->sa_family == AF_INET ? 16 : 28; - std::unique_ptr byteBuffer(ByteBuffer::allocate(msgIDLength)); + int msgIdLength = IpaddrSize(sa) + /* port field size */ 4 + sizeof(offset); + std::unique_ptr byteBuffer(ByteBuffer::allocate(msgIdLength)); if (sa->sa_family == AF_INET) { struct sockaddr_in* sin = (struct sockaddr_in*)sa; - byteBuffer->put(ByteArray((char*)&sin->sin_addr, 4)); - byteBuffer->putInt(ByteOrderUtil::NorminalBigEndian(sin->sin_port)); + byteBuffer->put(ByteArray(reinterpret_cast(&sin->sin_addr), kIPv4AddrSize)); + byteBuffer->putInt(ntohs(sin->sin_port)); } else { struct sockaddr_in6* sin6 = (struct sockaddr_in6*)sa; - byteBuffer->put(ByteArray((char*)&sin6->sin6_addr, 16)); - byteBuffer->putInt(ByteOrderUtil::NorminalBigEndian(sin6->sin6_port)); + byteBuffer->put(ByteArray(reinterpret_cast(&sin6->sin6_addr), kIPv6AddrSize)); + byteBuffer->putInt(ntohs(sin6->sin6_port)); } byteBuffer->putLong(offset); byteBuffer->flip(); - return UtilAll::bytes2string(byteBuffer->array(), msgIDLength); + return UtilAll::bytes2string(byteBuffer->array(), msgIdLength); } MessageId MessageDecoder::decodeMessageId(const std::string& msgId) { - size_t ip_length = msgId.length() == 32 ? 4 * 2 : 16 * 2; + size_t ip_length = msgId.length() == 32 ? kIPv4AddrSize * 2 : kIPv6AddrSize * 2; ByteArray byteArray(ip_length / 2); std::string ip = msgId.substr(0, ip_length); UtilAll::string2bytes(byteArray.array(), ip); std::string port = msgId.substr(ip_length, 8); - // uint32_t portInt = ByteOrderUtil::NorminalBigEndian(std::stoul(port, nullptr, 16)); uint32_t portInt = std::stoul(port, nullptr, 16); - auto* sin = ipPort2SocketAddress(byteArray, portInt); + auto* sin = IPPortToSockaddr(byteArray, portInt); std::string offset = msgId.substr(ip_length + 8); - // uint64_t offsetInt = ByteOrderUtil::NorminalBigEndian(std::stoull(offset, nullptr, 16)); uint64_t offsetInt = std::stoull(offset, nullptr, 16); return MessageId(sin, offsetInt); @@ -123,22 +125,22 @@ MessageExtPtr MessageDecoder::decode(ByteBuffer& byteBuffer, bool readBody, bool msgExt->set_born_timestamp(bornTimeStamp); // 10 BORNHOST - int bornhostIPLength = (sysFlag & MessageSysFlag::BORNHOST_V6_FLAG) == 0 ? 4 : 16; - ByteArray bornHost(bornhostIPLength); - byteBuffer.get(bornHost, 0, bornhostIPLength); + int bornHostLength = (sysFlag & MessageSysFlag::BORNHOST_V6_FLAG) == 0 ? kIPv4AddrSize : kIPv6AddrSize; + ByteArray bornHost(bornHostLength); + byteBuffer.get(bornHost, 0, bornHostLength); int32_t bornPort = byteBuffer.getInt(); - msgExt->set_born_host(ipPort2SocketAddress(bornHost, bornPort)); + msgExt->set_born_host(IPPortToSockaddr(bornHost, bornPort)); // 11 STORETIMESTAMP int64_t storeTimestamp = byteBuffer.getLong(); msgExt->set_store_timestamp(storeTimestamp); // 12 STOREHOST - int storehostIPLength = (sysFlag & MessageSysFlag::STOREHOST_V6_FLAG) == 0 ? 4 : 16; - ByteArray storeHost(bornhostIPLength); + int storehostIPLength = (sysFlag & MessageSysFlag::STOREHOST_V6_FLAG) == 0 ? kIPv4AddrSize : kIPv6AddrSize; + ByteArray storeHost(bornHostLength); byteBuffer.get(storeHost, 0, storehostIPLength); int32_t storePort = byteBuffer.getInt(); - msgExt->set_store_host(ipPort2SocketAddress(storeHost, storePort)); + msgExt->set_store_host(IPPortToSockaddr(storeHost, storePort)); // 13 RECONSUMETIMES int32_t reconsumeTimes = byteBuffer.getInt(); diff --git a/src/message/MessageDecoder.h b/src/message/MessageDecoder.h index ad0b82d37..5c45d8e2d 100644 --- a/src/message/MessageDecoder.h +++ b/src/message/MessageDecoder.h @@ -17,8 +17,13 @@ #ifndef ROCKETMQ_MESSAGE_MESSAGEDECODER_H_ #define ROCKETMQ_MESSAGE_MESSAGEDECODER_H_ +#ifndef WIN32 +#include // sockaddr +#else +#include +#endif + #include "ByteBuffer.hpp" -#include "MQException.h" #include "MQMessageExt.h" #include "MessageId.h" diff --git a/src/message/MessageExtImpl.cpp b/src/message/MessageExtImpl.cpp index f43ac357a..cfd6b99a4 100644 --- a/src/message/MessageExtImpl.cpp +++ b/src/message/MessageExtImpl.cpp @@ -44,20 +44,14 @@ MessageExtImpl::MessageExtImpl(int queueId, commit_log_offset_(0), sys_flag_(0), born_timestamp_(bornTimestamp), - born_host_(nullptr), + born_host_(SockaddrToStorage(bornHost)), store_timestamp_(storeTimestamp), - store_host_(nullptr), + store_host_(SockaddrToStorage(storeHost)), reconsume_times_(3), prepared_transaction_offset_(0), - msg_id_(msgId) { - born_host_ = copySocketAddress(born_host_, bornHost); - store_host_ = copySocketAddress(store_host_, storeHost); -} + msg_id_(msgId) {} -MessageExtImpl::~MessageExtImpl() { - free(born_host_); - free(store_host_); -} +MessageExtImpl::~MessageExtImpl() = default; TopicFilterType MessageExtImpl::parseTopicFilterType(int32_t sysFlag) { if ((sysFlag & MessageSysFlag::MULTI_TAGS_FLAG) == MessageSysFlag::MULTI_TAGS_FLAG) { @@ -123,15 +117,15 @@ void MessageExtImpl::set_born_timestamp(int64_t bornTimestamp) { } const struct sockaddr* MessageExtImpl::born_host() const { - return born_host_; + return reinterpret_cast(born_host_.get()); } std::string MessageExtImpl::born_host_string() const { - return socketAddress2String(born_host_); + return SockaddrToString(born_host()); } void MessageExtImpl::set_born_host(const struct sockaddr* bornHost) { - born_host_ = copySocketAddress(born_host_, bornHost); + born_host_ = SockaddrToStorage(bornHost); } int64_t MessageExtImpl::store_timestamp() const { @@ -143,15 +137,15 @@ void MessageExtImpl::set_store_timestamp(int64_t storeTimestamp) { } const struct sockaddr* MessageExtImpl::store_host() const { - return store_host_; + return reinterpret_cast(store_host_.get()); } std::string MessageExtImpl::store_host_string() const { - return socketAddress2String(store_host_); + return SockaddrToString(store_host()); } void MessageExtImpl::set_store_host(const struct sockaddr* storeHost) { - store_host_ = copySocketAddress(store_host_, storeHost); + store_host_ = SockaddrToStorage(storeHost); } const std::string& MessageExtImpl::msg_id() const { diff --git a/src/message/MessageExtImpl.h b/src/message/MessageExtImpl.h index 5d85ceae8..fc4447192 100644 --- a/src/message/MessageExtImpl.h +++ b/src/message/MessageExtImpl.h @@ -94,9 +94,9 @@ class MessageExtImpl : public MessageImpl, // base int64_t commit_log_offset_; int32_t sys_flag_; int64_t born_timestamp_; - struct sockaddr* born_host_; + std::unique_ptr born_host_; int64_t store_timestamp_; - struct sockaddr* store_host_; + std::unique_ptr store_host_; int32_t reconsume_times_; int64_t prepared_transaction_offset_; std::string msg_id_; diff --git a/src/message/MessageId.h b/src/message/MessageId.h index 64e460380..e9a501b28 100644 --- a/src/message/MessageId.h +++ b/src/message/MessageId.h @@ -27,29 +27,29 @@ namespace rocketmq { class MessageId { public: MessageId() : MessageId(nullptr, 0) {} - MessageId(struct sockaddr* address, int64_t offset) : address_(nullptr), offset_(offset) { setAddress(address); } + MessageId(const struct sockaddr* address, int64_t offset) : address_(SockaddrToStorage(address)), offset_(offset) {} - MessageId(const MessageId& other) : MessageId(other.address_, other.offset_) {} - MessageId(MessageId&& other) : address_(other.address_), offset_(other.offset_) { other.address_ = nullptr; } + MessageId(const MessageId& other) : MessageId(other.getAddress(), other.offset_) {} + MessageId(MessageId&& other) : address_(std::move(other.address_)), offset_(other.offset_) {} - virtual ~MessageId() { std::free(address_); } + virtual ~MessageId() = default; MessageId& operator=(const MessageId& other) { if (&other != this) { - setAddress(other.address_); + setAddress(other.getAddress()); this->offset_ = other.offset_; } return *this; } - const struct sockaddr* getAddress() const { return address_; } - void setAddress(struct sockaddr* address) { address_ = copySocketAddress(address_, address); } + const struct sockaddr* getAddress() const { return reinterpret_cast(address_.get()); } + void setAddress(const struct sockaddr* address) { address_ = SockaddrToStorage(address); } int64_t getOffset() const { return offset_; } void setOffset(int64_t offset) { offset_ = offset; } private: - struct sockaddr* address_; + std::unique_ptr address_; int64_t offset_; }; diff --git a/src/transport/EventLoop.cpp b/src/transport/EventLoop.cpp index 85ea1134b..5dce2d19a 100644 --- a/src/transport/EventLoop.cpp +++ b/src/transport/EventLoop.cpp @@ -207,9 +207,9 @@ int BufferEvent::connect(const std::string& addr) { } try { - auto* sa = string2SocketAddress(addr); // resolve domain - peer_addr_port_ = socketAddress2String(sa); - return bufferevent_socket_connect(buffer_event_, sa, sockaddr_size(sa)); + auto* sa = StringToSockaddr(addr); // resolve domain + peer_addr_port_ = SockaddrToString(sa); + return bufferevent_socket_connect(buffer_event_, sa, SockaddrSize(sa)); } catch (const std::exception& e) { LOG_ERROR_NEW("can not connect to {}, {}", addr, e.what()); return -1; diff --git a/src/transport/SocketUtil.cpp b/src/transport/SocketUtil.cpp index 04700882e..f20726317 100644 --- a/src/transport/SocketUtil.cpp +++ b/src/transport/SocketUtil.cpp @@ -16,73 +16,115 @@ */ #include "SocketUtil.h" -#include // std::realloc -#include // std::memset, std::memcpy +#include // std::abort +#include // std::memcpy, std::memset -#include -#include - -#include +#include +#include // std::invalid_argument, std::runtime_error +#include #ifndef WIN32 -#include -#include +#include // htons +#include // gethostname +#else +#include #endif -#include "ByteOrder.h" +#include + #include "MQException.h" -#include "UtilAll.h" namespace rocketmq { -union sockaddr_union { - struct sockaddr_in sin; - struct sockaddr_in6 sin6; -}; +std::unique_ptr SockaddrToStorage(const sockaddr* src) { + if (src == nullptr) { + return nullptr; + } + std::unique_ptr ss(new sockaddr_storage); + std::memcpy(ss.get(), src, SockaddrSize(src)); + return ss; +} -thread_local static sockaddr_union sin_buf; +thread_local sockaddr_storage ss_buffer; -struct sockaddr* ipPort2SocketAddress(const ByteArray& ip, uint16_t port) { - if (ip.size() == 4) { - struct sockaddr_in* sin = &sin_buf.sin; +sockaddr* IPPortToSockaddr(const ByteArray& ip, uint16_t port) { + sockaddr_storage* ss = &ss_buffer; + if (ip.size() == kIPv4AddrSize) { + auto* sin = reinterpret_cast(ss); sin->sin_family = AF_INET; - sin->sin_port = ByteOrderUtil::NorminalBigEndian(port); - ByteOrderUtil::Readsin_addr)>(&sin->sin_addr, ip.array()); - return (struct sockaddr*)sin; - } else if (ip.size() == 16) { - struct sockaddr_in6* sin6 = &sin_buf.sin6; + sin->sin_port = htons(port); + std::memcpy(&sin->sin_addr, ip.array(), kIPv4AddrSize); + } else if (ip.size() == kIPv6AddrSize) { + auto* sin6 = reinterpret_cast(&ss); sin6->sin6_family = AF_INET6; - sin6->sin6_port = ByteOrderUtil::NorminalBigEndian(port); - ByteOrderUtil::Readsin6_addr)>(&sin6->sin6_addr, ip.array()); - return (struct sockaddr*)sin6; + sin6->sin6_port = htons(port); + std::memcpy(&sin6->sin6_addr, ip.array(), kIPv6AddrSize); + } else { + throw std::invalid_argument("invalid ip size"); } - return nullptr; + return reinterpret_cast(ss); } -struct sockaddr* string2SocketAddress(const std::string& addr) { +sockaddr* StringToSockaddr(const std::string& addr) { + if (addr.empty()) { + throw std::invalid_argument("invalid address"); + } + std::string::size_type start_pos = addr[0] == '/' ? 1 : 0; - auto colon_pos = addr.find_last_of(":"); - std::string host = addr.substr(start_pos, colon_pos - start_pos); - std::string port = addr.substr(colon_pos + 1, addr.length() - colon_pos); - auto* sa = lookupNameServers(host); - if (sa != nullptr) { - if (sa->sa_family == AF_INET) { - auto* sin = (struct sockaddr_in*)sa; - sin->sin_port = htons((uint16_t)std::stoi(port)); - } else { - auto* sin6 = (struct sockaddr_in6*)sa; - sin6->sin6_port = htons((uint16_t)std::stoi(port)); + auto colon_pos = addr.find_last_of(':'); + auto bracket_pos = addr.find_last_of(']'); + if (bracket_pos != std::string::npos) { + // ipv6 address + if (addr.at(start_pos) != '[') { + throw std::invalid_argument("invalid address"); + } + if (colon_pos == std::string::npos) { + throw std::invalid_argument("invalid address"); } + if (colon_pos < bracket_pos) { + // have not port + if (bracket_pos != addr.size() - 1) { + throw std::invalid_argument("invalid address"); + } + colon_pos = addr.size(); + } else if (colon_pos != bracket_pos + 1) { + throw std::invalid_argument("invalid address"); + } + } else if (colon_pos == std::string::npos) { + // have not port + colon_pos = addr.size(); } + + decltype(bracket_pos) fix_bracket = bracket_pos == std::string::npos ? 0 : 1; + std::string host = addr.substr(start_pos + fix_bracket, colon_pos - start_pos - fix_bracket * 2); + auto* sa = LookupNameServers(host); + + std::string port = colon_pos >= addr.size() ? "0" : addr.substr(colon_pos + 1); + uint32_t n = std::stoul(port); + if (n > std::numeric_limits::max()) { + throw std::out_of_range("port is to large"); + } + uint16_t port_num = htons(static_cast(n)); + + if (sa->sa_family == AF_INET) { + auto* sin = reinterpret_cast(sa); + sin->sin_port = port_num; + } else if (sa->sa_family == AF_INET6) { + auto* sin6 = reinterpret_cast(sa); + sin6->sin6_port = port_num; + } else { + throw std::runtime_error("don't support non-inet address families"); + } + return sa; } /** - * converts an address from network format to presentation format (a.b.c.d) + * converts an address from network format to presentation format */ -std::string socketAddress2String(const struct sockaddr* addr) { +std::string SockaddrToString(const sockaddr* addr) { if (nullptr == addr) { - return "127.0.0.1"; + return std::string(); } char buf[128]; @@ -90,38 +132,40 @@ std::string socketAddress2String(const struct sockaddr* addr) { uint16_t port = 0; if (addr->sa_family == AF_INET) { - auto* sin = (struct sockaddr_in*)addr; - if (nullptr != evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf))) { - address = buf; + const auto* sin = reinterpret_cast(addr); + if (nullptr == evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf))) { + throw std::runtime_error("can not convert AF_INET address to text form"); } + address = buf; port = ntohs(sin->sin_port); } else if (addr->sa_family == AF_INET6) { - auto* sin6 = (struct sockaddr_in6*)addr; - if (nullptr != evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf))) { - address = buf; + const auto* sin6 = reinterpret_cast(addr); + if (nullptr == evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf))) { + throw std::runtime_error("can not convert AF_INET6 address to text form"); } + address = buf; port = ntohs(sin6->sin6_port); } else { - throw std::runtime_error("don't support non-inet Address families."); + throw std::runtime_error("don't support non-inet address families"); } - if (!address.empty() && port != 0) { - if (addr->sa_family == AF_INET6) { - address = "[" + address + "]"; - } - address += ":" + UtilAll::to_string(port); + if (addr->sa_family == AF_INET6) { + address = "[" + address + "]"; + } + if (port != 0) { + address += ":" + std::to_string(port); } return address; } -struct sockaddr* lookupNameServers(const std::string& hostname) { +sockaddr* LookupNameServers(const std::string& hostname) { if (hostname.empty()) { - return nullptr; + throw std::invalid_argument("invalid hostname"); } - struct evutil_addrinfo hints; - struct evutil_addrinfo* answer = NULL; + evutil_addrinfo hints; + evutil_addrinfo* answer = nullptr; /* Build the hints to tell getaddrinfo how to act. */ std::memset(&hints, 0, sizeof(hints)); @@ -131,48 +175,63 @@ struct sockaddr* lookupNameServers(const std::string& hostname) { hints.ai_flags = EVUTIL_AI_ADDRCONFIG; /* Only return addresses we can use. */ // Look up the hostname. - int err = evutil_getaddrinfo(hostname.c_str(), NULL, &hints, &answer); + int err = evutil_getaddrinfo(hostname.c_str(), nullptr, &hints, &answer); if (err != 0) { - std::string info = "Failed to resolve host name(" + hostname + "): " + evutil_gai_strerror(err); + std::string info = "Failed to resolve hostname(" + hostname + "): " + evutil_gai_strerror(err); THROW_MQEXCEPTION(UnknownHostException, info, -1); } - struct sockaddr* sin = nullptr; + sockaddr_storage* ss = &ss_buffer; - for (struct evutil_addrinfo* ai = answer; ai != NULL; ai = ai->ai_next) { + bool hit = false; + for (struct evutil_addrinfo* ai = answer; ai != nullptr; ai = ai->ai_next) { auto* ai_addr = ai->ai_addr; if (ai_addr->sa_family != AF_INET && ai_addr->sa_family != AF_INET6) { continue; } - sin = (struct sockaddr*)&sin_buf; - std::memcpy(sin, ai_addr, sockaddr_size(ai_addr)); + std::memcpy(ss, ai_addr, SockaddrSize(ai_addr)); + hit = true; break; } evutil_freeaddrinfo(answer); - return sin; + if (!hit) { + throw std::runtime_error("hostname is non-inet address family"); + } + + return reinterpret_cast(ss); } -struct sockaddr* copySocketAddress(struct sockaddr* dst, const struct sockaddr* src) { - if (src != nullptr) { - if (dst == nullptr || dst->sa_family != src->sa_family) { - dst = (struct sockaddr*)std::realloc(dst, sizeof(union sockaddr_union)); - } - std::memcpy(dst, src, sockaddr_size(src)); - } else { - free(dst); - dst = nullptr; +sockaddr* GetSelfIP() { + try { + return LookupNameServers(GetLocalHostname()); + } catch (const UnknownHostException& e) { + return LookupNameServers("localhost"); } - return dst; } -uint64_t h2nll(uint64_t v) { - return ByteOrderUtil::NorminalBigEndian(v); +const std::string& GetLocalHostname() { + static std::string local_hostname = []() { + char name[1024]; + if (::gethostname(name, sizeof(name)) != 0) { + return std::string(); + } + return std::string(name); + }(); + return local_hostname; } -uint64_t n2hll(uint64_t v) { - return ByteOrderUtil::NorminalBigEndian(v); +const std::string& GetLocalAddress() { + static std::string local_address = []() { + try { + return SockaddrToString(GetSelfIP()); + } catch (std::exception& e) { + std::cerr << e.what() << std::endl; + std::abort(); + } + }(); + return local_address; } } // namespace rocketmq diff --git a/src/transport/SocketUtil.h b/src/transport/SocketUtil.h index be18a38d7..6bfe5351d 100644 --- a/src/transport/SocketUtil.h +++ b/src/transport/SocketUtil.h @@ -17,13 +17,14 @@ #ifndef ROCKETMQ_TRANSPORT_SOCKETUTIL_H_ #define ROCKETMQ_TRANSPORT_SOCKETUTIL_H_ -#include +#include // size_t +#include // uint16_t #include #ifndef WIN32 -#include -#include +#include // sockaddr_in, AF_INET, sockaddr_in6, AF_INET6 +#include // sockaddr, sockaddr_storage #else #include #pragma comment(lib, "ws2_32.lib") @@ -33,21 +34,41 @@ namespace rocketmq { -static inline size_t sockaddr_size(const struct sockaddr* sa) { - return sa->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); +const size_t kIPv4AddrSize = 4; +const size_t kIPv6AddrSize = 16; + +static inline size_t IpaddrSize(const sockaddr* sa) { + assert(sa != nullptr); + assert(sa->sa_family == AF_INET || sa->sa_family == AF_INET6); + return sa->sa_family == AF_INET6 ? kIPv6AddrSize : kIPv4AddrSize; +} + +static inline size_t IpaddrSize(const sockaddr_storage* ss) { + return IpaddrSize(reinterpret_cast(ss)); +} + +static inline size_t SockaddrSize(const sockaddr* sa) { + assert(sa != nullptr); + assert(sa->sa_family == AF_INET || sa->sa_family == AF_INET6); + return sa->sa_family == AF_INET6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in); +} + +static inline size_t SockaddrSize(const sockaddr_storage* ss) { + return SockaddrSize(reinterpret_cast(ss)); } -struct sockaddr* ipPort2SocketAddress(const ByteArray& ip, uint16_t port); +std::unique_ptr SockaddrToStorage(const sockaddr* src); -struct sockaddr* string2SocketAddress(const std::string& addr); -std::string socketAddress2String(const struct sockaddr* addr); +sockaddr* IPPortToSockaddr(const ByteArray& ip, uint16_t port); -struct sockaddr* lookupNameServers(const std::string& hostname); +sockaddr* StringToSockaddr(const std::string& addr); +std::string SockaddrToString(const sockaddr* addr); -struct sockaddr* copySocketAddress(struct sockaddr* dst, const struct sockaddr* src); +sockaddr* LookupNameServers(const std::string& hostname); -uint64_t h2nll(uint64_t v); -uint64_t n2hll(uint64_t v); +sockaddr* GetSelfIP(); +const std::string& GetLocalHostname(); +const std::string& GetLocalAddress(); } // namespace rocketmq From 44b846ed14ab6833c5625449ea54685c6a32acce Mon Sep 17 00:00:00 2001 From: James Yin Date: Wed, 24 Mar 2021 16:47:24 +0800 Subject: [PATCH 48/62] fix: test --- test/CMakeLists.txt | 7 +++--- test/src/message/MQMessageExtTest.cpp | 14 +++++------- test/src/message/MessageDecoderTest.cpp | 22 ++++++++++--------- test/src/message/MessageIdTest.cpp | 13 ++++++----- test/src/protocol/ConsumerRunningInfoTest.cpp | 4 ++-- test/src/protocol/ProcessQueueInfoTest.cpp | 3 ++- .../transport/ClientRemotingProcessorTest.cpp | 11 +++++----- test/src/transport/ResponseFutureTest.cpp | 7 +++--- test/src/transport/SocketUtilTest.cpp | 10 ++++----- 9 files changed, 47 insertions(+), 44 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 41cff8245..d6e56ebab 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -22,9 +22,8 @@ set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${CMAKE_SOURCE_DIR}/bin/lib64/cmake;${CMAKE_SOURCE_DIR}/bin/lib/cmake") # Find dependencies -if (CMAKE_VERSION VERSION_LESS "3.0") - find_package(GTest 1.10.0 REQUIRED CONFIG) -else () +#find_package(GTest REQUIRED CONFIG) +if (NOT GTest_FOUND) include_directories("${CMAKE_SOURCE_DIR}/bin/include") if (EXISTS "${CMAKE_SOURCE_DIR}/bin/lib64/libgtest.a") @@ -55,7 +54,7 @@ function(config_test file) endif() endif() - if (CMAKE_VERSION VERSION_LESS "3.0") + if (GTest_FOUND) if (BUILD_ROCKETMQ_SHARED) target_link_libraries(${basename} rocketmq_shared GTest::gtest GTest::gtest_main GTest::gmock GTest::gmock_main) diff --git a/test/src/message/MQMessageExtTest.cpp b/test/src/message/MQMessageExtTest.cpp index b889aa8a6..702233c4f 100644 --- a/test/src/message/MQMessageExtTest.cpp +++ b/test/src/message/MQMessageExtTest.cpp @@ -89,18 +89,19 @@ TEST(MessageExtTest, MessageClientExtImpl) { messageClientExt.set_store_timestamp(2222); EXPECT_EQ(messageClientExt.store_timestamp(), 2222); - messageClientExt.set_born_host(rocketmq::string2SocketAddress("127.0.0.1:10091")); + messageClientExt.set_born_host(rocketmq::StringToSockaddr("127.0.0.1:10091")); EXPECT_EQ(messageClientExt.born_host_string(), "127.0.0.1:10091"); - messageClientExt.set_store_host(rocketmq::string2SocketAddress("127.0.0.2:10092")); + messageClientExt.set_store_host(rocketmq::StringToSockaddr("127.0.0.2:10092")); EXPECT_EQ(messageClientExt.store_host_string(), "127.0.0.2:10092"); } TEST(MessageExtTest, MessageExt) { - struct sockaddr* bronHost = rocketmq::copySocketAddress(nullptr, rocketmq::string2SocketAddress("127.0.0.1:10091")); - struct sockaddr* storeHost = rocketmq::copySocketAddress(nullptr, rocketmq::string2SocketAddress("127.0.0.2:10092")); + auto bronHost = rocketmq::SockaddrToStorage(rocketmq::StringToSockaddr("127.0.0.1:10091")); + auto storeHost = rocketmq::SockaddrToStorage(rocketmq::StringToSockaddr("127.0.0.2:10092")); - MQMessageExt messageExt(2, 1024, bronHost, 2048, storeHost, "msgId"); + MQMessageExt messageExt(2, 1024, reinterpret_cast(bronHost.get()), 2048, + reinterpret_cast(storeHost.get()), "msgId"); EXPECT_EQ(messageExt.queue_offset(), 0); EXPECT_EQ(messageExt.commit_log_offset(), 0); EXPECT_EQ(messageExt.born_timestamp(), 1024); @@ -113,9 +114,6 @@ TEST(MessageExtTest, MessageExt) { EXPECT_EQ(messageExt.msg_id(), "msgId"); EXPECT_EQ(messageExt.born_host_string(), "127.0.0.1:10091"); EXPECT_EQ(messageExt.store_host_string(), "127.0.0.2:10092"); - - free(bronHost); - free(storeHost); } TEST(MessageExtTest, ParseTopicFilterType) { diff --git a/test/src/message/MessageDecoderTest.cpp b/test/src/message/MessageDecoderTest.cpp index d602d80aa..74e55ce77 100644 --- a/test/src/message/MessageDecoderTest.cpp +++ b/test/src/message/MessageDecoderTest.cpp @@ -14,16 +14,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#include -#include +#include "MessageDecoder.h" #include #include +#include + +#include +#include + #include "ByteArray.h" #include "ByteBuffer.hpp" -#include "MessageDecoder.h" #include "MQMessage.h" #include "MQMessageConst.h" #include "MQMessageExt.h" @@ -39,12 +41,12 @@ using testing::Return; using rocketmq::ByteArray; using rocketmq::ByteBuffer; -using rocketmq::MessageSysFlag; using rocketmq::MessageDecoder; +using rocketmq::MessageId; +using rocketmq::MessageSysFlag; using rocketmq::MQMessage; using rocketmq::MQMessageConst; using rocketmq::MQMessageExt; -using rocketmq::MessageId; using rocketmq::RemotingCommand; using rocketmq::SendMessageRequestHeader; using rocketmq::stoba; @@ -52,13 +54,13 @@ using rocketmq::UtilAll; // TODO TEST(MessageDecoderTest, MessageId) { - std::string strMsgId = MessageDecoder::createMessageId(rocketmq::string2SocketAddress("127.0.0.1:10091"), 1024LL); + std::string strMsgId = MessageDecoder::createMessageId(rocketmq::StringToSockaddr("127.0.0.1:10091"), 1024LL); EXPECT_EQ(strMsgId, "7F0000010000276B0000000000000400"); MessageId msgId = MessageDecoder::decodeMessageId(strMsgId); EXPECT_EQ(msgId.getOffset(), 1024LL); - std::string strMsgId2 = MessageDecoder::createMessageId(rocketmq::string2SocketAddress("/172.16.2.114:0"), 123456LL); + std::string strMsgId2 = MessageDecoder::createMessageId(rocketmq::StringToSockaddr("/172.16.2.114:0"), 123456LL); EXPECT_EQ(strMsgId2, "AC10027200000000000000000001E240"); MessageId msgId2 = MessageDecoder::decodeMessageId(strMsgId2); @@ -107,7 +109,7 @@ TEST(MessageDecoderTest, Decode) { // 10 BORNHOST 56=48+4+4 byteBuffer->putInt(ntohl(inet_addr("127.0.0.1"))); byteBuffer->putInt(10091); - msgExt.set_born_host(rocketmq::string2SocketAddress("127.0.0.1:10091")); + msgExt.set_born_host(rocketmq::StringToSockaddr("127.0.0.1:10091")); // 11 STORETIMESTAMP 64=56+8 byteBuffer->putLong(4096LL); @@ -116,7 +118,7 @@ TEST(MessageDecoderTest, Decode) { // 12 STOREHOST 72=64+4+4 byteBuffer->putInt(ntohl(inet_addr("127.0.0.2"))); byteBuffer->putInt(10092); - msgExt.set_store_host(rocketmq::string2SocketAddress("127.0.0.2:10092")); + msgExt.set_store_host(rocketmq::StringToSockaddr("127.0.0.2:10092")); // 13 RECONSUMETIMES 76=72+4 byteBuffer->putInt(18); diff --git a/test/src/message/MessageIdTest.cpp b/test/src/message/MessageIdTest.cpp index aa0900670..19efbf43d 100644 --- a/test/src/message/MessageIdTest.cpp +++ b/test/src/message/MessageIdTest.cpp @@ -14,11 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "MessageId.h" +#include "SocketUtil.h" + #include #include -#include "MessageId.h" - using namespace std; using testing::InitGoogleMock; using testing::InitGoogleTest; @@ -27,12 +28,12 @@ using testing::Return; using rocketmq::MessageId; TEST(MessageIdTest, MessageId) { - MessageId msgId(rocketmq::string2SocketAddress("127.0.0.1:10091"), 1024); - EXPECT_EQ(rocketmq::socketAddress2String(msgId.getAddress()), "127.0.0.1:10091"); + MessageId msgId(rocketmq::StringToSockaddr("127.0.0.1:10091"), 1024); + EXPECT_EQ(rocketmq::SockaddrToString(msgId.getAddress()), "127.0.0.1:10091"); EXPECT_EQ(msgId.getOffset(), 1024); - msgId.setAddress(rocketmq::string2SocketAddress("127.0.0.2:10092")); - EXPECT_EQ(rocketmq::socketAddress2String(msgId.getAddress()), "127.0.0.2:10092"); + msgId.setAddress(rocketmq::StringToSockaddr("127.0.0.2:10092")); + EXPECT_EQ(rocketmq::SockaddrToString(msgId.getAddress()), "127.0.0.2:10092"); msgId.setOffset(2048); EXPECT_EQ(msgId.getOffset(), 2048); diff --git a/test/src/protocol/ConsumerRunningInfoTest.cpp b/test/src/protocol/ConsumerRunningInfoTest.cpp index 7c3dc8f12..74c21aae5 100644 --- a/test/src/protocol/ConsumerRunningInfoTest.cpp +++ b/test/src/protocol/ConsumerRunningInfoTest.cpp @@ -14,6 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "protocol/body/ConsumerRunningInfo.h" + #include #include #include @@ -23,8 +25,6 @@ #include #include -#include "ConsumerRunningInfo.h" - using std::map; using std::string; diff --git a/test/src/protocol/ProcessQueueInfoTest.cpp b/test/src/protocol/ProcessQueueInfoTest.cpp index cfd1a5664..dcb544ae8 100644 --- a/test/src/protocol/ProcessQueueInfoTest.cpp +++ b/test/src/protocol/ProcessQueueInfoTest.cpp @@ -14,11 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "protocol/body/ProcessQueueInfo.hpp" + #include #include #include "MQMessageExt.h" -#include "ProcessQueueInfo.h" using testing::InitGoogleMock; using testing::InitGoogleTest; diff --git a/test/src/transport/ClientRemotingProcessorTest.cpp b/test/src/transport/ClientRemotingProcessorTest.cpp index 1a840d939..e751a1430 100644 --- a/test/src/transport/ClientRemotingProcessorTest.cpp +++ b/test/src/transport/ClientRemotingProcessorTest.cpp @@ -14,18 +14,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "ClientRemotingProcessor.h" + +#include +#include + #include #include #include #include -#include -#include - #include "ByteArray.h" #include "ClientRPCHook.h" -#include "ClientRemotingProcessor.h" -#include "ConsumerRunningInfo.h" #include "MQClientConfigImpl.hpp" #include "MQClientInstance.h" #include "MQMessageQueue.h" @@ -34,6 +34,7 @@ #include "SessionCredentials.h" #include "TcpTransport.h" #include "UtilAll.h" +#include "protocol/body/ConsumerRunningInfo.h" #include "protocol/body/ResetOffsetBody.hpp" #include "protocol/header/CommandHeader.h" diff --git a/test/src/transport/ResponseFutureTest.cpp b/test/src/transport/ResponseFutureTest.cpp index 9826c82c1..15680d9aa 100644 --- a/test/src/transport/ResponseFutureTest.cpp +++ b/test/src/transport/ResponseFutureTest.cpp @@ -14,12 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "ResponseFuture.h" + #include #include #include "InvokeCallback.h" #include "RemotingCommand.h" -#include "ResponseFuture.h" #include "UtilAll.h" #include "protocol/RequestCode.h" @@ -48,8 +49,8 @@ TEST(ResponseFutureTest, Init) { EXPECT_FALSE(responseFuture.hasInvokeCallback()); // ~ResponseFuture delete callback - auto* callback = new MockInvokeCallback(); - ResponseFuture twoResponseFuture(MQRequestCode::QUERY_BROKER_OFFSET, 4, 1000, callback); + ResponseFuture twoResponseFuture(MQRequestCode::QUERY_BROKER_OFFSET, 4, 1000, + std::unique_ptr(new MockInvokeCallback())); EXPECT_TRUE(twoResponseFuture.hasInvokeCallback()); } diff --git a/test/src/transport/SocketUtilTest.cpp b/test/src/transport/SocketUtilTest.cpp index e7b8a7089..985d82634 100644 --- a/test/src/transport/SocketUtilTest.cpp +++ b/test/src/transport/SocketUtilTest.cpp @@ -14,11 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "SocketUtil.h" + #include #include -#include "SocketUtil.h" - using testing::InitGoogleMock; using testing::InitGoogleTest; using testing::Return; @@ -29,14 +29,14 @@ using namespace rocketmq; TEST(SocketUtilTest, Convert) { char ip[] = {0x7F, 0x00, 0x00, 0x01}; - struct sockaddr* sa = ipPort2SocketAddress(ByteArray(ip, sizeof(ip)), 0x276B); + struct sockaddr* sa = IPPortToSockaddr(ByteArray(ip, sizeof(ip)), 0x276B); struct sockaddr_in* sin = (struct sockaddr_in*)sa; EXPECT_EQ(sin->sin_addr.s_addr, 0x0100007F); EXPECT_EQ(sin->sin_port, 0x6B27); - EXPECT_EQ(socketAddress2String(sa), "127.0.0.1:10091"); + EXPECT_EQ(SockaddrToString(sa), "127.0.0.1:10091"); - sa = string2SocketAddress("127.0.0.1:10091"); + sa = StringToSockaddr("127.0.0.1:10091"); sin = (struct sockaddr_in*)sa; EXPECT_EQ(sin->sin_addr.s_addr, 0x0100007F); EXPECT_EQ(sin->sin_port, 0x6B27); From 112f09f1bdace8a55fcbc64873554c7139da00e2 Mon Sep 17 00:00:00 2001 From: James Yin Date: Fri, 26 Mar 2021 09:09:31 +0800 Subject: [PATCH 49/62] fix: bundle_static_library for apple clang --- cmake/BundleStaticLibrary.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/BundleStaticLibrary.cmake b/cmake/BundleStaticLibrary.cmake index 782eec4b1..04659db16 100644 --- a/cmake/BundleStaticLibrary.cmake +++ b/cmake/BundleStaticLibrary.cmake @@ -69,7 +69,7 @@ function(bundle_static_library tgt_name bundled_tgt_name) ${LIBRARY_OUTPUT_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}${bundled_tgt_name}${CMAKE_STATIC_LIBRARY_SUFFIX} ) - if(CMAKE_CXX_COMPILER_ID MATCHES "^(Clang|GNU)$") + if(CMAKE_CXX_COMPILER_ID MATCHES "^(AppleClang|Clang|GNU)$") file(WRITE ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in "CREATE ${bundled_tgt_full_name}\n") From eca58359185744d041d4835d06774d6e600c3fbe Mon Sep 17 00:00:00 2001 From: James Yin Date: Fri, 26 Mar 2021 14:34:14 +0800 Subject: [PATCH 50/62] refactor: cmake scripts --- CMakeLists.txt | 238 ++++++++++++++++---------------- cmake/BundleStaticLibrary.cmake | 83 ++++++----- cmake/FindJsoncpp.cmake | 93 ++++++------- cmake/FindLibevent.cmake | 226 ++++++++++++++++-------------- project/CMakeLists.txt | 105 +++++++------- test/CMakeLists.txt | 112 +++++++-------- 6 files changed, 447 insertions(+), 410 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e39910e61..33a1d4ddf 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,59 +16,59 @@ cmake_minimum_required(VERSION 2.8) # CMake complains if we don't have this. -if (COMMAND cmake_policy) - cmake_policy(SET CMP0003 NEW) -endif () - -# We're escaping quotes in the Windows version number, because -# for some reason CMake won't do it at config version 2.4.7 -# It seems that this restores the newer behaviour where define -# args are not auto-escaped. -if (COMMAND cmake_policy) - cmake_policy(SET CMP0005 NEW) -endif () +if(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +endif() + +# We're escaping quotes in the Windows version number, because for some reason +# CMake won't do it at config version 2.4.7 It seems that this restores the +# newer behaviour where define args are not auto-escaped. +if(COMMAND cmake_policy) + cmake_policy(SET CMP0005 NEW) +endif() # First, declare project (important for prerequisite checks). project(rocketmq-client-cpp) -if (NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release") -endif () -if (NOT CMAKE_CONFIGURATION_TYPES) - set(CMAKE_CONFIGURATION_TYPES "Release") -endif () +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release") +endif() +if(NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_CONFIGURATION_TYPES "Release") +endif() set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) set(CMAKE_VERBOSE_MAKEFILE 1) -if (APPLE) - set(CMAKE_MACOSX_RPATH 1) -endif (APPLE) +if(APPLE) + set(CMAKE_MACOSX_RPATH 1) +endif(APPLE) # put binaries in a different dir to make them easier to find. set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) # Find dependencies -#find_package(spdlog REQUIRED) -if (NOT spdlog_FOUND) - include_directories(${CMAKE_SOURCE_DIR}/bin/include) -endif () - -option(Libevent_USE_STATIC_LIBS "only find libevent static libs" OFF) # only find static libs -if (NOT LIBEVENT_ROOT) - set(LIBEVENT_ROOT ${CMAKE_SOURCE_DIR}/bin) -endif () + +# find_package(spdlog REQUIRED) +if(NOT spdlog_FOUND) + include_directories(${CMAKE_SOURCE_DIR}/bin/include) +endif() + +option(Libevent_USE_STATIC_LIBS "only find libevent static libs" OFF) +if(NOT LIBEVENT_ROOT) + set(LIBEVENT_ROOT ${CMAKE_SOURCE_DIR}/bin) +endif() find_package(Libevent 2.0.21 REQUIRED) -message(STATUS "** LIBEVENT_INCLUDE_DIR: ${LIBEVENT_INCLUDE_DIR}") +message(STATUS "** LIBEVENT_INCLUDE_DIRS: ${LIBEVENT_INCLUDE_DIRS}") message(STATUS "** LIBEVENT_LIBRARIES: ${LIBEVENT_LIBRARIES}") -option(JSONCPP_USE_STATIC_LIBS "only find jsoncpp static libs" OFF) # only find static libs -if (NOT JSONCPP_ROOT) - set(JSONCPP_ROOT ${CMAKE_SOURCE_DIR}/bin) -endif () +option(JSONCPP_USE_STATIC_LIBS "only find jsoncpp static libs" OFF) +if(NOT JSONCPP_ROOT) + set(JSONCPP_ROOT ${CMAKE_SOURCE_DIR}/bin) +endif() find_package(Jsoncpp 0.10.6 REQUIRED) message(STATUS "** JSONCPP_INCLUDE_DIRS: ${JSONCPP_INCLUDE_DIRS}") message(STATUS "** JSONCPP_LIBRARIES: ${JSONCPP_LIBRARIES}") @@ -76,97 +76,93 @@ message(STATUS "** JSONCPP_LIBRARIES: ${JSONCPP_LIBRARIES}") # Set compile options include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) -CHECK_C_COMPILER_FLAG("-std=c99" COMPILER_SUPPORTS_C99) -CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) -if (COMPILER_SUPPORTS_C99 AND COMPILER_SUPPORTS_CXX11) - if (NOT (CMAKE_VERSION VERSION_LESS "3.1")) - set(CMAKE_C_STANDARD 99) - set(CMAKE_CXX_STANDARD 11) - message(STATUS "** set CMAKE_C_STANDARD to 99") - message(STATUS "** set CMAKE_CXX_STANDARD to 11") - else () - if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") - set(C_STANDARD_FLAG "-std=gnu99") - set(CXX_STANDARD_FLAG "-std=gnu++11") - else () - set(C_STANDARD_FLAG "-std=c99") - set(CXX_STANDARD_FLAG "-std=c++11") - endif () - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_STANDARD_FLAG}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD_FLAG}") - message(STATUS "** set CMAKE_C_FLAGS with ${C_STANDARD_FLAG}") - message(STATUS "** set CMAKE_CXX_FLAGS with ${CXX_STANDARD_FLAG}") - endif () -else () - message(FATAL_ERROR "The compiler has no C99 or C++11 support.") -endif () - -if (WIN32) - add_definitions(-DWIN32 -DROCKETMQCLIENT_EXPORTS) - add_compile_options(/EHsc) - if (CMAKE_BUILD_TYPE EQUAL "Release") - add_compile_options(/MT) - else () - add_compile_options(/MTd) - endif () -else () - add_compile_options(-Wall - -Wno-deprecated - -fPIC - -fno-strict-aliasing - -Wno-unused-local-typedef - -Wno-expansion-to-defined) - - if (CMAKE_BUILD_BITS EQUAL 32) - add_compile_options(-m32) - else () #not-condition - add_compile_options(-m64) - endif () - - # Declare deplibs, so we can use list in linker later. There's probably - # a more elegant way of doing this; with SCons, when you check for the - # lib, it is automatically passed to the linker. - set(deplibs) - - # For some reason, the check_function_exists macro doesn't detect - # the inet_aton on some pure Unix platforms (e.g. sunos5). So we - # need to do a more detailed check and also include some extra deplibs. - list(APPEND deplibs dl) - list(APPEND deplibs pthread) - if (NOT APPLE) - list(APPEND deplibs rt) - endif () - list(APPEND deplibs z) - - option(CODE_COVERAGE "Enable coverage reporting" OFF) - if (CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - # Add required flags (GCC & LLVM/Clang) - # Code Coverage Configuration - add_library(coverage_config INTERFACE) - target_compile_options(coverage_config INTERFACE - -O0 # no optimization - -g # generate debug info +check_c_compiler_flag("-std=c99" COMPILER_SUPPORTS_C99) +check_cxx_compiler_flag("-std=c++11" COMPILER_SUPPORTS_CXX11) +if(COMPILER_SUPPORTS_C99 AND COMPILER_SUPPORTS_CXX11) + if(NOT (CMAKE_VERSION VERSION_LESS "3.1")) + set(CMAKE_C_STANDARD 99) + set(CMAKE_CXX_STANDARD 11) + message(STATUS "** set CMAKE_C_STANDARD to 99") + message(STATUS "** set CMAKE_CXX_STANDARD to 11") + else() + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + set(C_STANDARD_FLAG "-std=gnu99") + set(CXX_STANDARD_FLAG "-std=gnu++11") + else() + set(C_STANDARD_FLAG "-std=c99") + set(CXX_STANDARD_FLAG "-std=c++11") + endif() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_STANDARD_FLAG}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD_FLAG}") + message(STATUS "** set CMAKE_C_FLAGS with ${C_STANDARD_FLAG}") + message(STATUS "** set CMAKE_CXX_FLAGS with ${CXX_STANDARD_FLAG}") + endif() +else() + message(FATAL_ERROR "The compiler has no C99 or C++11 support.") +endif() + +if(WIN32) + add_definitions(-DWIN32 -DROCKETMQCLIENT_EXPORTS) + add_compile_options(/EHsc) + if(CMAKE_BUILD_TYPE EQUAL "Release") + add_compile_options(/MT) + else() + add_compile_options(/MTd) + endif() +else() + add_compile_options(-Wall -Wno-deprecated -fPIC -fno-strict-aliasing + -Wno-unused-local-typedef -Wno-expansion-to-defined) + + if(CMAKE_BUILD_BITS EQUAL 32) + add_compile_options(-m32) + else() # not-condition + add_compile_options(-m64) + endif() + + # Declare deplibs, so we can use list in linker later. There's probably a more + # elegant way of doing this; with SCons, when you check for the lib, it is + # automatically passed to the linker. + set(deplibs) + + # For some reason, the check_function_exists macro doesn't detect the + # inet_aton on some pure Unix platforms (e.g. sunos5). So we need to do a more + # detailed check and also include some extra deplibs. + list(APPEND deplibs dl) + list(APPEND deplibs pthread) + if(NOT APPLE) + list(APPEND deplibs rt) + endif() + list(APPEND deplibs z) + + option(CODE_COVERAGE "Enable coverage reporting" OFF) + if(CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + # Add required flags (GCC & LLVM/Clang) Code Coverage Configuration + add_library(coverage_config INTERFACE) + target_compile_options( + coverage_config + INTERFACE -O0 # no optimization + -g # generate debug info --coverage # sets all required flags - ) - if (NOT (CMAKE_VERSION VERSION_LESS "3.13")) - target_link_options(coverage_config INTERFACE --coverage) - else () - target_link_libraries(coverage_config INTERFACE --coverage) - endif () - list(APPEND deplibs coverage_config) - endif (CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - - # add include dir for bsd (posix uses /usr/include/) - set(CMAKE_INCLUDE_PATH "${CMAKE_INCLUDE_PATH}:/usr/local/include") -endif () + ) + if(NOT (CMAKE_VERSION VERSION_LESS "3.13")) + target_link_options(coverage_config INTERFACE --coverage) + else() + target_link_libraries(coverage_config INTERFACE --coverage) + endif() + list(APPEND deplibs coverage_config) + endif(CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + + # add include dir for bsd (posix uses /usr/include/) + set(CMAKE_INCLUDE_PATH "${CMAKE_INCLUDE_PATH}:/usr/local/include") +endif() add_subdirectory(libs) add_subdirectory(project) add_subdirectory(example) option(RUN_UNIT_TEST "RUN_UNIT_TEST" OFF) -if (RUN_UNIT_TEST) - message(STATUS "** RUN_UNIT_TEST: Do execution testing") - enable_testing() - add_subdirectory(test) -endif () +if(RUN_UNIT_TEST) + message(STATUS "** RUN_UNIT_TEST: Do execution testing") + enable_testing() + add_subdirectory(test) +endif() diff --git a/cmake/BundleStaticLibrary.cmake b/cmake/BundleStaticLibrary.cmake index 04659db16..c53d317b4 100644 --- a/cmake/BundleStaticLibrary.cmake +++ b/cmake/BundleStaticLibrary.cmake @@ -12,7 +12,7 @@ # 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. - +# # ref: https://cristianadam.eu/20190501/bundling-together-static-libraries-with-cmake/ set(STATIC_LIBRARY_REGEX "${CMAKE_STATIC_LIBRARY_SUFFIX}") @@ -50,7 +50,8 @@ function(bundle_static_library tgt_name bundled_tgt_name) _recursively_collect_dependencies(${dependency}) endif() else() - string(REGEX MATCH ${STATIC_LIBRARY_REGEX} IS_STATIC_LIBRARY ${dependency}) + string(REGEX MATCH ${STATIC_LIBRARY_REGEX} IS_STATIC_LIBRARY + ${dependency}) if(IS_STATIC_LIBRARY) list(APPEND static_libs ${dependency}) endif() @@ -69,42 +70,60 @@ function(bundle_static_library tgt_name bundled_tgt_name) ${LIBRARY_OUTPUT_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}${bundled_tgt_name}${CMAKE_STATIC_LIBRARY_SUFFIX} ) + message(STATUS "Bundling static library: ${bundled_tgt_full_name}") if(CMAKE_CXX_COMPILER_ID MATCHES "^(AppleClang|Clang|GNU)$") - file(WRITE ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in - "CREATE ${bundled_tgt_full_name}\n") + if(APPLE) + find_program(LIB_TOOL libtool REQUIRED) + + foreach(tgt IN LISTS static_libs) + if(TARGET ${tgt}) + list(APPEND static_libs_full_names $) + else() + list(APPEND static_libs_full_names ${tgt}) + endif() + endforeach() + + add_custom_command( + OUTPUT ${bundled_tgt_full_name} + COMMAND ${LIB_TOOL} -no_warning_for_no_symbols -static -o + ${bundled_tgt_full_name} ${static_libs_full_names} + COMMENT "Bundling ${bundled_tgt_name}" + VERBATIM) + else() + file(WRITE ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in + "CREATE ${bundled_tgt_full_name}\n") + + foreach(tgt IN LISTS static_libs) + if(TARGET ${tgt}) + file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in + "ADDLIB $\n") + else() + file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in + "ADDLIB ${tgt}\n") + endif() + endforeach() - foreach(tgt IN LISTS static_libs) - if(TARGET ${tgt}) - file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in - "ADDLIB $\n") - else() - file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in - "ADDLIB ${tgt}\n") - endif() - endforeach() + file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in "SAVE\n") + file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in "END\n") - file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in "SAVE\n") - file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in "END\n") + file( + GENERATE + OUTPUT ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri + INPUT ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in) - file( - GENERATE - OUTPUT ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri - INPUT ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in) + set(AR_TOOL ${CMAKE_AR}) + if(CMAKE_INTERPROCEDURAL_OPTIMIZATION) + set(AR_TOOL ${CMAKE_CXX_COMPILER_AR}) + endif() - set(ar_tool ${CMAKE_AR}) - if(CMAKE_INTERPROCEDURAL_OPTIMIZATION) - set(ar_tool ${CMAKE_CXX_COMPILER_AR}) + add_custom_command( + OUTPUT ${bundled_tgt_full_name} + COMMAND ${AR_TOOL} -M < ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri + COMMENT "Bundling ${bundled_tgt_name}" + VERBATIM) endif() - - message( - STATUS "** Bundled static library: ${bundled_tgt_full_name}") - add_custom_command( - OUTPUT ${bundled_tgt_full_name} - COMMAND ${ar_tool} -M < ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri - COMMENT "Bundling ${bundled_tgt_name}" - VERBATIM) elseif(MSVC) - find_program(lib_tool lib) + find_program(LIB_TOOL lib REQUIRED) foreach(tgt IN LISTS static_libs) list(APPEND static_libs_full_names $) @@ -112,7 +131,7 @@ function(bundle_static_library tgt_name bundled_tgt_name) add_custom_command( OUTPUT ${bundled_tgt_full_name} - COMMAND ${lib_tool} /NOLOGO /OUT:${bundled_tgt_full_name} + COMMAND ${LIB_TOOL} /NOLOGO /OUT:${bundled_tgt_full_name} ${static_libs_full_names} COMMENT "Bundling ${bundled_tgt_name}" VERBATIM) diff --git a/cmake/FindJsoncpp.cmake b/cmake/FindJsoncpp.cmake index 4625ccfa1..b9a3ab3b1 100755 --- a/cmake/FindJsoncpp.cmake +++ b/cmake/FindJsoncpp.cmake @@ -12,7 +12,7 @@ # 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. - +# # Find jsoncpp # # Find the jsoncpp includes and library @@ -30,59 +30,58 @@ # JSONCPP_LIBRARIES, the libraries needed to use jsoncpp. # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES -if (JSONCPP_USE_STATIC_LIBS) - set(_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES}) - if (WIN32) - list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .lib .a) - else () - set(CMAKE_FIND_LIBRARY_SUFFIXES .a) - endif () -else () - set(_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES}) - if (WIN32) - list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .dll .so) - elseif (APPLE) - set(CMAKE_FIND_LIBRARY_SUFFIXES .dylib) - else () - set(CMAKE_FIND_LIBRARY_SUFFIXES .so) - endif () -endif () +if(JSONCPP_USE_STATIC_LIBS) + set(_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES}) + if(WIN32) + list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .lib .a) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a) + endif() +else() + set(_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES}) + if(WIN32) + list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .dll .so) + elseif(APPLE) + set(CMAKE_FIND_LIBRARY_SUFFIXES .dylib) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .so) + endif() +endif() set(JSONCPP_INCLUDE_SEARCH_PATH /usr/local/include /usr/include) set(JSONCPP_LIBRARIES_SEARCH_PATH /usr/local/lib /usr/lib) -if (JSONCPP_ROOT) - list(INSERT JSONCPP_INCLUDE_SEARCH_PATH 0 ${JSONCPP_ROOT}/include) - list(INSERT JSONCPP_LIBRARIES_SEARCH_PATH 0 ${JSONCPP_ROOT}/lib) -endif () +if(JSONCPP_ROOT) + list(INSERT JSONCPP_INCLUDE_SEARCH_PATH 0 ${JSONCPP_ROOT}/include) + list(INSERT JSONCPP_LIBRARIES_SEARCH_PATH 0 ${JSONCPP_ROOT}/lib) +endif() -find_path(JSONCPP_INCLUDE_DIRS - NAMES json.h json/json.h - PATHS ${JSONCPP_INCLUDE_SEARCH_PATH} - PATH_SUFFIXES jsoncpp) +find_path( + JSONCPP_JSON_DIR + NAMES json/json.h json.h + PATHS ${JSONCPP_INCLUDE_SEARCH_PATH} + PATH_SUFFIXES jsoncpp + NO_DEFAULT_PATH) -find_library(JSONCPP_LIBRARIES - NAMES jsoncpp - PATHS ${JSONCPP_LIBRARIES_SEARCH_PATH}) +find_library( + JSONCPP_JSONCPP_LIBRARY + NAMES jsoncpp + PATHS ${JSONCPP_LIBRARIES_SEARCH_PATH} + NO_DEFAULT_PATH) -if (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS) - set(JSONCPP_FOUND "YES") -else (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS) - set(JSONCPP_FOUND "NO") -endif (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Jsoncpp REQUIRED_VARS JSONCPP_JSON_DIR + JSONCPP_JSONCPP_LIBRARY) -if (JSONCPP_FOUND) - if (NOT JSONCPP_FIND_QUIETLY) - message(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}") - endif (NOT JSONCPP_FIND_QUIETLY) -else (JSONCPP_FOUND) - if (JSONCPP_FIND_REQUIRED) - message(FATAL_ERROR "Could not find JSONCPP library, include: ${JSONCPP_INCLUDE_DIRS}, lib: ${JSONCPP_LIBRARIES}") - endif (JSONCPP_FIND_REQUIRED) -endif (JSONCPP_FOUND) +if(JSONCPP_FOUND) + set(JSONCPP_INCLUDE_DIRS ${JSONCPP_JSON_DIR}) + set(JSONCPP_LIBRARIES ${JSONCPP_JSONCPP_LIBRARY}) +endif(JSONCPP_FOUND) +unset(JSONCPP_JSON_DIR) +unset(JSONCPP_JSONCPP_LIBRARY) -mark_as_advanced(JSONCPP_LIBRARIES JSONCPP_INCLUDE_DIRS) +mark_as_advanced(JSONCPP_INCLUDE_DIRS JSONCPP_LIBRARIES) # Restore the original find library ordering -if (JSONCPP_USE_STATIC_LIBS) - set(CMAKE_FIND_LIBRARY_SUFFIXES ${_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) -endif () +if(JSONCPP_USE_STATIC_LIBS) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) +endif() diff --git a/cmake/FindLibevent.cmake b/cmake/FindLibevent.cmake index 1b4ab6528..9702f48db 100755 --- a/cmake/FindLibevent.cmake +++ b/cmake/FindLibevent.cmake @@ -12,7 +12,7 @@ # 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. - +# # - Try to find libevent #.rst # FindLibevent @@ -37,125 +37,139 @@ # LIBEVENT__FOUND - Component was found ( is uppercase) # LIBEVENT__LIBRARY - Library to be linked for Libevent component . -find_package(PkgConfig QUIET) -pkg_check_modules(PC_LIBEVENT QUIET libevent) - # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES -if (Libevent_USE_STATIC_LIBS) - set(_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES}) - if (WIN32) - list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .lib .a) - else () - set(CMAKE_FIND_LIBRARY_SUFFIXES .a) - endif () -else () - set(_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES}) - if (WIN32) - list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .dll .so) - elseif (APPLE) - set(CMAKE_FIND_LIBRARY_SUFFIXES .dylib) - else () - set(CMAKE_FIND_LIBRARY_SUFFIXES .so) - endif () -endif () +if(Libevent_USE_STATIC_LIBS) + set(_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES + :${CMAKE_FIND_LIBRARY_SUFFIXES}) + if(WIN32) + list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .lib .a) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a) + endif() +else() + set(_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES + :${CMAKE_FIND_LIBRARY_SUFFIXES}) + if(WIN32) + list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .dll .so) + elseif(APPLE) + set(CMAKE_FIND_LIBRARY_SUFFIXES .dylib) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .so) + endif() +endif() +# default search path set(LIBEVENT_INCLUDE_SEARCH_PATH /usr/local/include /usr/include) set(LIBEVENT_LIBRARIES_SEARCH_PATH /usr/local/lib /usr/lib) -if (LIBEVENT_ROOT) - list(INSERT LIBEVENT_INCLUDE_SEARCH_PATH 0 ${LIBEVENT_ROOT}/include) - list(INSERT LIBEVENT_LIBRARIES_SEARCH_PATH 0 ${LIBEVENT_ROOT}/lib) -endif () + +# pkgconfig hint +find_package(PkgConfig QUIET) +pkg_check_modules(PC_LIBEVENT QUIET libevent) +if(PC_LIBEVENT_FOUND) + list(INSERT LIBEVENT_INCLUDE_SEARCH_PATH 0 ${PC_LIBEVENT_INCLUDE_DIRS}) + list(INSERT LIBEVENT_LIBRARIES_SEARCH_PATH 0 ${PC_LIBEVENT_LIBRARY_DIRS}) +endif() + +# custom search path +if(LIBEVENT_ROOT) + list(INSERT LIBEVENT_INCLUDE_SEARCH_PATH 0 ${LIBEVENT_ROOT}/include) + list(INSERT LIBEVENT_LIBRARIES_SEARCH_PATH 0 ${LIBEVENT_ROOT}/lib) +endif() + +set(_LIBEVENT_REQUIRED_VARS LIBEVENT_EVENT_CONFIG_DIR) # Look for the Libevent 2.0 or 1.4 headers -find_path(LIBEVENT_INCLUDE_DIR - NAMES event2/event-config.h event-config.h - PATHS ${LIBEVENT_INCLUDE_SEARCH_PATH} - HINTS ${PC_LIBEVENT_INCLUDE_DIRS}) +find_path( + LIBEVENT_EVENT_CONFIG_DIR + NAMES event2/event-config.h event-config.h + PATHS ${LIBEVENT_INCLUDE_SEARCH_PATH} + NO_DEFAULT_PATH) -# ------------------------------------------------------------------------ -# Prefix initialization -# ------------------------------------------------------------------------ -set(Libevent_LIB_PREFIX "") -set(LIBEVENT_EVENT_CONFIG_DIR ${LIBEVENT_INCLUDE_DIR}) -if (WIN32) - set(Libevent_LIB_PREFIX "lib") -endif () +# Parse version +if(LIBEVENT_EVENT_CONFIG_DIR) + set(_version_regex "^#define[ \t]+_EVENT_VERSION[ \t]+\"([^\"]+)\".*") + if(EXISTS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h") + # Libevent 2.0 + file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h" + LIBEVENT_VERSION REGEX "${_version_regex}") + if(NOT LIBEVENT_VERSION) + # Libevent 2.1 + set(_version_regex "^#define[ \t]+EVENT__VERSION[ \t]+\"([^\"]+)\".*") + file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h" + LIBEVENT_VERSION REGEX "${_version_regex}") + endif() + else() + # Libevent 1.4 + if(EXISTS "${LIBEVENT_EVENT_CONFIG_DIR}/event-config.h") + file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event-config.h" + LIBEVENT_VERSION REGEX "${_version_regex}") + endif() + endif() + string(REGEX REPLACE "${_version_regex}" "\\1" LIBEVENT_VERSION + "${LIBEVENT_VERSION}") + unset(_version_regex) +endif() -if (LIBEVENT_INCLUDE_DIR) - set(_version_regex "^#define[ \t]+_EVENT_VERSION[ \t]+\"([^\"]+)\".*") - if (EXISTS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h") - # Libevent 2.0 - file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h" - LIBEVENT_VERSION REGEX "${_version_regex}") - if (NOT LIBEVENT_VERSION) - # Libevent 2.1 - set(_version_regex "^#define[ \t]+EVENT__VERSION[ \t]+\"([^\"]+)\".*") - file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h" - LIBEVENT_VERSION REGEX "${_version_regex}") - endif () - else () - # Libevent 1.4 - if (EXISTS "${LIBEVENT_EVENT_CONFIG_DIR}/event-config.h") - file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event-config.h" - LIBEVENT_VERSION REGEX "${_version_regex}") - endif () - endif () - string(REGEX REPLACE "${_version_regex}" "\\1" - LIBEVENT_VERSION "${LIBEVENT_VERSION}") - unset(_version_regex) -endif () +# Prefix initialization +if(WIN32) + set(Libevent_LIB_PREFIX "lib") +else() + set(Libevent_LIB_PREFIX "") +endif() + +if(WIN32) + set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extra) +else() + set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extra pthreads) +endif() -set(_LIBEVENT_REQUIRED_VARS) -if (WIN32) - set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extra) -else () - set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extra pthreads) -endif () message(STATUS "** libevent components: ${Libevent_FIND_COMPONENTS}") -foreach (COMPONENT ${Libevent_FIND_COMPONENTS}) - set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event") - # Note: compare two variables to avoid a CMP0054 policy warning - if (COMPONENT STREQUAL _LIBEVENT_LIBNAME) - set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event") - else () - set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event_${COMPONENT}") - endif () - string(TOUPPER "${COMPONENT}" COMPONENT_UPPER) - message(STATUS "** fine ${_LIBEVENT_LIBNAME} in ${LIBEVENT_LIBRARIES_SEARCH_PATH}") - find_library(LIBEVENT_${COMPONENT_UPPER}_LIBRARY - NAMES ${_LIBEVENT_LIBNAME} - PATHS ${LIBEVENT_LIBRARIES_SEARCH_PATH} - HINTS ${PC_LIBEVENT_LIBRARY_DIRS} - ) - if (LIBEVENT_${COMPONENT_UPPER}_LIBRARY) - set(Libevent_${COMPONENT}_FOUND 1) - endif () - list(APPEND _LIBEVENT_REQUIRED_VARS LIBEVENT_${COMPONENT_UPPER}_LIBRARY) -endforeach () +foreach(COMPONENT ${Libevent_FIND_COMPONENTS}) + set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event") + # Note: compare two variables to avoid a CMP0054 policy warning + if(NOT (COMPONENT STREQUAL _LIBEVENT_LIBNAME)) + set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event_${COMPONENT}") + endif() + string(TOUPPER "${COMPONENT}" COMPONENT_UPPER) + message( + STATUS "** find ${_LIBEVENT_LIBNAME} in ${LIBEVENT_LIBRARIES_SEARCH_PATH}") + find_library( + LIBEVENT_${COMPONENT_UPPER}_LIBRARY + NAMES ${_LIBEVENT_LIBNAME} + PATHS ${LIBEVENT_LIBRARIES_SEARCH_PATH} + NO_DEFAULT_PATH) + if(LIBEVENT_${COMPONENT_UPPER}_LIBRARY) + set(LIBEVENT_${COMPONENT_UPPER}_FOUND ON) + else() + set(LIBEVENT_${COMPONENT_UPPER}_FOUND OFF) + endif() + list(APPEND _LIBEVENT_REQUIRED_VARS LIBEVENT_${COMPONENT_UPPER}_LIBRARY) +endforeach() unset(_LIBEVENT_LIBNAME) include(FindPackageHandleStandardArgs) -# handle the QUIETLY and REQUIRED arguments and set LIBEVENT_FOUND to TRUE -# if all listed variables are TRUE and the requested version matches. -find_package_handle_standard_args(Libevent - REQUIRED_VARS ${_LIBEVENT_REQUIRED_VARS} LIBEVENT_INCLUDE_DIR - VERSION_VAR LIBEVENT_VERSION - HANDLE_COMPONENTS) +find_package_handle_standard_args( + Libevent + REQUIRED_VARS ${_LIBEVENT_REQUIRED_VARS} + VERSION_VAR LIBEVENT_VERSION + HANDLE_COMPONENTS) +unset(_LIBEVENT_REQUIRED_VARS) -if (LIBEVENT_FOUND) - set(LIBEVENT_INCLUDE_DIRS ${LIBEVENT_INCLUDE_DIR}) - set(LIBEVENT_LIBRARIES) - foreach (COMPONENT ${Libevent_FIND_COMPONENTS}) - string(TOUPPER "${COMPONENT}" COMPONENT_UPPER) - list(APPEND LIBEVENT_LIBRARIES ${LIBEVENT_${COMPONENT_UPPER}_LIBRARY}) - set(LIBEVENT_${COMPONENT_UPPER}_FOUND ${Libevent_${COMPONENT}_FOUND}) - endforeach () -endif () +if(LIBEVENT_FOUND) + set(LIBEVENT_INCLUDE_DIRS ${LIBEVENT_EVENT_CONFIG_DIR}) + set(LIBEVENT_LIBRARIES) + foreach(COMPONENT ${Libevent_FIND_COMPONENTS}) + string(TOUPPER "${COMPONENT}" COMPONENT_UPPER) + if(LIBEVENT_${COMPONENT_UPPER}_FOUND) + list(APPEND LIBEVENT_LIBRARIES ${LIBEVENT_${COMPONENT_UPPER}_LIBRARY}) + endif() + endforeach() +endif() +unset(LIBEVENT_EVENT_CONFIG_DIR) -mark_as_advanced(LIBEVENT_INCLUDE_DIR ${_LIBEVENT_REQUIRED_VARS}) +mark_as_advanced(LIBEVENT_INCLUDE_DIRS LIBEVENT_LIBRARIES) # Restore the original find library ordering -if (Libevent_USE_STATIC_LIBS) - set(CMAKE_FIND_LIBRARY_SUFFIXES ${_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) -endif () -unset(_LIBEVENT_REQUIRED_VARS) +if(Libevent_USE_STATIC_LIBS) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) +endif() diff --git a/project/CMakeLists.txt b/project/CMakeLists.txt index c65d319c2..c79ee4730 100755 --- a/project/CMakeLists.txt +++ b/project/CMakeLists.txt @@ -25,66 +25,71 @@ list(REMOVE_ITEM SRC_FILES ${PROJECT_SOURCE_DIR}/../src/dllmain.cpp) # subdirs set(SUB_DIRS) file(GLOB children ${PROJECT_SOURCE_DIR}/../src/*) -foreach (child ${children}) - if (IS_DIRECTORY ${child}) - list(APPEND SUB_DIRS ${child}) - endif () -endforeach () +foreach(child ${children}) + if(IS_DIRECTORY ${child}) + list(APPEND SUB_DIRS ${child}) + endif() +endforeach() list(APPEND SUB_DIRS ${PROJECT_SOURCE_DIR}/../src) # libs_directories file(GLOB LIB_DIRS ${PROJECT_SOURCE_DIR}/../libs/*) -foreach (dir ${LIB_DIRS}) - if (IS_DIRECTORY ${dir}) - set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH};${dir}) - include_directories(${dir}/include) - endif () -endforeach () +foreach(dir ${LIB_DIRS}) + if(IS_DIRECTORY ${dir}) + set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH};${dir}) + include_directories(${dir}/include) + endif() +endforeach() # static -if (BUILD_ROCKETMQ_STATIC) - add_library(rocketmq_static STATIC - ${SRC_FILES}) - target_include_directories(rocketmq_static - PUBLIC ${CMAKE_SOURCE_DIR}/include ${SUB_DIRS} ${JSONCPP_INCLUDE_DIRS} ${LIBEVENT_INCLUDE_DIRS}) - if (spdlog_FOUND) - target_link_libraries(rocketmq_static - PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} ${LIBEVENT_LIBRARIES} spdlog::spdlog) - else (spdlog_FOUND) - target_link_libraries(rocketmq_static - PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} ${LIBEVENT_LIBRARIES}) - endif (spdlog_FOUND) - # set_target_properties(rocketmq_static - # PROPERTIES OUTPUT_NAME "rocketmq") +if(BUILD_ROCKETMQ_STATIC) + add_library(rocketmq_static STATIC ${SRC_FILES}) + target_include_directories( + rocketmq_static PUBLIC ${CMAKE_SOURCE_DIR}/include ${SUB_DIRS} + ${JSONCPP_INCLUDE_DIRS} ${LIBEVENT_INCLUDE_DIRS}) + if(spdlog_FOUND) + target_link_libraries( + rocketmq_static PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} + ${LIBEVENT_LIBRARIES} spdlog::spdlog) + else(spdlog_FOUND) + target_link_libraries( + rocketmq_static PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} + ${LIBEVENT_LIBRARIES}) + endif(spdlog_FOUND) + # set_target_properties(rocketmq_static PROPERTIES OUTPUT_NAME "rocketmq") - include(BundleStaticLibrary) - bundle_static_library(rocketmq_static rocketmq) -endif () + include(BundleStaticLibrary) + bundle_static_library(rocketmq_static rocketmq) +endif() # shared -if (BUILD_ROCKETMQ_SHARED) - add_library(rocketmq_shared SHARED - ${SRC_FILES}) - target_include_directories(rocketmq_shared - PUBLIC ${CMAKE_SOURCE_DIR}/include ${SUB_DIRS} ${JSONCPP_INCLUDE_DIRS} ${LIBEVENT_INCLUDE_DIRS}) - if (spdlog_FOUND) - target_link_libraries(rocketmq_shared - PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} ${LIBEVENT_LIBRARIES} spdlog::spdlog) - else (spdlog_FOUND) - target_link_libraries(rocketmq_shared - PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} ${LIBEVENT_LIBRARIES}) - endif (spdlog_FOUND) - set_target_properties(rocketmq_shared - PROPERTIES OUTPUT_NAME "rocketmq") -endif () +if(BUILD_ROCKETMQ_SHARED) + add_library(rocketmq_shared SHARED ${SRC_FILES}) + target_include_directories( + rocketmq_shared PUBLIC ${CMAKE_SOURCE_DIR}/include ${SUB_DIRS} + ${JSONCPP_INCLUDE_DIRS} ${LIBEVENT_INCLUDE_DIRS}) + if(spdlog_FOUND) + target_link_libraries( + rocketmq_shared PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} + ${LIBEVENT_LIBRARIES} spdlog::spdlog) + else(spdlog_FOUND) + target_link_libraries( + rocketmq_shared PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} + ${LIBEVENT_LIBRARIES}) + endif(spdlog_FOUND) + set_target_properties(rocketmq_shared PROPERTIES OUTPUT_NAME "rocketmq") +endif() # install -if (BUILD_ROCKETMQ_STATIC) - install(TARGETS rocketmq_static DESTINATION lib) - install(FILES ${LIBRARY_OUTPUT_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}rocketmq${CMAKE_STATIC_LIBRARY_SUFFIX} DESTINATION lib) -endif () -if (BUILD_ROCKETMQ_SHARED) - install(TARGETS rocketmq_shared DESTINATION lib) -endif () +if(BUILD_ROCKETMQ_STATIC) + install(TARGETS rocketmq_static DESTINATION lib) + install( + FILES + ${LIBRARY_OUTPUT_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}rocketmq${CMAKE_STATIC_LIBRARY_SUFFIX} + DESTINATION lib) +endif() +if(BUILD_ROCKETMQ_SHARED) + install(TARGETS rocketmq_shared DESTINATION lib) +endif() install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include/rocketmq) install(DIRECTORY ${CMAKE_SOURCE_DIR}/doc/ DESTINATION doc) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d6e56ebab..203a2688d 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -19,73 +19,77 @@ set(CMAKE_BUILD_TYPE "Debug") set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) -set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${CMAKE_SOURCE_DIR}/bin/lib64/cmake;${CMAKE_SOURCE_DIR}/bin/lib/cmake") +set(CMAKE_PREFIX_PATH + "${CMAKE_PREFIX_PATH};${CMAKE_SOURCE_DIR}/bin/lib64/cmake;${CMAKE_SOURCE_DIR}/bin/lib/cmake" +) -# Find dependencies -#find_package(GTest REQUIRED CONFIG) -if (NOT GTest_FOUND) - include_directories("${CMAKE_SOURCE_DIR}/bin/include") +# Find dependencies find_package(GTest REQUIRED CONFIG) +if(NOT GTest_FOUND) + include_directories("${CMAKE_SOURCE_DIR}/bin/include") - if (EXISTS "${CMAKE_SOURCE_DIR}/bin/lib64/libgtest.a") - set(Gtest_LIBRARY_DIR "${CMAKE_SOURCE_DIR}/bin/lib64") - else () - set(Gtest_LIBRARY_DIR "${CMAKE_SOURCE_DIR}/bin/lib") - endif () - link_libraries("${Gtest_LIBRARY_DIR}/libgtest.a" "${Gtest_LIBRARY_DIR}/libgtest_main.a" - "${Gtest_LIBRARY_DIR}/libgmock.a" "${Gtest_LIBRARY_DIR}/libgmock_main.a") -endif () + if(EXISTS "${CMAKE_SOURCE_DIR}/bin/lib64/libgtest.a") + set(Gtest_LIBRARY_DIR "${CMAKE_SOURCE_DIR}/bin/lib64") + else() + set(Gtest_LIBRARY_DIR "${CMAKE_SOURCE_DIR}/bin/lib") + endif() + link_libraries( + "${Gtest_LIBRARY_DIR}/libgtest.a" "${Gtest_LIBRARY_DIR}/libgtest_main.a" + "${Gtest_LIBRARY_DIR}/libgmock.a" "${Gtest_LIBRARY_DIR}/libgmock_main.a") +endif() -if (NOT (CMAKE_VERSION VERSION_LESS "3.9")) - cmake_policy(SET CMP0054 NEW) - cmake_policy(SET CMP0057 NEW) - include(GoogleTest) -endif () +if(NOT (CMAKE_VERSION VERSION_LESS "3.9")) + cmake_policy(SET CMP0054 NEW) + cmake_policy(SET CMP0057 NEW) + include(GoogleTest) +endif() function(config_test file) - get_filename_component(basename ${file} NAME_WE) + get_filename_component(basename ${file} NAME_WE) - add_executable(${basename} ${file}) + add_executable(${basename} ${file}) - if(MSVC) - if(CMAKE_CONFIGURATION_TYPES STREQUAL "Release") - set_target_properties(${basename} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT") - else() - set_target_properties(${basename} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMTD") - endif() + if(MSVC) + if(CMAKE_CONFIGURATION_TYPES STREQUAL "Release") + set_target_properties(${basename} PROPERTIES LINK_FLAGS + "/NODEFAULTLIB:LIBCMT") + else() + set_target_properties(${basename} PROPERTIES LINK_FLAGS + "/NODEFAULTLIB:LIBCMTD") endif() + endif() - if (GTest_FOUND) - if (BUILD_ROCKETMQ_SHARED) - target_link_libraries(${basename} rocketmq_shared - GTest::gtest GTest::gtest_main GTest::gmock GTest::gmock_main) - else (BUILD_ROCKETMQ_SHARED) - target_link_libraries(${basename} rocketmq_static - GTest::gtest GTest::gtest_main GTest::gmock GTest::gmock_main) - endif (BUILD_ROCKETMQ_SHARED) - else () - if (BUILD_ROCKETMQ_SHARED) - target_link_libraries(${basename} rocketmq_shared) - else (BUILD_ROCKETMQ_SHARED) - target_link_libraries(${basename} rocketmq_static) - endif (BUILD_ROCKETMQ_SHARED) - endif () + if(GTest_FOUND) + if(BUILD_ROCKETMQ_SHARED) + target_link_libraries(${basename} rocketmq_shared GTest::gtest + GTest::gtest_main GTest::gmock GTest::gmock_main) + else(BUILD_ROCKETMQ_SHARED) + target_link_libraries(${basename} rocketmq_static GTest::gtest + GTest::gtest_main GTest::gmock GTest::gmock_main) + endif(BUILD_ROCKETMQ_SHARED) + else() + if(BUILD_ROCKETMQ_SHARED) + target_link_libraries(${basename} rocketmq_shared) + else(BUILD_ROCKETMQ_SHARED) + target_link_libraries(${basename} rocketmq_static) + endif(BUILD_ROCKETMQ_SHARED) + endif() - if (NOT (CMAKE_VERSION VERSION_LESS "3.10")) - gtest_discover_tests(${basename}) - elseif (NOT (CMAKE_VERSION VERSION_LESS "3.9")) - gtest_add_tests(TARGET ${basename}) - endif () + if(NOT (CMAKE_VERSION VERSION_LESS "3.10")) + gtest_discover_tests(${basename}) + elseif(NOT (CMAKE_VERSION VERSION_LESS "3.9")) + gtest_add_tests(TARGET ${basename}) + endif() endfunction() function(config_all_test dir) - file(GLOB files "${dir}/*") - foreach (file ${files}) - if (IS_DIRECTORY ${file}) - config_all_test(${file}) - elseif (${file} MATCHES "^.+\\.(c|cpp)$") - config_test(${file}) - endif () - endforeach () + file(GLOB files "${dir}/*") + foreach(file ${files}) + if(IS_DIRECTORY ${file}) + config_all_test(${file}) + elseif(${file} MATCHES "^.+\\.(c|cpp)$") + config_test(${file}) + endif() + endforeach() endfunction() config_all_test(${PROJECT_SOURCE_DIR}/src) From 6d60f068ecf92a8cbb4da571907fa851c006e2c7 Mon Sep 17 00:00:00 2001 From: James Yin Date: Fri, 26 Mar 2021 16:56:48 +0800 Subject: [PATCH 51/62] feat: expose logger config api --- include/LoggerConfig.h | 73 ++++++++++++++++++++++++++++++++++++++++++ src/log/Logging.cpp | 21 +++++------- src/log/Logging.h | 47 ++------------------------- 3 files changed, 83 insertions(+), 58 deletions(-) create mode 100644 include/LoggerConfig.h diff --git a/include/LoggerConfig.h b/include/LoggerConfig.h new file mode 100644 index 000000000..6050dffca --- /dev/null +++ b/include/LoggerConfig.h @@ -0,0 +1,73 @@ +/* + * 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_LOGGERCONFIG_H_ +#define ROCKETMQ_LOGGERCONFIG_H_ + +#include + +namespace rocketmq { + +enum LogLevel { + LOG_LEVEL_FATAL = 1, + LOG_LEVEL_ERROR = 2, + LOG_LEVEL_WARN = 3, + LOG_LEVEL_INFO = 4, + LOG_LEVEL_DEBUG = 5, + LOG_LEVEL_TRACE = 6, + LOG_LEVEL_LEVEL_NUM = 7 +}; + +class LoggerConfig { + public: + LoggerConfig(const std::string& name, const std::string& path) + : LoggerConfig(name, LOG_LEVEL_INFO, path, 1024 * 1024 * 100, 3) {} + LoggerConfig(const std::string& name, LogLevel level, const std::string& path, int file_size, int file_count) + : name_(name), level_(level), path_(path), file_size_(file_size), file_count_(file_count) {} + + public: + inline const std::string& name() const { return name_; } + inline void set_name(const std::string& name) { name_ = name; } + + inline LogLevel level() const { return level_; } + inline void set_level(LogLevel level) { level_ = level; } + + inline const std::string& path() const { return path_; } + inline void set_path(const std::string& path) { path_ = path; } + + inline int file_size() const { return file_size_; } + inline void set_file_size(int file_size) { file_size_ = file_size; } + + inline int file_count() const { return file_count_; } + inline void set_file_count(int file_count) { file_count_ = file_count; } + + inline bool config_spdlog() const { return config_spdlog_; } + inline void set_config_spdlog(bool config_spdlog) { config_spdlog_ = config_spdlog; } + + private: + std::string name_; + LogLevel level_; + std::string path_; + int file_size_; + int file_count_; + bool config_spdlog_{true}; +}; + +LoggerConfig& GetDefaultLoggerConfig(); + +} // namespace rocketmq + +#endif // ROCKETMQ_LOGGERCONFIG_H_ diff --git a/src/log/Logging.cpp b/src/log/Logging.cpp index 6eb958ebd..6370096ae 100644 --- a/src/log/Logging.cpp +++ b/src/log/Logging.cpp @@ -81,20 +81,15 @@ LoggerConfig& GetDefaultLoggerConfig() { return default_logger_config; } -static std::once_flag default_logger_init_flag; -static std::unique_ptr default_logger; - Logger& GetDefaultLogger() { - if (default_logger == nullptr) { - std::call_once(default_logger_init_flag, [] { - auto& default_logger_config = GetDefaultLoggerConfig(); - if (default_logger_config.config_spdlog()) { - ConfigSpdlog(); - } - default_logger.reset(new Logger(default_logger_config)); - }); - } - return *default_logger; + static Logger default_logger = []() { + auto& default_logger_config = GetDefaultLoggerConfig(); + if (default_logger_config.config_spdlog()) { + ConfigSpdlog(); + } + return Logger(default_logger_config); + }(); + return default_logger; } Logger::Logger(const LoggerConfig& config) { diff --git a/src/log/Logging.h b/src/log/Logging.h index 24bbd95d8..0678c9ee5 100644 --- a/src/log/Logging.h +++ b/src/log/Logging.h @@ -31,52 +31,9 @@ #endif // clang-format on -namespace rocketmq { - -enum LogLevel { - LOG_LEVEL_FATAL = 1, - LOG_LEVEL_ERROR = 2, - LOG_LEVEL_WARN = 3, - LOG_LEVEL_INFO = 4, - LOG_LEVEL_DEBUG = 5, - LOG_LEVEL_TRACE = 6, - LOG_LEVEL_LEVEL_NUM = 7 -}; - -class LoggerConfig { - public: - LoggerConfig(const std::string& name, const std::string& path) - : LoggerConfig(name, LOG_LEVEL_INFO, path, 1024 * 1024 * 100, 3) {} - LoggerConfig(const std::string& name, LogLevel level, const std::string& path, int file_size, int file_count) - : name_(name), level_(level), path_(path), file_size_(file_size), file_count_(file_count) {} - - public: - inline const std::string& name() const { return name_; } - inline void set_name(const std::string& name) { name_ = name; } - - inline LogLevel level() const { return level_; } - inline void set_level(LogLevel level) { level_ = level; } +#include "LoggerConfig.h" - inline const std::string& path() const { return path_; } - inline void set_path(const std::string& path) { path_ = path; } - - inline int file_size() const { return file_size_; } - inline void set_file_size(int file_size) { file_size_ = file_size; } - - inline int file_count() const { return file_count_; } - inline void set_file_count(int file_count) { file_count_ = file_count; } - - inline bool config_spdlog() const { return config_spdlog_; } - inline void set_config_spdlog(bool config_spdlog) { config_spdlog_ = config_spdlog; } - - private: - std::string name_; - LogLevel level_; - std::string path_; - int file_size_; - int file_count_; - bool config_spdlog_{true}; -}; +namespace rocketmq { class Logger { public: From 06470c70b529a8f893311e72edb0d945b88147d8 Mon Sep 17 00:00:00 2001 From: James Yin Date: Fri, 26 Mar 2021 18:29:30 +0800 Subject: [PATCH 52/62] fix: auto delete callback --- include/PullCallback.h | 23 +++++------------------ include/RequestCallback.h | 23 +++++------------------ include/SendCallback.h | 23 +++++------------------ src/common/PullCallbackWrap.cpp | 24 ++++++++++++++++++++++++ src/common/SendCallbackWrap.cpp | 24 ++++++++++++++++++++++++ src/producer/RequestResponseFuture.cpp | 24 ++++++++++++++++++++++++ 6 files changed, 87 insertions(+), 54 deletions(-) diff --git a/include/PullCallback.h b/include/PullCallback.h index 08deacab9..841b5983a 100755 --- a/include/PullCallback.h +++ b/include/PullCallback.h @@ -22,7 +22,7 @@ namespace rocketmq { -enum PullCallbackType { PULL_CALLBACK_TYPE_SIMPLE = 0, PULL_CALLBACK_TYPE_AUTO_DELETE = 1 }; +enum class PullCallbackType { kSimple, kAutoDelete }; /** * PullCallback - callback interface for async pull @@ -34,24 +34,11 @@ class ROCKETMQCLIENT_API PullCallback { virtual void onSuccess(std::unique_ptr pull_result) = 0; virtual void onException(MQException& e) noexcept = 0; - virtual PullCallbackType getPullCallbackType() const { return PULL_CALLBACK_TYPE_SIMPLE; } + virtual PullCallbackType getPullCallbackType() const { return PullCallbackType::kSimple; } public: - inline void invokeOnSuccess(std::unique_ptr pull_result) { - auto type = getPullCallbackType(); - onSuccess(std::move(pull_result)); - if (type == PULL_CALLBACK_TYPE_AUTO_DELETE && getPullCallbackType() == PULL_CALLBACK_TYPE_AUTO_DELETE) { - delete this; - } - } - - inline void invokeOnException(MQException& exception) noexcept { - auto type = getPullCallbackType(); - onException(exception); - if (type == PULL_CALLBACK_TYPE_AUTO_DELETE && getPullCallbackType() == PULL_CALLBACK_TYPE_AUTO_DELETE) { - delete this; - } - } + void invokeOnSuccess(std::unique_ptr pull_result) noexcept; + void invokeOnException(MQException& exception) noexcept; }; /** @@ -61,7 +48,7 @@ class ROCKETMQCLIENT_API PullCallback { */ class ROCKETMQCLIENT_API AutoDeletePullCallback : public PullCallback { public: - PullCallbackType getPullCallbackType() const override final { return PULL_CALLBACK_TYPE_AUTO_DELETE; } + PullCallbackType getPullCallbackType() const override final { return PullCallbackType::kAutoDelete; } }; } // namespace rocketmq diff --git a/include/RequestCallback.h b/include/RequestCallback.h index c666ccc1a..493e6819d 100644 --- a/include/RequestCallback.h +++ b/include/RequestCallback.h @@ -22,7 +22,7 @@ namespace rocketmq { -enum RequestCallbackType { REQUEST_CALLBACK_TYPE_SIMPLE = 0, REQUEST_CALLBACK_TYPE_AUTO_DELETE = 1 }; +enum class RequestCallbackType { kSimple, kAutoDelete }; /** * RequestCallback - callback interface for async request @@ -34,24 +34,11 @@ class ROCKETMQCLIENT_API RequestCallback { virtual void onSuccess(MQMessage message) = 0; virtual void onException(MQException& e) noexcept = 0; - virtual RequestCallbackType getRequestCallbackType() const { return REQUEST_CALLBACK_TYPE_SIMPLE; } + virtual RequestCallbackType getRequestCallbackType() const { return RequestCallbackType::kSimple; } public: - inline void invokeOnSuccess(MQMessage message) { - auto type = getRequestCallbackType(); - onSuccess(std::move(message)); - if (type == REQUEST_CALLBACK_TYPE_AUTO_DELETE && getRequestCallbackType() == REQUEST_CALLBACK_TYPE_AUTO_DELETE) { - delete this; - } - } - - inline void invokeOnException(MQException& exception) noexcept { - auto type = getRequestCallbackType(); - onException(exception); - if (type == REQUEST_CALLBACK_TYPE_AUTO_DELETE && getRequestCallbackType() == REQUEST_CALLBACK_TYPE_AUTO_DELETE) { - delete this; - } - } + void invokeOnSuccess(MQMessage message) noexcept; + void invokeOnException(MQException& exception) noexcept; }; /** @@ -61,7 +48,7 @@ class ROCKETMQCLIENT_API RequestCallback { */ class ROCKETMQCLIENT_API AutoDeleteRequestCallback : public RequestCallback { public: - RequestCallbackType getRequestCallbackType() const override final { return REQUEST_CALLBACK_TYPE_AUTO_DELETE; } + RequestCallbackType getRequestCallbackType() const override final { return RequestCallbackType::kAutoDelete; } }; } // namespace rocketmq diff --git a/include/SendCallback.h b/include/SendCallback.h index 9191c2572..a301d949e 100755 --- a/include/SendCallback.h +++ b/include/SendCallback.h @@ -22,7 +22,7 @@ namespace rocketmq { -enum SendCallbackType { SEND_CALLBACK_TYPE_SIMPLE = 0, SEND_CALLBACK_TYPE_AUTO_DELETE = 1 }; +enum class SendCallbackType { kSimple, kAutoDelete }; /** * SendCallback - callback interface for async send @@ -34,24 +34,11 @@ class ROCKETMQCLIENT_API SendCallback { virtual void onSuccess(SendResult& sendResult) = 0; virtual void onException(MQException& e) noexcept = 0; - virtual SendCallbackType getSendCallbackType() const { return SEND_CALLBACK_TYPE_SIMPLE; } + virtual SendCallbackType getSendCallbackType() const { return SendCallbackType::kSimple; } public: - inline void invokeOnSuccess(SendResult& send_result) { - auto type = getSendCallbackType(); - onSuccess(send_result); - if (type == SEND_CALLBACK_TYPE_AUTO_DELETE && getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { - delete this; - } - } - - inline void invokeOnException(MQException& exception) noexcept { - auto type = getSendCallbackType(); - onException(exception); - if (type == SEND_CALLBACK_TYPE_AUTO_DELETE && getSendCallbackType() == SEND_CALLBACK_TYPE_AUTO_DELETE) { - delete this; - } - } + void invokeOnSuccess(SendResult& send_result) noexcept; + void invokeOnException(MQException& exception) noexcept; }; /** @@ -62,7 +49,7 @@ class ROCKETMQCLIENT_API SendCallback { class ROCKETMQCLIENT_API AutoDeleteSendCallback : public SendCallback // base interface { public: - SendCallbackType getSendCallbackType() const override final { return SEND_CALLBACK_TYPE_AUTO_DELETE; } + SendCallbackType getSendCallbackType() const override final { return SendCallbackType::kAutoDelete; } }; } // namespace rocketmq diff --git a/src/common/PullCallbackWrap.cpp b/src/common/PullCallbackWrap.cpp index bc915a410..91283515a 100644 --- a/src/common/PullCallbackWrap.cpp +++ b/src/common/PullCallbackWrap.cpp @@ -18,6 +18,30 @@ namespace rocketmq { +void PullCallback::invokeOnSuccess(std::unique_ptr pull_result) noexcept { + auto type = getPullCallbackType(); + try { + onSuccess(std::move(pull_result)); + } catch (const std::exception& e) { + LOG_WARN_NEW("encounter exception when invoke PullCallback::onSuccess(), {}", e.what()); + } + if (type == PullCallbackType::kAutoDelete) { + delete this; + } +} + +void PullCallback::invokeOnException(MQException& exception) noexcept { + auto type = getPullCallbackType(); + try { + onException(exception); + } catch (const std::exception& e) { + LOG_WARN_NEW("encounter exception when invoke PullCallback::onException(), {}", e.what()); + } + if (type == PullCallbackType::kAutoDelete) { + delete this; + } +} + PullCallbackWrap::PullCallbackWrap(PullCallback* pullCallback, MQClientAPIImpl* pClientAPI) : pull_callback_(pullCallback), client_api_impl_(pClientAPI) {} diff --git a/src/common/SendCallbackWrap.cpp b/src/common/SendCallbackWrap.cpp index 562b30fe1..eab2fb56c 100644 --- a/src/common/SendCallbackWrap.cpp +++ b/src/common/SendCallbackWrap.cpp @@ -32,6 +32,30 @@ namespace rocketmq { +void SendCallback::invokeOnSuccess(SendResult& send_result) noexcept { + auto type = getSendCallbackType(); + try { + onSuccess(send_result); + } catch (const std::exception& e) { + LOG_WARN_NEW("encounter exception when invoke SendCallback::onSuccess(), {}", e.what()); + } + if (type == SendCallbackType::kAutoDelete) { + delete this; + } +} + +void SendCallback::invokeOnException(MQException& exception) noexcept { + auto type = getSendCallbackType(); + try { + onException(exception); + } catch (const std::exception& e) { + LOG_WARN_NEW("encounter exception when invoke SendCallback::onException(), {}", e.what()); + } + if (type == SendCallbackType::kAutoDelete) { + delete this; + } +} + SendCallbackWrap::SendCallbackWrap(const std::string& addr, const std::string& brokerName, const MessagePtr msg, diff --git a/src/producer/RequestResponseFuture.cpp b/src/producer/RequestResponseFuture.cpp index 615d27b33..bb65adc5a 100644 --- a/src/producer/RequestResponseFuture.cpp +++ b/src/producer/RequestResponseFuture.cpp @@ -21,6 +21,30 @@ namespace rocketmq { +void RequestCallback::invokeOnSuccess(MQMessage message) noexcept { + auto type = getRequestCallbackType(); + try { + onSuccess(std::move(message)); + } catch (const std::exception& e) { + LOG_WARN_NEW("encounter exception when invoke RequestCallback::onSuccess(), {}", e.what()); + } + if (type == RequestCallbackType::kAutoDelete) { + delete this; + } +} + +void RequestCallback::invokeOnException(MQException& exception) noexcept { + auto type = getRequestCallbackType(); + try { + onException(exception); + } catch (const std::exception& e) { + LOG_WARN_NEW("encounter exception when invoke RequestCallback::onException(), {}", e.what()); + } + if (type == RequestCallbackType::kAutoDelete) { + delete this; + } +} + RequestResponseFuture::RequestResponseFuture(const std::string& correlationId, long timeoutMillis, RequestCallback* requestCallback) From ec800c124d7f5231f22b432ef1240e2fd42178d1 Mon Sep 17 00:00:00 2001 From: James Yin Date: Sun, 28 Mar 2021 13:20:32 +0800 Subject: [PATCH 53/62] fix: missing cassert header --- src/ClientRemotingProcessor.cpp | 2 ++ src/MQClientAPIImpl.cpp | 1 + src/common/PullCallbackWrap.cpp | 2 ++ src/common/SendCallbackWrap.cpp | 2 ++ src/common/UtilAll.cpp | 2 ++ src/concurrent/latch.hpp | 3 ++- src/concurrent/time.hpp | 1 + src/producer/DefaultMQProducerImpl.cpp | 3 ++- src/transport/SocketUtil.h | 1 + 9 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/ClientRemotingProcessor.cpp b/src/ClientRemotingProcessor.cpp index 32366d60e..d4fc34cb7 100644 --- a/src/ClientRemotingProcessor.cpp +++ b/src/ClientRemotingProcessor.cpp @@ -16,6 +16,8 @@ */ #include "ClientRemotingProcessor.h" +#include + #include "MQProtos.h" #include "MessageAccessor.hpp" #include "MessageDecoder.h" diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index e5372d023..6bc5d3e82 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -18,6 +18,7 @@ #include #include + #include #include "ClientRemotingProcessor.h" diff --git a/src/common/PullCallbackWrap.cpp b/src/common/PullCallbackWrap.cpp index 91283515a..2fa051060 100644 --- a/src/common/PullCallbackWrap.cpp +++ b/src/common/PullCallbackWrap.cpp @@ -16,6 +16,8 @@ */ #include "PullCallbackWrap.h" +#include + namespace rocketmq { void PullCallback::invokeOnSuccess(std::unique_ptr pull_result) noexcept { diff --git a/src/common/SendCallbackWrap.cpp b/src/common/SendCallbackWrap.cpp index eab2fb56c..9d324f07c 100644 --- a/src/common/SendCallbackWrap.cpp +++ b/src/common/SendCallbackWrap.cpp @@ -16,6 +16,8 @@ */ #include "SendCallbackWrap.h" +#include + #include #include "DefaultMQProducer.h" diff --git a/src/common/UtilAll.cpp b/src/common/UtilAll.cpp index 731d8aa1a..bb13eaebe 100644 --- a/src/common/UtilAll.cpp +++ b/src/common/UtilAll.cpp @@ -16,6 +16,8 @@ */ #include "UtilAll.h" +#include + #include #include #include diff --git a/src/concurrent/latch.hpp b/src/concurrent/latch.hpp index b583f8ff1..656d47ec4 100644 --- a/src/concurrent/latch.hpp +++ b/src/concurrent/latch.hpp @@ -17,9 +17,10 @@ #ifndef ROCKETMQ_CONCURRENT_LATCH_HPP_ #define ROCKETMQ_CONCURRENT_LATCH_HPP_ -#include #include #include + +#include #include #include diff --git a/src/concurrent/time.hpp b/src/concurrent/time.hpp index fef4f4ecc..35855eaed 100644 --- a/src/concurrent/time.hpp +++ b/src/concurrent/time.hpp @@ -18,6 +18,7 @@ #define ROCKETMQ_CONCURRENT_TIME_HPP_ #include + #include namespace rocketmq { diff --git a/src/producer/DefaultMQProducerImpl.cpp b/src/producer/DefaultMQProducerImpl.cpp index ade43d1ac..0105bd6c0 100644 --- a/src/producer/DefaultMQProducerImpl.cpp +++ b/src/producer/DefaultMQProducerImpl.cpp @@ -17,8 +17,8 @@ #include "DefaultMQProducerImpl.h" #include + #include -#include "MQMessageQueue.h" #ifndef WIN32 #include @@ -33,6 +33,7 @@ #include "MQClientManager.h" #include "MQException.h" #include "MQFaultStrategy.h" +#include "MQMessageQueue.h" #include "MQProtos.h" #include "MessageBatch.h" #include "MessageClientIDSetter.h" diff --git a/src/transport/SocketUtil.h b/src/transport/SocketUtil.h index 6bfe5351d..b40e7dcd9 100644 --- a/src/transport/SocketUtil.h +++ b/src/transport/SocketUtil.h @@ -17,6 +17,7 @@ #ifndef ROCKETMQ_TRANSPORT_SOCKETUTIL_H_ #define ROCKETMQ_TRANSPORT_SOCKETUTIL_H_ +#include // assert #include // size_t #include // uint16_t From ad2478206a58bb996e98018d568446e1695bc873 Mon Sep 17 00:00:00 2001 From: James Yin Date: Sun, 28 Mar 2021 13:38:27 +0800 Subject: [PATCH 54/62] fix: missing limits header --- src/transport/SocketUtil.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/transport/SocketUtil.cpp b/src/transport/SocketUtil.cpp index f20726317..230db1a8e 100644 --- a/src/transport/SocketUtil.cpp +++ b/src/transport/SocketUtil.cpp @@ -20,6 +20,7 @@ #include // std::memcpy, std::memset #include +#include #include // std::invalid_argument, std::runtime_error #include From f622c31bfd7a97188cfd2b620b32e6ef6edaa88a Mon Sep 17 00:00:00 2001 From: James Yin Date: Sun, 28 Mar 2021 15:02:49 +0800 Subject: [PATCH 55/62] fix: MQClientAPIImpl::getMaxOffset --- src/MQClientAPIImpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index 6bc5d3e82..fe76f131c 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -358,7 +358,7 @@ int64_t MQClientAPIImpl::getMaxOffset(const std::string& addr, assert(response != nullptr); switch (response->code()) { case SUCCESS: { - auto* responseHeader = response->decodeCommandCustomHeader(GET_MAX_OFFSET); + auto* responseHeader = response->decodeCommandCustomHeader(); return responseHeader->offset; } default: From 8c783fda2979979382776a5edd46cae93eacf4cb Mon Sep 17 00:00:00 2001 From: James Yin Date: Sat, 27 Mar 2021 20:12:35 +0800 Subject: [PATCH 56/62] refactor: build scripts --- build.compatible.sh | 351 ++++++++++++++++++++++++++++++++++++++++++++ build.sh | 221 +++++++++++++--------------- 2 files changed, 450 insertions(+), 122 deletions(-) create mode 100755 build.compatible.sh diff --git a/build.compatible.sh b/build.compatible.sh new file mode 100755 index 000000000..451b2489a --- /dev/null +++ b/build.compatible.sh @@ -0,0 +1,351 @@ +#!/usr/bin/env bash + +# 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. + +set -e + +basepath=$( + cd $(dirname $0) + pwd +) +down_dir="${basepath}/tmp_down_dir" +build_dir="${basepath}/tmp_build_dir" +packet_dir="${basepath}/tmp_packet_dir" +install_lib_dir="${basepath}/bin" +fname_spdlog="spdlog*.zip" +fname_libevent="libevent*.zip" +fname_jsoncpp="jsoncpp*.zip" +fname_spdlog_down="v1.5.0.zip" +fname_libevent_down="release-2.1.11-stable.zip" +fname_jsoncpp_down="0.10.6.zip" + +PrintParams() { + echo "=========================================one key build help============================================" + echo "sh build.sh [no build spdlog:noLog] [no build libevent:noEvent] [no build json:noJson] [ execution test:test]" + echo "usage: sh build.sh noLog noJson noEvent test" + echo "=========================================one key build help============================================" + echo "" +} + +need_build_spdlog=1 +need_build_jsoncpp=1 +need_build_libevent=1 +test=0 +verbose=1 +codecov=0 +cpu_num=4 + +pasres_arguments() { + for var in "$@"; do + case "$var" in + noLog) + need_build_spdlog=0 + ;; + noJson) + need_build_jsoncpp=0 + ;; + noEvent) + need_build_libevent=0 + ;; + noVerbose) + verbose=0 + ;; + codecov) + codecov=1 + ;; + test) + test=1 + ;; + esac + done + +} +pasres_arguments $@ + +PrintParams() { + echo "###########################################################################" + + if [ $need_build_spdlog -eq 0 ]; then + echo "no need build spdlog lib" + else + echo "need build spdlog lib" + fi + + if [ $need_build_libevent -eq 0 ]; then + echo "no need build libevent lib" + else + echo "need build libevent lib" + fi + + if [ $need_build_jsoncpp -eq 0 ]; then + echo "no need build jsoncpp lib" + else + echo "need build jsoncpp lib" + fi + + if [ $test -eq 1 ]; then + echo "build unit tests" + else + echo "without build unit tests" + fi + + if [ $codecov -eq 1 ]; then + echo "run unit tests with code coverage" + fi + + if [ $verbose -eq 0 ]; then + echo "no need print detail logs" + else + echo "need print detail logs" + fi + + echo "###########################################################################" + echo "" +} + +Prepare() { + if [ -e ${down_dir} ]; then + echo "${down_dir} is exist" + else + mkdir -p ${down_dir} + fi + + cd ${basepath} + + if [ -e ${fname_spdlog} ]; then + mv -f ${basepath}/${fname_spdlog} ${down_dir} + fi + + if [ -e ${fname_libevent} ]; then + mv -f ${basepath}/${fname_libevent} ${down_dir} + fi + + if [ -e ${fname_jsoncpp} ]; then + mv -f ${basepath}/${fname_jsoncpp} ${down_dir} + fi + + if [ -e ${build_dir} ]; then + echo "${build_dir} is exist" + else + mkdir -p ${build_dir} + fi + + if [ -e ${packet_dir} ]; then + echo "${packet_dir} is exist" + else + mkdir -p ${packet_dir} + fi + + if [ -e ${install_lib_dir} ]; then + echo "${install_lib_dir} is exist" + else + mkdir -p ${install_lib_dir} + fi +} + +BuildSpdlog() { + if [ $need_build_spdlog -eq 0 ]; then + echo "no need build spdlog lib" + return 0 + fi + + if [ -d "${basepath}/bin/include/spdlog" ]; then + echo "spdlog already exist no need build test" + return 0 + fi + + cd ${down_dir} + if [ -e ${fname_spdlog} ]; then + echo "${fname_spdlog} is exist" + else + wget https://github.com/gabime/spdlog/archive/${fname_spdlog_down} -O spdlog-${fname_spdlog_down} + fi + unzip -o ${fname_spdlog} >unzipspdlog.txt 2>&1 + + spdlog_dir=$(ls -d spdlog* | grep -v zip) + cd ${spdlog_dir} + cp -r include ${install_lib_dir} + + echo "build spdlog success." +} + +BuildLibevent() { + if [ $need_build_libevent -eq 0 ]; then + echo "no need build libevent lib" + return 0 + fi + + if [ -d "${basepath}/bin/include/event2" ]; then + echo "spdlog already exist no need build test" + return 0 + fi + + cd ${down_dir} + if [ -e ${fname_libevent} ]; then + echo "${fname_libevent} is exist" + else + wget https://github.com/libevent/libevent/archive/${fname_libevent_down} -O libevent-${fname_libevent_down} + fi + unzip -o ${fname_libevent} >unziplibevent.txt 2>&1 + + libevent_dir=$(ls -d libevent* | grep -v zip) + cd ${libevent_dir} + ./autogen.sh + echo "build libevent static #####################" + if [ $verbose -eq 0 ]; then + ./configure --disable-openssl --enable-static=yes --enable-shared=no CFLAGS=-fPIC CPPFLAGS=-fPIC --prefix=${install_lib_dir} >libeventconfig.txt 2>&1 + else + ./configure --disable-openssl --enable-static=yes --enable-shared=no CFLAGS=-fPIC CPPFLAGS=-fPIC --prefix=${install_lib_dir} + fi + if [ $verbose -eq 0 ]; then + echo "build libevent without detail log." + make -j $cpu_num >libeventbuild.txt 2>&1 + else + make -j $cpu_num + fi + make install + echo "build libevent success." +} + +BuildJsonCPP() { + if [ $need_build_jsoncpp -eq 0 ]; then + echo "no need build jsoncpp lib" + return 0 + fi + + if [ -d "${basepath}/bin/include/jsoncpp" ]; then + echo "jsoncpp already exist no need build test" + return 0 + fi + + cd ${down_dir} + if [ -e ${fname_jsoncpp} ]; then + echo "${fname_jsoncpp} is exist" + else + wget https://github.com/open-source-parsers/jsoncpp/archive/${fname_jsoncpp_down} -O jsoncpp-${fname_jsoncpp_down} + fi + unzip -o ${fname_jsoncpp} >unzipjsoncpp.txt 2>&1 + jsoncpp_dir=$(ls -d jsoncpp* | grep -v zip) + cd ${jsoncpp_dir} + mkdir -p build + cd build + echo "build jsoncpp static ######################" + if [ $verbose -eq 0 ]; then + echo "build jsoncpp without detail log." + cmake .. -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${install_lib_dir} >jsoncppbuild.txt 2>&1 + else + cmake .. -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${install_lib_dir} + fi + if [ $verbose -eq 0 ]; then + make -j $cpu_num >jsoncppbuild.txt 2>&1 + else + make -j $cpu_num + fi + make install + echo "build jsoncpp success." + if [ ! -f ${install_lib_dir}/lib/libjsoncpp.a ]; then + echo " ./bin/lib directory is not libjsoncpp.a" + cp ${install_lib_dir}/lib/x86_64-linux-gnu/libjsoncpp.a ${install_lib_dir}/lib/ + fi +} + +BuildRocketMQClient() { + cd ${build_dir} + echo "============start to build rocketmq client cpp.=========" + if [ $test -eq 0 ]; then + cmake -DLibevent_USE_STATIC_LIBS=ON -DJSONCPP_USE_STATIC_LIBS=ON -DBUILD_ROCKETMQ_STATIC=ON -DBUILD_ROCKETMQ_SHARED=OFF .. + else + if [ $codecov -eq 1 ]; then + cmake .. -DLibevent_USE_STATIC_LIBS=ON -DJSONCPP_USE_STATIC_LIBS=ON -DBUILD_ROCKETMQ_STATIC=ON -DBUILD_ROCKETMQ_SHARED=OFF -DRUN_UNIT_TEST=ON -DCODE_COVERAGE=ON + else + cmake .. -DLibevent_USE_STATIC_LIBS=ON -DJSONCPP_USE_STATIC_LIBS=ON -DBUILD_ROCKETMQ_STATIC=ON -DBUILD_ROCKETMQ_SHARED=OFF -DRUN_UNIT_TEST=ON + fi + fi + if [ $verbose -eq 0 ]; then + echo "build rocketmq without detail log." + make -j $cpu_num >buildclient.txt 2>&1 + else + make -j $cpu_num + fi + #sudo make install +} + +BuildGoogleTest() { + if [ $test -eq 0 ]; then + echo "no need build google test lib" + return 0 + fi + + if [ -f ./bin/lib/libgtest.a ]; then + echo "libgtest already exist no need build test" + return 0 + fi + + cd ${down_dir} + if [ -e release-1.10.0.tar.gz ]; then + echo "${fname_boost} is exist" + else + wget https://github.com/abseil/googletest/archive/release-1.10.0.tar.gz + fi + if [ ! -d "googletest-release-1.10.0" ]; then + tar -zxvf release-1.10.0.tar.gz >googletest.txt 2>&1 + fi + cd googletest-release-1.10.0 + mkdir build + cd build + echo "build googletest static #####################" + if [ $verbose -eq 0 ]; then + echo "build googletest without detail log." + cmake .. -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${install_lib_dir} >googletestbuild.txt 2>&1 + else + cmake .. -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${install_lib_dir} + fi + if [ $verbose -eq 0 ]; then + make -j $cpu_num >gtestbuild.txt 2>&1 + else + make -j $cpu_num + fi + make install + + if [ ! -f ${install_lib_dir}/lib/libgtest.a ]; then + echo " ./bin/lib directory is not libgtest.a" + cp ${install_lib_dir}/lib64/lib* ${install_lib_dir}/lib + fi +} + +ExecutionTesting() { + if [ $test -eq 0 ]; then + echo "Build success without executing unit tests." + return 0 + fi + echo "############# unit test start ###########" + cd ${build_dir} + if [ $verbose -eq 0 ]; then + ctest + else + ctest -V + fi + echo "############# unit test finish ###########" +} + +PrintParams +Prepare +BuildSpdlog +BuildLibevent +BuildJsonCPP +BuildGoogleTest +BuildRocketMQClient +ExecutionTesting diff --git a/build.sh b/build.sh index ee1cbfa33..bd0a98724 100755 --- a/build.sh +++ b/build.sh @@ -18,19 +18,32 @@ set -e basepath=$( - cd $(dirname $0) + cd $(dirname "$0") pwd ) + +function version_lt() { + test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$2" +} + +cmake_version=$(cmake --version | head -n 1 | awk '{ print $3; }') +if version_lt "${cmake_version}" "3.15"; then + # shellcheck source=build.compatible.sh + "${basepath}/build.compatible.sh" + exit 0 +fi + down_dir="${basepath}/tmp_down_dir" build_dir="${basepath}/tmp_build_dir" -packet_dir="${basepath}/tmp_packet_dir" install_lib_dir="${basepath}/bin" fname_spdlog="spdlog*.zip" fname_libevent="libevent*.zip" fname_jsoncpp="jsoncpp*.zip" +fname_gtest="googletest*.tar.gz" fname_spdlog_down="v1.5.0.zip" fname_libevent_down="release-2.1.11-stable.zip" fname_jsoncpp_down="0.10.6.zip" +fname_gtest_down="release-1.10.0.tar.gz" PrintParams() { echo "=========================================one key build help============================================" @@ -73,7 +86,7 @@ pasres_arguments() { done } -pasres_arguments $@ +pasres_arguments "$@" PrintParams() { echo "###########################################################################" @@ -117,42 +130,40 @@ PrintParams() { } Prepare() { - if [ -e ${down_dir} ]; then + cd "${basepath}" + + if [ -e "${down_dir}" ]; then echo "${down_dir} is exist" else - mkdir -p ${down_dir} + mkdir -p "${down_dir}" fi - cd ${basepath} - if [ -e ${fname_spdlog} ]; then - mv -f ${basepath}/${fname_spdlog} ${down_dir} + mv -f ${basepath}/${fname_spdlog} "${down_dir}" fi if [ -e ${fname_libevent} ]; then - mv -f ${basepath}/${fname_libevent} ${down_dir} + mv -f ${basepath}/${fname_libevent} "${down_dir}" fi if [ -e ${fname_jsoncpp} ]; then - mv -f ${basepath}/${fname_jsoncpp} ${down_dir} + mv -f ${basepath}/${fname_jsoncpp} "${down_dir}" fi - if [ -e ${build_dir} ]; then - echo "${build_dir} is exist" - else - mkdir -p ${build_dir} + if [ -e ${fname_gtest} ]; then + mv -f ${basepath}/${fname_gtest} "${down_dir}" fi - if [ -e ${packet_dir} ]; then - echo "${packet_dir} is exist" + if [ -e "${build_dir}" ]; then + echo "${build_dir} is exist" else - mkdir -p ${packet_dir} + mkdir -p "${build_dir}" fi - if [ -e ${install_lib_dir} ]; then + if [ -e "${install_lib_dir}" ]; then echo "${install_lib_dir} is exist" else - mkdir -p ${install_lib_dir} + mkdir -p "${install_lib_dir}" fi } @@ -162,20 +173,21 @@ BuildSpdlog() { return 0 fi - cd ${down_dir} - if [ -e ${fname_spdlog} ]; then + if [ -d "${basepath}/bin/include/spdlog" ]; then + echo "spdlog already exist no need build test" + return 0 + fi + + if [ -e ${down_dir}/${fname_spdlog} ]; then echo "${fname_spdlog} is exist" else - wget https://github.com/gabime/spdlog/archive/${fname_spdlog_down} -O spdlog-${fname_spdlog_down} - fi - unzip -o ${fname_spdlog} >unzipspdlog.txt 2>&1 - if [ $? -ne 0 ]; then - exit 1 + wget "https://github.com/gabime/spdlog/archive/${fname_spdlog_down}" -O "${down_dir}/spdlog-${fname_spdlog_down}" fi + unzip -o ${down_dir}/${fname_spdlog} -d "${down_dir}" >"${down_dir}/unzipspdlog.txt" 2>&1 + + spdlog_dir=$(ls -d ${down_dir}/spdlog* | grep -v zip) - spdlog_dir=$(ls | grep spdlog | grep .*[^zip]$) - cd ${spdlog_dir} - cp -r include ${install_lib_dir} + cp -r "${spdlog_dir}/include" "${install_lib_dir}" echo "build spdlog success." } @@ -186,45 +198,37 @@ BuildLibevent() { return 0 fi - cd ${down_dir} - if [ -e ${fname_libevent} ]; then + if [ -d "${basepath}/bin/include/event2" ]; then + echo "spdlog already exist no need build test" + return 0 + fi + + if [ -e ${down_dir}/${fname_libevent} ]; then echo "${fname_libevent} is exist" else - wget https://github.com/libevent/libevent/archive/${fname_libevent_down} -O libevent-${fname_libevent_down} - fi - unzip -o ${fname_libevent} >unziplibevent.txt 2>&1 - if [ $? -ne 0 ]; then - exit 1 + wget "https://github.com/libevent/libevent/archive/${fname_libevent_down}" -O "${down_dir}/libevent-${fname_libevent_down}" fi + unzip -o ${down_dir}/${fname_libevent} -d "${down_dir}" >"${down_dir}/unziplibevent.txt" 2>&1 + + libevent_dir=$(ls -d ${down_dir}/libevent* | grep -v zip) - libevent_dir=$(ls | grep libevent | grep .*[^zip]$) - cd ${libevent_dir} - if [ $? -ne 0 ]; then - exit 1 - fi - ./autogen.sh - if [ $? -ne 0 ]; then - exit 1 - fi echo "build libevent static #####################" + pushd "${libevent_dir}" + ./autogen.sh if [ $verbose -eq 0 ]; then - ./configure --disable-openssl --enable-static=yes --enable-shared=no CFLAGS=-fPIC CPPFLAGS=-fPIC --prefix=${install_lib_dir} >libeventconfig.txt 2>&1 + ./configure --disable-openssl --enable-static=yes --enable-shared=no CFLAGS=-fPIC CPPFLAGS=-fPIC --prefix="${install_lib_dir}" >libeventconfig.txt 2>&1 else - ./configure --disable-openssl --enable-static=yes --enable-shared=no CFLAGS=-fPIC CPPFLAGS=-fPIC --prefix=${install_lib_dir} - fi - if [ $? -ne 0 ]; then - exit 1 + ./configure --disable-openssl --enable-static=yes --enable-shared=no CFLAGS=-fPIC CPPFLAGS=-fPIC --prefix="${install_lib_dir}" fi if [ $verbose -eq 0 ]; then echo "build libevent without detail log." - make -j $cpu_num >libeventbuild.txt 2>&1 + make -j $cpu_num >"${down_dir}/libeventbuild.txt" 2>&1 else make -j $cpu_num fi - if [ $? -ne 0 ]; then - exit 1 - fi make install + popd + echo "build libevent success." } @@ -234,73 +238,59 @@ BuildJsonCPP() { return 0 fi - cd ${down_dir} + if [ -d "${basepath}/bin/include/jsoncpp" ]; then + echo "jsoncpp already exist no need build test" + return 0 + fi - if [ -e ${fname_jsoncpp} ]; then + if [ -e ${down_dir}/${fname_jsoncpp} ]; then echo "${fname_jsoncpp} is exist" else - wget https://github.com/open-source-parsers/jsoncpp/archive/${fname_jsoncpp_down} -O jsoncpp-${fname_jsoncpp_down} - fi - unzip -o ${fname_jsoncpp} >unzipjsoncpp.txt 2>&1 - if [ $? -ne 0 ]; then - exit 1 - fi - jsoncpp_dir=$(ls | grep ^jsoncpp | grep .*[^zip]$) - cd ${jsoncpp_dir} - if [ $? -ne 0 ]; then - exit 1 + wget "https://github.com/open-source-parsers/jsoncpp/archive/${fname_jsoncpp_down}" -O "${down_dir}/jsoncpp-${fname_jsoncpp_down}" fi - mkdir build - cd build + unzip -o ${down_dir}/${fname_jsoncpp} -d "${down_dir}" >"${down_dir}/unzipjsoncpp.txt" 2>&1 + + jsoncpp_dir=$(ls -d ${down_dir}/jsoncpp* | grep -v zip) + echo "build jsoncpp static ######################" if [ $verbose -eq 0 ]; then echo "build jsoncpp without detail log." - cmake .. -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${install_lib_dir} >jsoncppbuild.txt 2>&1 + cmake -S "${jsoncpp_dir}" -B "${jsoncpp_dir}/build" -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX="${install_lib_dir}" >jsoncppbuild.txt 2>&1 else - cmake .. -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${install_lib_dir} - fi - if [ $? -ne 0 ]; then - exit 1 + cmake -S "${jsoncpp_dir}" -B "${jsoncpp_dir}/build" -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX="${install_lib_dir}" fi if [ $verbose -eq 0 ]; then - make -j $cpu_num >jsoncppbuild.txt 2>&1 + cmake --build "${jsoncpp_dir}/build" >"${down_dir}/jsoncppbuild.txt" 2>&1 else - make -j $cpu_num - fi - if [ $? -ne 0 ]; then - exit 1 + cmake --build "${jsoncpp_dir}/build" fi - make install - echo "build jsoncpp success." - if [ ! -f ${install_lib_dir}/lib/libjsoncpp.a ]; then + cmake --install "${jsoncpp_dir}/build" + if [ ! -f "${install_lib_dir}/lib/libjsoncpp.a" ]; then echo " ./bin/lib directory is not libjsoncpp.a" - cp ${install_lib_dir}/lib/x86_64-linux-gnu/libjsoncpp.a ${install_lib_dir}/lib/ + cp "${install_lib_dir}/lib/x86_64-linux-gnu/libjsoncpp.a" "${install_lib_dir}/lib/" fi + + echo "build jsoncpp success." } BuildRocketMQClient() { - cd ${build_dir} echo "============start to build rocketmq client cpp.=========" if [ $test -eq 0 ]; then - cmake -DLibevent_USE_STATIC_LIBS=ON -DJSONCPP_USE_STATIC_LIBS=ON -DBUILD_ROCKETMQ_STATIC=ON -DBUILD_ROCKETMQ_SHARED=OFF .. + cmake -S "${basepath}" -B "${build_dir}" -DLibevent_USE_STATIC_LIBS=ON -DJSONCPP_USE_STATIC_LIBS=ON -DBUILD_ROCKETMQ_STATIC=ON -DBUILD_ROCKETMQ_SHARED=OFF else if [ $codecov -eq 1 ]; then - cmake .. -DLibevent_USE_STATIC_LIBS=ON -DJSONCPP_USE_STATIC_LIBS=ON -DBUILD_ROCKETMQ_STATIC=ON -DBUILD_ROCKETMQ_SHARED=OFF -DRUN_UNIT_TEST=ON -DCODE_COVERAGE=ON + cmake -S "${basepath}" -B "${build_dir}" -DLibevent_USE_STATIC_LIBS=ON -DJSONCPP_USE_STATIC_LIBS=ON -DBUILD_ROCKETMQ_STATIC=ON -DBUILD_ROCKETMQ_SHARED=OFF -DRUN_UNIT_TEST=ON -DCODE_COVERAGE=ON else - cmake .. -DLibevent_USE_STATIC_LIBS=ON -DJSONCPP_USE_STATIC_LIBS=ON -DBUILD_ROCKETMQ_STATIC=ON -DBUILD_ROCKETMQ_SHARED=OFF -DRUN_UNIT_TEST=ON + cmake -S "${basepath}" -B "${build_dir}" -DLibevent_USE_STATIC_LIBS=ON -DJSONCPP_USE_STATIC_LIBS=ON -DBUILD_ROCKETMQ_STATIC=ON -DBUILD_ROCKETMQ_SHARED=OFF -DRUN_UNIT_TEST=ON fi fi if [ $verbose -eq 0 ]; then echo "build rocketmq without detail log." - make -j $cpu_num >buildclient.txt 2>&1 + cmake --build "${build_dir}" >"${build_dir}/buildclient.txt" 2>&1 else - make -j $cpu_num + cmake --build "${build_dir}" fi - if [ $? -ne 0 ]; then - echo "build error....." - exit 1 - fi - #sudo make install + #sudo cmake --install "${build_dir}" } BuildGoogleTest() { @@ -309,46 +299,37 @@ BuildGoogleTest() { return 0 fi - if [ -f ./bin/lib/libgtest.a ]; then + if [ -f "${install_lib_dir}/lib/libgtest.a" ]; then echo "libgtest already exist no need build test" return 0 fi - cd ${down_dir} - if [ -e release-1.10.0.tar.gz ]; then - echo "${fname_boost} is exist" + if [ -e ${down_dir}/${fname_gtest} ]; then + echo "${fname_gtest} is exist" else - wget https://github.com/abseil/googletest/archive/release-1.10.0.tar.gz - fi - if [ ! -d "googletest-release-1.10.0" ]; then - tar -zxvf release-1.10.0.tar.gz >googletest.txt 2>&1 + wget "https://github.com/abseil/googletest/archive/${fname_gtest_down}" -O "${down_dir}/googletest-${fname_gtest_down}" fi - cd googletest-release-1.10.0 - mkdir build - cd build + tar -zxvf ${down_dir}/${fname_gtest} -C "${down_dir}" >"${down_dir}/unzipgtest.txt" 2>&1 + + gtest_dir=$(ls -d ${down_dir}/googletest* | grep -v tar) + echo "build googletest static #####################" if [ $verbose -eq 0 ]; then echo "build googletest without detail log." - cmake .. -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${install_lib_dir} >googletestbuild.txt 2>&1 + cmake -S "${gtest_dir}" -B "${gtest_dir}/build" -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX="${install_lib_dir}" >"${down_dir}/googletestbuild.txt" 2>&1 else - cmake .. -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${install_lib_dir} - fi - if [ $? -ne 0 ]; then - exit 1 + cmake -S "${gtest_dir}" -B "${gtest_dir}/build" -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX="${install_lib_dir}" fi if [ $verbose -eq 0 ]; then - make -j $cpu_num >gtestbuild.txt 2>&1 + cmake --build "${gtest_dir}/build" >"${down_dir}/gtestbuild.txt" 2>&1 else - make -j $cpu_num + cmake --build "${gtest_dir}/build" fi - if [ $? -ne 0 ]; then - exit 1 - fi - make install + cmake --install "${gtest_dir}/build" - if [ ! -f ${install_lib_dir}/lib/libgtest.a ]; then + if [ ! -f "${install_lib_dir}/lib/libgtest.a" ]; then echo " ./bin/lib directory is not libgtest.a" - cp ${install_lib_dir}/lib64/lib* ${install_lib_dir}/lib + cp ${install_lib_dir}/lib64/lib* "${install_lib_dir}/lib" fi } @@ -358,16 +339,12 @@ ExecutionTesting() { return 0 fi echo "############# unit test start ###########" - cd ${build_dir} + cd "${build_dir}" if [ $verbose -eq 0 ]; then ctest else ctest -V fi - if [ $? -ne 0 ]; then - echo "############# unit test failed ###########" - exit 1 - fi echo "############# unit test finish ###########" } From f3a9097f612acf6db90c6f62e1a2fe87277e5e81 Mon Sep 17 00:00:00 2001 From: James Yin Date: Mon, 29 Mar 2021 13:49:17 +0800 Subject: [PATCH 57/62] fix: update topic subscribe info from cache first --- src/consumer/DefaultMQPushConsumerImpl.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/consumer/DefaultMQPushConsumerImpl.cpp b/src/consumer/DefaultMQPushConsumerImpl.cpp index bf00cc279..77ba01782 100644 --- a/src/consumer/DefaultMQPushConsumerImpl.cpp +++ b/src/consumer/DefaultMQPushConsumerImpl.cpp @@ -321,9 +321,16 @@ void DefaultMQPushConsumerImpl::updateTopicSubscribeInfoWhenSubscriptionChanged( auto& subTable = rebalance_impl_->getSubscriptionInner(); for (const auto& it : subTable) { const auto& topic = it.first; - bool ret = client_instance_->updateTopicRouteInfoFromNameServer(topic); - if (!ret) { - LOG_WARN_NEW("The topic:[{}] not exist", topic); + auto topic_route_data = client_instance_->getTopicRouteData(topic); + if (topic_route_data != nullptr) { + std::vector subscribeInfo = + MQClientInstance::topicRouteData2TopicSubscribeInfo(topic, topic_route_data); + updateTopicSubscribeInfo(topic, subscribeInfo); + } else { + bool ret = client_instance_->updateTopicRouteInfoFromNameServer(topic); + if (!ret) { + LOG_WARN_NEW("The topic[{}] not exist, or its route data not changed", topic); + } } } } From f3c827806fab17356966b69ed086be7af5dd67f8 Mon Sep 17 00:00:00 2001 From: James Yin Date: Tue, 6 Apr 2021 21:17:42 +0800 Subject: [PATCH 58/62] refactor: return std::unique_ptr not pointer --- include/RemotingCommand.h | 8 +- src/ClientRemotingProcessor.cpp | 19 +++-- src/ClientRemotingProcessor.h | 12 +-- src/MQClientAPIImpl.cpp | 84 ++++++++++--------- src/MQClientAPIImpl.h | 70 ++++++++-------- src/MQClientInstance.cpp | 35 ++++---- src/MQClientInstance.h | 16 ++-- src/common/FilterAPI.hpp | 7 +- src/consumer/DefaultLitePullConsumerImpl.cpp | 41 +++++---- src/consumer/DefaultLitePullConsumerImpl.h | 37 ++++---- src/consumer/DefaultMQPushConsumerImpl.cpp | 14 ++-- src/consumer/DefaultMQPushConsumerImpl.h | 2 +- src/consumer/MQConsumerInner.h | 3 +- src/consumer/PullAPIWrapper.cpp | 45 +++++----- src/consumer/PullAPIWrapper.h | 30 +++---- src/consumer/RebalanceImpl.cpp | 19 ++--- src/consumer/RebalanceImpl.h | 4 +- src/consumer/RebalanceLitePullImpl.h | 3 - src/consumer/RemoteBrokerOffsetStore.cpp | 4 +- src/io/ByteBuffer.cpp | 8 +- src/io/ByteBuffer.hpp | 14 ++-- src/io/DefaultByteBuffer.hpp | 15 ++-- src/message/MessageClientIDSetter.cpp | 4 +- src/producer/DefaultMQProducerImpl.cpp | 49 +++++------ src/producer/DefaultMQProducerImpl.h | 36 ++++---- src/protocol/RemotingCommand.cpp | 8 +- src/protocol/TopicList.h | 2 +- src/protocol/body/LockBatchResponseBody.hpp | 4 +- src/protocol/body/ResetOffsetBody.hpp | 4 +- src/protocol/body/TopicRouteData.hpp | 4 +- src/protocol/header/CommandHeader.cpp | 60 +++++++------ src/protocol/header/CommandHeader.h | 27 +++--- .../header/ReplyMessageRequestHeader.hpp | 4 +- src/transport/RequestProcessor.h | 2 +- src/transport/TcpRemotingClient.cpp | 4 +- test/src/protocol/RemotingCommandTest.cpp | 2 +- 36 files changed, 359 insertions(+), 341 deletions(-) diff --git a/include/RemotingCommand.h b/include/RemotingCommand.h index 68847b3b8..af67c8796 100644 --- a/include/RemotingCommand.h +++ b/include/RemotingCommand.h @@ -67,7 +67,7 @@ class ROCKETMQCLIENT_API RemotingCommand { template H* decodeCommandCustomHeader(bool useCache = true); - static RemotingCommand* Decode(ByteArrayRef array, bool hasPackageLength = false); + static std::unique_ptr Decode(ByteArrayRef array, bool hasPackageLength = false); std::string toString() const; @@ -116,9 +116,9 @@ H* RemotingCommand::decodeCommandCustomHeader(bool useCache) { } try { - H* header = H::Decode(ext_fields_); - custom_header_.reset(header); - return header; + std::unique_ptr header = H::Decode(ext_fields_); + custom_header_ = std::move(header); + return static_cast(custom_header_.get()); } catch (std::exception& e) { THROW_MQEXCEPTION(RemotingCommandException, e.what(), -1); } diff --git a/src/ClientRemotingProcessor.cpp b/src/ClientRemotingProcessor.cpp index d4fc34cb7..329d0d4ee 100644 --- a/src/ClientRemotingProcessor.cpp +++ b/src/ClientRemotingProcessor.cpp @@ -35,7 +35,8 @@ ClientRemotingProcessor::ClientRemotingProcessor(MQClientInstance* clientInstanc ClientRemotingProcessor::~ClientRemotingProcessor() = default; -RemotingCommand* ClientRemotingProcessor::processRequest(TcpTransportPtr channel, RemotingCommand* request) { +std::unique_ptr ClientRemotingProcessor::processRequest(TcpTransportPtr channel, + RemotingCommand* request) { const auto& addr = channel->getPeerAddrAndPort(); LOG_DEBUG_NEW("processRequest, code:{}, addr:{}", request->code(), addr); switch (request->code()) { @@ -61,7 +62,8 @@ RemotingCommand* ClientRemotingProcessor::processRequest(TcpTransportPtr channel return nullptr; } -RemotingCommand* ClientRemotingProcessor::checkTransactionState(const std::string& addr, RemotingCommand* request) { +std::unique_ptr ClientRemotingProcessor::checkTransactionState(const std::string& addr, + RemotingCommand* request) { auto* requestHeader = request->decodeCommandCustomHeader(); assert(requestHeader != nullptr); @@ -95,14 +97,14 @@ RemotingCommand* ClientRemotingProcessor::checkTransactionState(const std::strin return nullptr; } -RemotingCommand* ClientRemotingProcessor::notifyConsumerIdsChanged(RemotingCommand* request) { +std::unique_ptr ClientRemotingProcessor::notifyConsumerIdsChanged(RemotingCommand* request) { auto* requestHeader = request->decodeCommandCustomHeader(); LOG_INFO_NEW("notifyConsumerIdsChanged, group:{}", requestHeader->getConsumerGroup()); client_instance_->rebalanceImmediately(); return nullptr; } -RemotingCommand* ClientRemotingProcessor::resetOffset(RemotingCommand* request) { +std::unique_ptr ClientRemotingProcessor::resetOffset(RemotingCommand* request) { auto* responseHeader = request->decodeCommandCustomHeader(); auto requestBody = request->body(); if (requestBody != nullptr && requestBody->size() > 0) { @@ -116,7 +118,8 @@ RemotingCommand* ClientRemotingProcessor::resetOffset(RemotingCommand* request) return nullptr; // as resetOffset is oneWayRPC, do not need return any response } -RemotingCommand* ClientRemotingProcessor::getConsumerRunningInfo(const std::string& addr, RemotingCommand* request) { +std::unique_ptr ClientRemotingProcessor::getConsumerRunningInfo(const std::string& addr, + RemotingCommand* request) { auto* requestHeader = request->decodeCommandCustomHeader(); LOG_INFO_NEW("getConsumerRunningInfo, group:{}", requestHeader->getConsumerGroup()); @@ -137,10 +140,10 @@ RemotingCommand* ClientRemotingProcessor::getConsumerRunningInfo(const std::stri response->set_remark("The Consumer Group not exist in this consumer"); } - return response.release(); + return response; } -RemotingCommand* ClientRemotingProcessor::receiveReplyMessage(RemotingCommand* request) { +std::unique_ptr ClientRemotingProcessor::receiveReplyMessage(RemotingCommand* request) { std::unique_ptr response( new RemotingCommand(MQResponseCode::SYSTEM_ERROR, "not set any response code")); @@ -192,7 +195,7 @@ RemotingCommand* ClientRemotingProcessor::receiveReplyMessage(RemotingCommand* r response->set_remark("process reply message fail"); } - return response.release(); + return response; } void ClientRemotingProcessor::processReplyMessage(std::unique_ptr replyMsg) { diff --git a/src/ClientRemotingProcessor.h b/src/ClientRemotingProcessor.h index ca28297b0..7812d8882 100644 --- a/src/ClientRemotingProcessor.h +++ b/src/ClientRemotingProcessor.h @@ -28,13 +28,13 @@ class ClientRemotingProcessor : public RequestProcessor { ClientRemotingProcessor(MQClientInstance* clientInstance); virtual ~ClientRemotingProcessor(); - RemotingCommand* processRequest(TcpTransportPtr channel, RemotingCommand* request) override; + std::unique_ptr processRequest(TcpTransportPtr channel, RemotingCommand* request) override; - RemotingCommand* checkTransactionState(const std::string& addr, RemotingCommand* request); - RemotingCommand* notifyConsumerIdsChanged(RemotingCommand* request); - RemotingCommand* resetOffset(RemotingCommand* request); - RemotingCommand* getConsumerRunningInfo(const std::string& addr, RemotingCommand* request); - RemotingCommand* receiveReplyMessage(RemotingCommand* request); + std::unique_ptr checkTransactionState(const std::string& addr, RemotingCommand* request); + std::unique_ptr notifyConsumerIdsChanged(RemotingCommand* request); + std::unique_ptr resetOffset(RemotingCommand* request); + std::unique_ptr getConsumerRunningInfo(const std::string& addr, RemotingCommand* request); + std::unique_ptr receiveReplyMessage(RemotingCommand* request); private: void processReplyMessage(std::unique_ptr replyMsg); diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp index fe76f131c..176da3b9f 100644 --- a/src/MQClientAPIImpl.cpp +++ b/src/MQClientAPIImpl.cpp @@ -88,28 +88,28 @@ void MQClientAPIImpl::createTopic(const std::string& addr, const std::string& de THROW_MQEXCEPTION(MQBrokerException, response->remark(), response->code()); } -SendResult* MQClientAPIImpl::sendMessage(const std::string& addr, - const std::string& brokerName, - const MessagePtr msg, - std::unique_ptr requestHeader, - int timeoutMillis, - CommunicationMode communicationMode, - DefaultMQProducerImplPtr producer) { +std::unique_ptr MQClientAPIImpl::sendMessage(const std::string& addr, + const std::string& brokerName, + const MessagePtr msg, + std::unique_ptr requestHeader, + int timeoutMillis, + CommunicationMode communicationMode, + DefaultMQProducerImplPtr producer) { return sendMessage(addr, brokerName, msg, std::move(requestHeader), timeoutMillis, communicationMode, nullptr, nullptr, nullptr, 0, producer); } -SendResult* MQClientAPIImpl::sendMessage(const std::string& addr, - const std::string& brokerName, - const MessagePtr msg, - std::unique_ptr requestHeader, - int timeoutMillis, - CommunicationMode communicationMode, - SendCallback* sendCallback, - TopicPublishInfoPtr topicPublishInfo, - MQClientInstancePtr instance, - int retryTimesWhenSendFailed, - DefaultMQProducerImplPtr producer) { +std::unique_ptr MQClientAPIImpl::sendMessage(const std::string& addr, + const std::string& brokerName, + const MessagePtr msg, + std::unique_ptr requestHeader, + int timeoutMillis, + CommunicationMode communicationMode, + SendCallback* sendCallback, + TopicPublishInfoPtr topicPublishInfo, + MQClientInstancePtr instance, + int retryTimesWhenSendFailed, + DefaultMQProducerImplPtr producer) { int code = SEND_MESSAGE; std::unique_ptr header; @@ -124,7 +124,7 @@ SendResult* MQClientAPIImpl::sendMessage(const std::string& addr, } if (code != SEND_MESSAGE && code != SEND_REPLY_MESSAGE) { - header.reset(SendMessageRequestHeaderV2::createSendMessageRequestHeaderV2(requestHeader.get())); + header = SendMessageRequestHeaderV2::createSendMessageRequestHeaderV2(requestHeader.get()); } else { header = std::move(requestHeader); } @@ -173,20 +173,20 @@ void MQClientAPIImpl::sendMessageAsyncImpl(std::unique_ptr& cbw, remoting_client_->invokeAsync(addr, request, cbw, timeoutMillis); } -SendResult* MQClientAPIImpl::sendMessageSync(const std::string& addr, - const std::string& brokerName, - const MessagePtr msg, - RemotingCommand& request, - int timeoutMillis) { +std::unique_ptr MQClientAPIImpl::sendMessageSync(const std::string& addr, + const std::string& brokerName, + const MessagePtr msg, + RemotingCommand& request, + int timeoutMillis) { // block until response std::unique_ptr response(remoting_client_->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); return processSendResponse(brokerName, msg, response.get()); } -SendResult* MQClientAPIImpl::processSendResponse(const std::string& brokerName, - const MessagePtr msg, - RemotingCommand* response) { +std::unique_ptr MQClientAPIImpl::processSendResponse(const std::string& brokerName, + const MessagePtr msg, + RemotingCommand* response) { SendStatus sendStatus = SEND_OK; switch (response->code()) { case FLUSH_DISK_TIMEOUT: @@ -227,18 +227,18 @@ SendResult* MQClientAPIImpl::processSendResponse(const std::string& brokerName, } } - SendResult* sendResult = - new SendResult(sendStatus, uniqMsgId, responseHeader->msgId, messageQueue, responseHeader->queueOffset); + std::unique_ptr sendResult( + new SendResult(sendStatus, uniqMsgId, responseHeader->msgId, messageQueue, responseHeader->queueOffset)); sendResult->set_transaction_id(responseHeader->transactionId); return sendResult; } -PullResult* MQClientAPIImpl::pullMessage(const std::string& addr, - PullMessageRequestHeader* requestHeader, - int timeoutMillis, - CommunicationMode communicationMode, - PullCallback* pullCallback) { +std::unique_ptr MQClientAPIImpl::pullMessage(const std::string& addr, + PullMessageRequestHeader* requestHeader, + int timeoutMillis, + CommunicationMode communicationMode, + PullCallback* pullCallback) { RemotingCommand request(PULL_MESSAGE, requestHeader); switch (communicationMode) { @@ -261,13 +261,15 @@ void MQClientAPIImpl::pullMessageAsync(const std::string& addr, remoting_client_->invokeAsync(addr, request, cbw, timeoutMillis); } -PullResult* MQClientAPIImpl::pullMessageSync(const std::string& addr, RemotingCommand& request, int timeoutMillis) { +std::unique_ptr MQClientAPIImpl::pullMessageSync(const std::string& addr, + RemotingCommand& request, + int timeoutMillis) { std::unique_ptr response(remoting_client_->invokeSync(addr, request, timeoutMillis)); assert(response != nullptr); return processPullResponse(response.get()); } -PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* response) { +std::unique_ptr MQClientAPIImpl::processPullResponse(RemotingCommand* response) { PullStatus pullStatus = NO_NEW_MSG; switch (response->code()) { case SUCCESS: @@ -294,8 +296,9 @@ PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* response) { auto* responseHeader = response->decodeCommandCustomHeader(); assert(responseHeader != nullptr); - return new PullResultExt(pullStatus, responseHeader->nextBeginOffset, responseHeader->minOffset, - responseHeader->maxOffset, (int)responseHeader->suggestWhichBrokerId, response->body()); + return std::unique_ptr(new PullResultExt(pullStatus, responseHeader->nextBeginOffset, + responseHeader->minOffset, responseHeader->maxOffset, + (int)responseHeader->suggestWhichBrokerId, response->body())); } MQMessageExt MQClientAPIImpl::viewMessage(const std::string& addr, int64_t phyoffset, int timeoutMillis) { @@ -622,7 +625,8 @@ void MQClientAPIImpl::unlockBatchMQ(const std::string& addr, } } -TopicRouteData* MQClientAPIImpl::getTopicRouteInfoFromNameServer(const std::string& topic, int timeoutMillis) { +std::unique_ptr MQClientAPIImpl::getTopicRouteInfoFromNameServer(const std::string& topic, + int timeoutMillis) { RemotingCommand request(GET_ROUTEINFO_BY_TOPIC, new GetRouteInfoRequestHeader(topic)); std::unique_ptr response(remoting_client_->invokeSync(null, request, timeoutMillis)); @@ -642,7 +646,7 @@ TopicRouteData* MQClientAPIImpl::getTopicRouteInfoFromNameServer(const std::stri THROW_MQEXCEPTION(MQClientException, response->remark(), response->code()); } -TopicList* MQClientAPIImpl::getTopicListFromNameServer() { +std::unique_ptr MQClientAPIImpl::getTopicListFromNameServer() { RemotingCommand request(GET_ALL_TOPIC_LIST_FROM_NAMESERVER, nullptr); std::unique_ptr response(remoting_client_->invokeSync(null, request)); diff --git a/src/MQClientAPIImpl.h b/src/MQClientAPIImpl.h index 535f33d8a..5bebeff78 100644 --- a/src/MQClientAPIImpl.h +++ b/src/MQClientAPIImpl.h @@ -59,32 +59,34 @@ class MQClientAPIImpl { void createTopic(const std::string& addr, const std::string& defaultTopic, TopicConfig topicConfig); - SendResult* sendMessage(const std::string& addr, - const std::string& brokerName, - const MessagePtr msg, - std::unique_ptr requestHeader, - int timeoutMillis, - CommunicationMode communicationMode, - DefaultMQProducerImplPtr producer); - SendResult* sendMessage(const std::string& addr, - const std::string& brokerName, - const MessagePtr msg, - std::unique_ptr requestHeader, - int timeoutMillis, - CommunicationMode communicationMode, - SendCallback* sendCallback, - TopicPublishInfoPtr topicPublishInfo, - MQClientInstancePtr instance, - int retryTimesWhenSendFailed, - DefaultMQProducerImplPtr producer); - SendResult* processSendResponse(const std::string& brokerName, const MessagePtr msg, RemotingCommand* pResponse); - - PullResult* pullMessage(const std::string& addr, - PullMessageRequestHeader* requestHeader, - int timeoutMillis, - CommunicationMode communicationMode, - PullCallback* pullCallback); - PullResult* processPullResponse(RemotingCommand* pResponse); + std::unique_ptr sendMessage(const std::string& addr, + const std::string& brokerName, + const MessagePtr msg, + std::unique_ptr requestHeader, + int timeoutMillis, + CommunicationMode communicationMode, + DefaultMQProducerImplPtr producer); + std::unique_ptr sendMessage(const std::string& addr, + const std::string& brokerName, + const MessagePtr msg, + std::unique_ptr requestHeader, + int timeoutMillis, + CommunicationMode communicationMode, + SendCallback* sendCallback, + TopicPublishInfoPtr topicPublishInfo, + MQClientInstancePtr instance, + int retryTimesWhenSendFailed, + DefaultMQProducerImplPtr producer); + std::unique_ptr processSendResponse(const std::string& brokerName, + const MessagePtr msg, + RemotingCommand* pResponse); + + std::unique_ptr pullMessage(const std::string& addr, + PullMessageRequestHeader* requestHeader, + int timeoutMillis, + CommunicationMode communicationMode, + PullCallback* pullCallback); + std::unique_ptr processPullResponse(RemotingCommand* pResponse); MQMessageExt viewMessage(const std::string& addr, int64_t phyoffset, int timeoutMillis); @@ -141,9 +143,9 @@ class MQClientAPIImpl { int timeoutMillis, bool oneway = false); - TopicRouteData* getTopicRouteInfoFromNameServer(const std::string& topic, int timeoutMillis); + std::unique_ptr getTopicRouteInfoFromNameServer(const std::string& topic, int timeoutMillis); - TopicList* getTopicListFromNameServer(); + std::unique_ptr getTopicListFromNameServer(); int wipeWritePermOfBroker(const std::string& namesrvAddr, const std::string& brokerName, int timeoutMillis); @@ -165,11 +167,11 @@ class MQClientAPIImpl { private: friend class SendCallbackWrap; - SendResult* sendMessageSync(const std::string& addr, - const std::string& brokerName, - const MessagePtr msg, - RemotingCommand& request, - int timeoutMillis); + std::unique_ptr sendMessageSync(const std::string& addr, + const std::string& brokerName, + const MessagePtr msg, + RemotingCommand& request, + int timeoutMillis); void sendMessageAsync(const std::string& addr, const std::string& brokerName, @@ -184,7 +186,7 @@ class MQClientAPIImpl { void sendMessageAsyncImpl(std::unique_ptr& cbw, int64_t timeoutMillis); - PullResult* pullMessageSync(const std::string& addr, RemotingCommand& request, int timeoutMillis); + std::unique_ptr pullMessageSync(const std::string& addr, RemotingCommand& request, int timeoutMillis); void pullMessageAsync(const std::string& addr, RemotingCommand& request, diff --git a/src/MQClientInstance.cpp b/src/MQClientInstance.cpp index 443b7c401..d9ebc4e96 100644 --- a/src/MQClientInstance.cpp +++ b/src/MQClientInstance.cpp @@ -19,7 +19,6 @@ #include #include "ClientRemotingProcessor.h" -#include "protocol/body/ConsumerRunningInfo.h" #include "Logging.h" #include "MQAdminImpl.h" #include "MQClientAPIImpl.h" @@ -33,6 +32,7 @@ #include "TcpRemotingClient.h" #include "TopicPublishInfo.hpp" #include "UtilAll.h" +#include "protocol/body/ConsumerRunningInfo.h" namespace rocketmq { @@ -415,8 +415,7 @@ bool MQClientInstance::updateTopicRouteInfoFromNameServer(const std::string& top try { TopicRouteDataPtr topicRouteData; if (isDefault) { - topicRouteData.reset( - mq_client_api_impl_->getTopicRouteInfoFromNameServer(AUTO_CREATE_TOPIC_KEY_TOPIC, 1000 * 3)); + topicRouteData = mq_client_api_impl_->getTopicRouteInfoFromNameServer(AUTO_CREATE_TOPIC_KEY_TOPIC, 1000 * 3); if (topicRouteData != nullptr) { auto& queueDatas = topicRouteData->queue_datas(); for (auto& qd : queueDatas) { @@ -427,7 +426,7 @@ bool MQClientInstance::updateTopicRouteInfoFromNameServer(const std::string& top } LOG_DEBUG_NEW("getTopicRouteInfoFromNameServer is null for topic: {}", topic); } else { - topicRouteData.reset(mq_client_api_impl_->getTopicRouteInfoFromNameServer(topic, 1000 * 3)); + topicRouteData = mq_client_api_impl_->getTopicRouteInfoFromNameServer(topic, 1000 * 3); } if (topicRouteData != nullptr) { LOG_INFO_NEW("updateTopicRouteInfoFromNameServer has data"); @@ -477,19 +476,19 @@ bool MQClientInstance::updateTopicRouteInfoFromNameServer(const std::string& top return false; } -HeartbeatData* MQClientInstance::prepareHeartbeatData() { - HeartbeatData* pHeartbeatData = new HeartbeatData(); +std::unique_ptr MQClientInstance::prepareHeartbeatData() { + std::unique_ptr heartbeat_data(new HeartbeatData()); // clientID - pHeartbeatData->set_client_id(client_id_); + heartbeat_data->set_client_id(client_id_); // Consumer - insertConsumerInfoToHeartBeatData(pHeartbeatData); + insertConsumerInfoToHeartBeatData(heartbeat_data.get()); // Producer - insertProducerInfoToHeartBeatData(pHeartbeatData); + insertProducerInfoToHeartBeatData(heartbeat_data.get()); - return pHeartbeatData; + return heartbeat_data; } void MQClientInstance::insertConsumerInfoToHeartBeatData(HeartbeatData* heartbeatData) { @@ -769,7 +768,7 @@ TopicPublishInfoPtr MQClientInstance::tryToFindTopicPublishInfo(const std::strin } } -FindBrokerResult* MQClientInstance::findBrokerAddressInAdmin(const std::string& brokerName) { +std::unique_ptr MQClientInstance::findBrokerAddressInAdmin(const std::string& brokerName) { BrokerAddrMAP brokerTable(getBrokerAddrTable()); bool found = false; bool slave = false; @@ -788,7 +787,7 @@ FindBrokerResult* MQClientInstance::findBrokerAddressInAdmin(const std::string& brokerTable.clear(); if (found) { - return new FindBrokerResult(brokerAddr, slave); + return std::unique_ptr(new FindBrokerResult(brokerAddr, slave)); } return nullptr; @@ -817,9 +816,9 @@ std::string MQClientInstance::findBrokerAddressInPublish(const std::string& brok return null; } -FindBrokerResult* MQClientInstance::findBrokerAddressInSubscribe(const std::string& brokerName, - int brokerId, - bool onlyThisBroker) { +std::unique_ptr MQClientInstance::findBrokerAddressInSubscribe(const std::string& brokerName, + int brokerId, + bool onlyThisBroker) { std::string brokerAddr; bool slave = false; bool found = false; @@ -846,7 +845,7 @@ FindBrokerResult* MQClientInstance::findBrokerAddressInSubscribe(const std::stri brokerTable.clear(); if (found) { - return new FindBrokerResult(brokerAddr, slave); + return std::unique_ptr(new FindBrokerResult(brokerAddr, slave)); } return nullptr; @@ -950,7 +949,7 @@ void MQClientInstance::resetOffset(const std::string& group, } } -ConsumerRunningInfo* MQClientInstance::consumerRunningInfo(const std::string& consumerGroup) { +std::unique_ptr MQClientInstance::consumerRunningInfo(const std::string& consumerGroup) { auto* consumer = selectConsumer(consumerGroup); if (consumer != nullptr) { std::unique_ptr runningInfo(consumer->consumerRunningInfo()); @@ -967,7 +966,7 @@ ConsumerRunningInfo* MQClientInstance::consumerRunningInfo(const std::string& co runningInfo->setProperty(ConsumerRunningInfo::PROP_CLIENT_VERSION, MQVersion::GetVersionDesc(MQVersion::CURRENT_VERSION)); - return runningInfo.release(); + return runningInfo; } } diff --git a/src/MQClientInstance.h b/src/MQClientInstance.h index 5a589aaf2..bf606b100 100644 --- a/src/MQClientInstance.h +++ b/src/MQClientInstance.h @@ -22,18 +22,18 @@ #include #include -#include "protocol/body/ConsumerRunningInfo.h" #include "FindBrokerResult.hpp" #include "MQClientConfig.h" -#include "MQException.h" #include "MQConsumerInner.h" +#include "MQException.h" #include "MQMessageQueue.h" #include "MQProducerInner.h" #include "ServiceState.h" #include "TopicPublishInfo.hpp" +#include "concurrent/executor.hpp" +#include "protocol/body/ConsumerRunningInfo.h" #include "protocol/body/TopicRouteData.hpp" #include "protocol/heartbeat/HeartbeatData.hpp" -#include "concurrent/executor.hpp" namespace rocketmq { @@ -83,9 +83,11 @@ class MQClientInstance { MQProducerInner* selectProducer(const std::string& group); MQConsumerInner* selectConsumer(const std::string& group); - FindBrokerResult* findBrokerAddressInAdmin(const std::string& brokerName); + std::unique_ptr findBrokerAddressInAdmin(const std::string& brokerName); std::string findBrokerAddressInPublish(const std::string& brokerName); - FindBrokerResult* findBrokerAddressInSubscribe(const std::string& brokerName, int brokerId, bool onlyThisBroker); + std::unique_ptr findBrokerAddressInSubscribe(const std::string& brokerName, + int brokerId, + bool onlyThisBroker); void findConsumerIds(const std::string& topic, const std::string& group, std::vector& cids); @@ -95,7 +97,7 @@ class MQClientInstance { const std::string& topic, const std::map& offsetTable); - ConsumerRunningInfo* consumerRunningInfo(const std::string& consumerGroup); + std::unique_ptr consumerRunningInfo(const std::string& consumerGroup); public: TopicPublishInfoPtr tryToFindTopicPublishInfo(const std::string& topic); @@ -133,7 +135,7 @@ class MQClientInstance { // heartbeat void sendHeartbeatToAllBroker(); - HeartbeatData* prepareHeartbeatData(); + std::unique_ptr prepareHeartbeatData(); void insertConsumerInfoToHeartBeatData(HeartbeatData* pHeartbeatData); void insertProducerInfoToHeartBeatData(HeartbeatData* pHeartbeatData); diff --git a/src/common/FilterAPI.hpp b/src/common/FilterAPI.hpp index 9bb18bb84..76096cfdb 100644 --- a/src/common/FilterAPI.hpp +++ b/src/common/FilterAPI.hpp @@ -20,14 +20,15 @@ #include // std::string #include "MQException.h" -#include "protocol/heartbeat/SubscriptionData.hpp" #include "UtilAll.h" +#include "protocol/heartbeat/SubscriptionData.hpp" namespace rocketmq { class FilterAPI { public: - static SubscriptionData* buildSubscriptionData(const std::string& topic, const std::string& sub_string) { + static std::unique_ptr buildSubscriptionData(const std::string& topic, + const std::string& sub_string) { // delete in Rebalance std::unique_ptr subscription_data(new SubscriptionData(topic, sub_string)); @@ -52,7 +53,7 @@ class FilterAPI { } } - return subscription_data.release(); + return subscription_data; } }; diff --git a/src/consumer/DefaultLitePullConsumerImpl.cpp b/src/consumer/DefaultLitePullConsumerImpl.cpp index 3a5fc8166..f53f7ed57 100644 --- a/src/consumer/DefaultLitePullConsumerImpl.cpp +++ b/src/consumer/DefaultLitePullConsumerImpl.cpp @@ -22,11 +22,11 @@ #include "AssignedMessageQueue.hpp" #include "FilterAPI.hpp" +#include "LocalFileOffsetStore.h" #include "MQAdminImpl.h" #include "MQClientAPIImpl.h" #include "MQClientInstance.h" #include "NamespaceUtil.h" -#include "LocalFileOffsetStore.h" #include "PullAPIWrapper.h" #include "PullSysFlag.h" #include "RebalanceLitePullImpl.h" @@ -186,7 +186,7 @@ class DefaultLitePullConsumerImpl::PullTaskImpl : public std::enable_shared_from if (consumer->subscription_type_ == SubscriptionType::SUBSCRIBE) { subscription_data = consumer->rebalance_impl_->getSubscriptionData(message_queue_.topic()); } else { - subscription_data = FilterAPI::buildSubscriptionData(message_queue_.topic(), SUB_ALL); + subscription_data = FilterAPI::buildSubscriptionData(message_queue_.topic(), SUB_ALL).release(); } std::unique_ptr pull_result( @@ -502,8 +502,7 @@ void DefaultLitePullConsumerImpl::subscribe(const std::string& topic, const std: THROW_MQEXCEPTION(MQClientException, "Topic can not be null or empty.", -1); } set_subscription_type(SubscriptionType::SUBSCRIBE); - auto* subscription_data = FilterAPI::buildSubscriptionData(topic, subExpression); - rebalance_impl_->setSubscriptionData(topic, subscription_data); + rebalance_impl_->setSubscriptionData(topic, FilterAPI::buildSubscriptionData(topic, subExpression)); message_queue_listener_.reset(new MessageQueueListenerImpl(shared_from_this())); assigned_message_queue_->set_rebalance_impl(rebalance_impl_.get()); @@ -600,29 +599,29 @@ int64_t DefaultLitePullConsumerImpl::fetchConsumeOffset(const MQMessageQueue& me return rebalance_impl_->computePullFromWhere(messageQueue); } -PullResult* DefaultLitePullConsumerImpl::pull(const MQMessageQueue& mq, - SubscriptionData* subscription_data, - int64_t offset, - int max_nums) { +std::unique_ptr DefaultLitePullConsumerImpl::pull(const MQMessageQueue& mq, + SubscriptionData* subscription_data, + int64_t offset, + int max_nums) { return pull(mq, subscription_data, offset, max_nums, getDefaultLitePullConsumerConfig()->consumer_pull_timeout_millis()); } -PullResult* DefaultLitePullConsumerImpl::pull(const MQMessageQueue& mq, - SubscriptionData* subscription_data, - int64_t offset, - int max_nums, - long timeout) { +std::unique_ptr DefaultLitePullConsumerImpl::pull(const MQMessageQueue& mq, + SubscriptionData* subscription_data, + int64_t offset, + int max_nums, + long timeout) { return pullSyncImpl(mq, subscription_data, offset, max_nums, getDefaultLitePullConsumerConfig()->long_polling_enable(), timeout); } -PullResult* DefaultLitePullConsumerImpl::pullSyncImpl(const MQMessageQueue& mq, - SubscriptionData* subscription_data, - int64_t offset, - int max_nums, - bool block, - long timeout) { +std::unique_ptr DefaultLitePullConsumerImpl::pullSyncImpl(const MQMessageQueue& mq, + SubscriptionData* subscription_data, + int64_t offset, + int max_nums, + bool block, + long timeout) { if (offset < 0) { THROW_MQEXCEPTION(MQClientException, "offset < 0", -1); } @@ -838,8 +837,8 @@ void DefaultLitePullConsumerImpl::registerTopicMessageQueueChangeListener( } } -ConsumerRunningInfo* DefaultLitePullConsumerImpl::consumerRunningInfo() { - auto* info = new ConsumerRunningInfo(); +std::unique_ptr DefaultLitePullConsumerImpl::consumerRunningInfo() { + std::unique_ptr info(new ConsumerRunningInfo()); info->setProperty(ConsumerRunningInfo::PROP_CONSUMER_START_TIMESTAMP, UtilAll::to_string(start_time_)); diff --git a/src/consumer/DefaultLitePullConsumerImpl.h b/src/consumer/DefaultLitePullConsumerImpl.h index 6923799cf..1f727d93c 100755 --- a/src/consumer/DefaultLitePullConsumerImpl.h +++ b/src/consumer/DefaultLitePullConsumerImpl.h @@ -21,14 +21,14 @@ #include // std::mutex #include // std::string -#include "concurrent/blocking_queue.hpp" -#include "concurrent/executor.hpp" #include "DefaultLitePullConsumer.h" -#include "MessageQueueListener.h" -#include "MessageQueueLock.hpp" #include "MQClientImpl.h" #include "MQConsumerInner.h" +#include "MessageQueueListener.h" +#include "MessageQueueLock.hpp" #include "TopicMessageQueueChangeListener.h" +#include "concurrent/blocking_queue.hpp" +#include "concurrent/executor.hpp" namespace rocketmq { @@ -125,7 +125,7 @@ class DefaultLitePullConsumerImpl : public std::enable_shared_from_this consumerRunningInfo() override; private: void checkConfig(); @@ -149,18 +149,21 @@ class DefaultLitePullConsumerImpl : public std::enable_shared_from_this pull(const MQMessageQueue& mq, + SubscriptionData* subscription_data, + int64_t offset, + int max_nums); + std::unique_ptr pull(const MQMessageQueue& mq, + SubscriptionData* subscription_data, + int64_t offset, + int max_nums, + long timeout); + std::unique_ptr pullSyncImpl(const MQMessageQueue& mq, + SubscriptionData* subscription_data, + int64_t offset, + int max_nums, + bool block, + long timeout); void submitConsumeRequest(ConsumeRequest* consume_request); diff --git a/src/consumer/DefaultMQPushConsumerImpl.cpp b/src/consumer/DefaultMQPushConsumerImpl.cpp index 77ba01782..1c8a76316 100644 --- a/src/consumer/DefaultMQPushConsumerImpl.cpp +++ b/src/consumer/DefaultMQPushConsumerImpl.cpp @@ -62,8 +62,8 @@ class DefaultMQPushConsumerImpl::AsyncPullCallback : public AutoDeletePullCallba return; } - pull_result.reset(consumer->pull_api_wrapper_->processPullResult(pull_request_->message_queue(), - std::move(pull_result), subscription_data_)); + pull_result = consumer->pull_api_wrapper_->processPullResult(pull_request_->message_queue(), std::move(pull_result), + subscription_data_); switch (pull_result->pull_status()) { case FOUND: { int64_t prev_request_offset = pull_request_->next_offset(); @@ -298,8 +298,7 @@ void DefaultMQPushConsumerImpl::checkConfig() { void DefaultMQPushConsumerImpl::copySubscription() { for (const auto& it : subscription_) { LOG_INFO_NEW("buildSubscriptionData: {}, {}", it.first, it.second); - SubscriptionData* subscriptionData = FilterAPI::buildSubscriptionData(it.first, it.second); - rebalance_impl_->setSubscriptionData(it.first, subscriptionData); + rebalance_impl_->setSubscriptionData(it.first, FilterAPI::buildSubscriptionData(it.first, it.second)); } switch (getDefaultMQPushConsumerConfig()->message_model()) { @@ -308,8 +307,7 @@ void DefaultMQPushConsumerImpl::copySubscription() { case CLUSTERING: { // auto subscript retry topic std::string retryTopic = UtilAll::getRetryTopic(client_config_->group_name()); - SubscriptionData* subscriptionData = FilterAPI::buildSubscriptionData(retryTopic, SUB_ALL); - rebalance_impl_->setSubscriptionData(retryTopic, subscriptionData); + rebalance_impl_->setSubscriptionData(retryTopic, FilterAPI::buildSubscriptionData(retryTopic, SUB_ALL)); break; } default: @@ -572,8 +570,8 @@ void DefaultMQPushConsumerImpl::updateConsumeOffset(const MQMessageQueue& mq, in } } -ConsumerRunningInfo* DefaultMQPushConsumerImpl::consumerRunningInfo() { - auto* info = new ConsumerRunningInfo(); +std::unique_ptr DefaultMQPushConsumerImpl::consumerRunningInfo() { + std::unique_ptr info(new ConsumerRunningInfo()); info->setProperty(ConsumerRunningInfo::PROP_CONSUME_ORDERLY, UtilAll::to_string(consume_orderly_)); info->setProperty(ConsumerRunningInfo::PROP_THREADPOOL_CORE_SIZE, diff --git a/src/consumer/DefaultMQPushConsumerImpl.h b/src/consumer/DefaultMQPushConsumerImpl.h index ecac5868f..28fe38597 100755 --- a/src/consumer/DefaultMQPushConsumerImpl.h +++ b/src/consumer/DefaultMQPushConsumerImpl.h @@ -100,7 +100,7 @@ class DefaultMQPushConsumerImpl : public std::enable_shared_from_this consumerRunningInfo() override; public: void executePullRequestLater(PullRequestPtr pullRequest, long timeDelay); diff --git a/src/consumer/MQConsumerInner.h b/src/consumer/MQConsumerInner.h index d38e83979..3daa1b8e7 100644 --- a/src/consumer/MQConsumerInner.h +++ b/src/consumer/MQConsumerInner.h @@ -21,6 +21,7 @@ #include #include "ConsumeType.h" +#include "MQMessageQueue.h" #include "protocol/heartbeat/SubscriptionData.hpp" namespace rocketmq { @@ -48,7 +49,7 @@ class MQConsumerInner { // offset persistence virtual void persistConsumerOffset() = 0; - virtual ConsumerRunningInfo* consumerRunningInfo() = 0; + virtual std::unique_ptr consumerRunningInfo() = 0; }; } // namespace rocketmq diff --git a/src/consumer/PullAPIWrapper.cpp b/src/consumer/PullAPIWrapper.cpp index e25f423f1..16049f257 100644 --- a/src/consumer/PullAPIWrapper.cpp +++ b/src/consumer/PullAPIWrapper.cpp @@ -16,11 +16,13 @@ */ #include "PullAPIWrapper.h" +#include + #include "ByteBuffer.hpp" #include "MQClientAPIImpl.h" #include "MQClientInstance.h" -#include "MessageDecoder.h" #include "MessageAccessor.hpp" +#include "MessageDecoder.h" #include "PullResultExt.hpp" #include "PullSysFlag.h" @@ -50,12 +52,12 @@ int PullAPIWrapper::recalculatePullFromWhichNode(const MQMessageQueue& mq) { return MASTER_ID; } -PullResult* PullAPIWrapper::processPullResult(const MQMessageQueue& mq, - std::unique_ptr pull_result, - SubscriptionData* subscription_data) { +std::unique_ptr PullAPIWrapper::processPullResult(const MQMessageQueue& mq, + std::unique_ptr pull_result, + SubscriptionData* subscription_data) { auto* pull_result_ext = dynamic_cast(pull_result.get()); if (pull_result_ext == nullptr) { - return pull_result.release(); + return pull_result; } // update node @@ -94,28 +96,29 @@ PullResult* PullAPIWrapper::processPullResult(const MQMessageQueue& mq, } } - return new PullResult(pull_result_ext->pull_status(), pull_result_ext->next_begin_offset(), - pull_result_ext->min_offset(), pull_result_ext->max_offset(), std::move(msg_list_filter_again)); + return std::unique_ptr(new PullResult(pull_result_ext->pull_status(), + pull_result_ext->next_begin_offset(), pull_result_ext->min_offset(), + pull_result_ext->max_offset(), std::move(msg_list_filter_again))); } -PullResult* PullAPIWrapper::pullKernelImpl(const MQMessageQueue& mq, - const std::string& subExpression, - const std::string& expressionType, - int64_t subVersion, - int64_t offset, - int maxNums, - int sysFlag, - int64_t commitOffset, - int brokerSuspendMaxTimeMillis, - int timeoutMillis, - CommunicationMode communicationMode, - PullCallback* pullCallback) { +std::unique_ptr PullAPIWrapper::pullKernelImpl(const MQMessageQueue& mq, + const std::string& subExpression, + const std::string& expressionType, + int64_t subVersion, + int64_t offset, + int maxNums, + int sysFlag, + int64_t commitOffset, + int brokerSuspendMaxTimeMillis, + int timeoutMillis, + CommunicationMode communicationMode, + PullCallback* pullCallback) { std::unique_ptr findBrokerResult( client_instance_->findBrokerAddressInSubscribe(mq.broker_name(), recalculatePullFromWhichNode(mq), false)); if (findBrokerResult == nullptr) { client_instance_->updateTopicRouteInfoFromNameServer(mq.topic()); - findBrokerResult.reset( - client_instance_->findBrokerAddressInSubscribe(mq.broker_name(), recalculatePullFromWhichNode(mq), false)); + findBrokerResult = + client_instance_->findBrokerAddressInSubscribe(mq.broker_name(), recalculatePullFromWhichNode(mq), false); } if (findBrokerResult != nullptr) { diff --git a/src/consumer/PullAPIWrapper.h b/src/consumer/PullAPIWrapper.h index 7bdbf5bf7..01727d306 100644 --- a/src/consumer/PullAPIWrapper.h +++ b/src/consumer/PullAPIWrapper.h @@ -32,22 +32,22 @@ class PullAPIWrapper { PullAPIWrapper(MQClientInstance* instance, const std::string& consumerGroup); ~PullAPIWrapper(); - PullResult* processPullResult(const MQMessageQueue& mq, - std::unique_ptr pull_result, - SubscriptionData* subscriptionData); + std::unique_ptr processPullResult(const MQMessageQueue& mq, + std::unique_ptr pull_result, + SubscriptionData* subscriptionData); - PullResult* pullKernelImpl(const MQMessageQueue& mq, - const std::string& subExpression, - const std::string& expressionType, - int64_t subVersion, - int64_t offset, - int maxNums, - int sysFlag, - int64_t commitOffset, - int brokerSuspendMaxTimeMillis, - int timeoutMillis, - CommunicationMode communicationMode, - PullCallback* pullCallback); + std::unique_ptr pullKernelImpl(const MQMessageQueue& mq, + const std::string& subExpression, + const std::string& expressionType, + int64_t subVersion, + int64_t offset, + int maxNums, + int sysFlag, + int64_t commitOffset, + int brokerSuspendMaxTimeMillis, + int timeoutMillis, + CommunicationMode communicationMode, + PullCallback* pullCallback); private: void updatePullFromWhichNode(const MQMessageQueue& mq, int brokerId); diff --git a/src/consumer/RebalanceImpl.cpp b/src/consumer/RebalanceImpl.cpp index f890ea9e5..f97bc16de 100644 --- a/src/consumer/RebalanceImpl.cpp +++ b/src/consumer/RebalanceImpl.cpp @@ -30,11 +30,7 @@ RebalanceImpl::RebalanceImpl(const std::string& consumerGroup, allocate_mq_strategy_(allocateMqStrategy), client_instance_(instance) {} -RebalanceImpl::~RebalanceImpl() { - for (auto& it : subscription_inner_) { - deleteAndZero(it.second); - } -} +RebalanceImpl::~RebalanceImpl() = default; void RebalanceImpl::unlock(const MQMessageQueue& mq, const bool oneway) { std::unique_ptr findBrokerResult( @@ -474,18 +470,15 @@ TOPIC2SD& RebalanceImpl::getSubscriptionInner() { SubscriptionData* RebalanceImpl::getSubscriptionData(const std::string& topic) { const auto& it = subscription_inner_.find(topic); if (it != subscription_inner_.end()) { - return it->second; + return it->second.get(); } return nullptr; } -void RebalanceImpl::setSubscriptionData(const std::string& topic, SubscriptionData* subscriptionData) noexcept { - if (subscriptionData != nullptr) { - const auto& it = subscription_inner_.find(topic); - if (it != subscription_inner_.end()) { - deleteAndZero(it->second); - } - subscription_inner_[topic] = subscriptionData; +void RebalanceImpl::setSubscriptionData(const std::string& topic, + std::unique_ptr subscription_data) noexcept { + if (subscription_data != nullptr) { + subscription_inner_[topic] = std::move(subscription_data); } } diff --git a/src/consumer/RebalanceImpl.h b/src/consumer/RebalanceImpl.h index a44784e07..55b33fd5e 100755 --- a/src/consumer/RebalanceImpl.h +++ b/src/consumer/RebalanceImpl.h @@ -32,7 +32,7 @@ namespace rocketmq { typedef std::map MQ2PQ; typedef std::map> TOPIC2MQS; -typedef std::map TOPIC2SD; +typedef std::map> TOPIC2SD; typedef std::map> BROKER2MQS; class RebalanceImpl { @@ -75,7 +75,7 @@ class RebalanceImpl { public: TOPIC2SD& getSubscriptionInner(); SubscriptionData* getSubscriptionData(const std::string& topic); - void setSubscriptionData(const std::string& topic, SubscriptionData* sd) noexcept; + void setSubscriptionData(const std::string& topic, std::unique_ptr sd) noexcept; bool getTopicSubscribeInfo(const std::string& topic, std::vector& mqs); void setTopicSubscribeInfo(const std::string& topic, std::vector& mqs); diff --git a/src/consumer/RebalanceLitePullImpl.h b/src/consumer/RebalanceLitePullImpl.h index 56b6189ac..90bcf8e1c 100755 --- a/src/consumer/RebalanceLitePullImpl.h +++ b/src/consumer/RebalanceLitePullImpl.h @@ -23,9 +23,6 @@ namespace rocketmq { typedef std::map MQ2PQ; -typedef std::map> TOPIC2MQS; -typedef std::map TOPIC2SD; -typedef std::map> BROKER2MQS; class RebalanceLitePullImpl : public RebalanceImpl { public: diff --git a/src/consumer/RemoteBrokerOffsetStore.cpp b/src/consumer/RemoteBrokerOffsetStore.cpp index ad2e210b3..713bf1782 100644 --- a/src/consumer/RemoteBrokerOffsetStore.cpp +++ b/src/consumer/RemoteBrokerOffsetStore.cpp @@ -151,7 +151,7 @@ void RemoteBrokerOffsetStore::updateConsumeOffsetToBroker(const MQMessageQueue& if (findBrokerResult == nullptr) { client_instance_->updateTopicRouteInfoFromNameServer(mq.topic()); - findBrokerResult.reset(client_instance_->findBrokerAddressInAdmin(mq.broker_name())); + findBrokerResult = client_instance_->findBrokerAddressInAdmin(mq.broker_name()); } if (findBrokerResult != nullptr) { @@ -177,7 +177,7 @@ int64_t RemoteBrokerOffsetStore::fetchConsumeOffsetFromBroker(const MQMessageQue if (findBrokerResult == nullptr) { client_instance_->updateTopicRouteInfoFromNameServer(mq.topic()); - findBrokerResult.reset(client_instance_->findBrokerAddressInAdmin(mq.broker_name())); + findBrokerResult = client_instance_->findBrokerAddressInAdmin(mq.broker_name()); } if (findBrokerResult != nullptr) { diff --git a/src/io/ByteBuffer.cpp b/src/io/ByteBuffer.cpp index f12bd7258..01216563a 100644 --- a/src/io/ByteBuffer.cpp +++ b/src/io/ByteBuffer.cpp @@ -22,16 +22,16 @@ namespace rocketmq { -ByteBuffer* ByteBuffer::allocate(int32_t capacity) { +std::unique_ptr ByteBuffer::allocate(int32_t capacity) { if (capacity < 0) { throw std::invalid_argument(""); } - return new DefaultByteBuffer(capacity, capacity); + return std::unique_ptr(new DefaultByteBuffer(capacity, capacity)); } -ByteBuffer* ByteBuffer::wrap(ByteArrayRef array, int32_t offset, int32_t length) { +std::unique_ptr ByteBuffer::wrap(ByteArrayRef array, int32_t offset, int32_t length) { try { - return new DefaultByteBuffer(std::move(array), offset, length); + return std::unique_ptr(new DefaultByteBuffer(std::move(array), offset, length)); } catch (const std::exception& x) { throw std::runtime_error("IndexOutOfBoundsException"); } diff --git a/src/io/ByteBuffer.hpp b/src/io/ByteBuffer.hpp index 5a302500b..4e3ea0481 100644 --- a/src/io/ByteBuffer.hpp +++ b/src/io/ByteBuffer.hpp @@ -19,18 +19,18 @@ #include // std::stringstream -#include "ByteArray.h" #include "Buffer.hpp" +#include "ByteArray.h" #include "ByteOrder.h" namespace rocketmq { class ByteBuffer : public Buffer { public: - static ByteBuffer* allocate(int32_t capacity); + static std::unique_ptr allocate(int32_t capacity); - static ByteBuffer* wrap(ByteArrayRef array, int32_t offset, int32_t length); - static ByteBuffer* wrap(ByteArrayRef array) { return wrap(array, 0, array->size()); } + static std::unique_ptr wrap(ByteArrayRef array, int32_t offset, int32_t length); + static std::unique_ptr wrap(ByteArrayRef array) { return wrap(array, 0, array->size()); } protected: ByteBuffer(int32_t mark, int32_t pos, int32_t lim, int32_t cap, ByteArrayRef byte_array, int32_t offset) @@ -46,9 +46,9 @@ class ByteBuffer : public Buffer { virtual ~ByteBuffer() = default; public: - virtual ByteBuffer* slice() = 0; - virtual ByteBuffer* duplicate() = 0; - virtual ByteBuffer* asReadOnlyBuffer() = 0; + virtual std::unique_ptr slice() = 0; + virtual std::unique_ptr duplicate() = 0; + virtual std::unique_ptr asReadOnlyBuffer() = 0; // get/put routine // ====================== diff --git a/src/io/DefaultByteBuffer.hpp b/src/io/DefaultByteBuffer.hpp index ca740bab9..55b225d7a 100644 --- a/src/io/DefaultByteBuffer.hpp +++ b/src/io/DefaultByteBuffer.hpp @@ -20,6 +20,7 @@ #include // std::memcpy #include // std::move +#include // std::unique_ptr #include // std::type_index #include "ByteBuffer.hpp" @@ -38,17 +39,19 @@ class DefaultByteBuffer : public ByteBuffer { : ByteBuffer(mark, pos, lim, cap, std::move(buf), off) {} public: - ByteBuffer* slice() override { - return new DefaultByteBuffer(byte_array_, -1, 0, remaining(), remaining(), position() + offset_); + std::unique_ptr slice() override { + return std::unique_ptr( + new DefaultByteBuffer(byte_array_, -1, 0, remaining(), remaining(), position() + offset_)); } - ByteBuffer* duplicate() override { - return new DefaultByteBuffer(byte_array_, mark_value(), position(), limit(), capacity(), offset_); + std::unique_ptr duplicate() override { + return std::unique_ptr( + new DefaultByteBuffer(byte_array_, mark_value(), position(), limit(), capacity(), offset_)); } - ByteBuffer* asReadOnlyBuffer() override { + std::unique_ptr asReadOnlyBuffer() override { // return new HeapByteBufferR(byte_array_, mark_value(), position(), limit(), capacity(), offset_); - return nullptr; + return std::unique_ptr(); } char get() override { return (*byte_array_)[ix(nextGetIndex())]; } diff --git a/src/message/MessageClientIDSetter.cpp b/src/message/MessageClientIDSetter.cpp index 5560ba1e2..5dfba1c6f 100644 --- a/src/message/MessageClientIDSetter.cpp +++ b/src/message/MessageClientIDSetter.cpp @@ -37,7 +37,7 @@ MessageClientIDSetter::MessageClientIDSetter() { std::unique_ptr buffer; sockaddr* addr = GetSelfIP(); if (addr != nullptr) { - buffer.reset(ByteBuffer::allocate(SockaddrSize(addr) + 2 + 4)); + buffer = ByteBuffer::allocate(SockaddrSize(addr) + 2 + 4); if (addr->sa_family == AF_INET) { auto* sin = (struct sockaddr_in*)addr; buffer->put(ByteArray(reinterpret_cast(&sin->sin_addr), kIPv4AddrSize)); @@ -49,7 +49,7 @@ MessageClientIDSetter::MessageClientIDSetter() { } } if (buffer == nullptr) { - buffer.reset(ByteBuffer::allocate(4 + 2 + 4)); + buffer = ByteBuffer::allocate(4 + 2 + 4); buffer->putInt(UtilAll::currentTimeMillis()); } buffer->putShort(UtilAll::getProcessId()); diff --git a/src/producer/DefaultMQProducerImpl.cpp b/src/producer/DefaultMQProducerImpl.cpp index 0105bd6c0..9e9ecc286 100644 --- a/src/producer/DefaultMQProducerImpl.cpp +++ b/src/producer/DefaultMQProducerImpl.cpp @@ -612,10 +612,10 @@ void DefaultMQProducerImpl::prepareSendRequest(Message& msg, long timeout) { } } -SendResult* DefaultMQProducerImpl::sendDefaultImpl(MessagePtr msg, - CommunicationMode communicationMode, - SendCallback* sendCallback, - long timeout) { +std::unique_ptr DefaultMQProducerImpl::sendDefaultImpl(MessagePtr msg, + CommunicationMode communicationMode, + SendCallback* sendCallback, + long timeout) { Validators::checkMessage(*msg, dynamic_cast(client_config_.get())->max_message_size()); uint64_t beginTimestampFirst = UtilAll::currentTimeMillis(); @@ -647,8 +647,7 @@ SendResult* DefaultMQProducerImpl::sendDefaultImpl(MessagePtr msg, break; } - sendResult.reset( - sendKernelImpl(msg, mq, communicationMode, sendCallback, topicPublishInfo, timeout - costTime)); + sendResult = sendKernelImpl(msg, mq, communicationMode, sendCallback, topicPublishInfo, timeout - costTime); endTimestamp = UtilAll::currentTimeMillis(); updateFaultItem(mq.broker_name(), endTimestamp - beginTimestampPrev, false); switch (communicationMode) { @@ -664,7 +663,7 @@ SendResult* DefaultMQProducerImpl::sendDefaultImpl(MessagePtr msg, } } - return sendResult.release(); + return sendResult; default: break; } @@ -679,7 +678,7 @@ SendResult* DefaultMQProducerImpl::sendDefaultImpl(MessagePtr msg, } // end of for if (sendResult != nullptr) { - return sendResult.release(); + return sendResult; } std::string info = "Send [" + UtilAll::to_string(times) + "] times, still failed, cost [" + @@ -700,12 +699,12 @@ void DefaultMQProducerImpl::updateFaultItem(const std::string& brokerName, const mq_fault_strategy_->updateFaultItem(brokerName, currentLatency, isolation); } -SendResult* DefaultMQProducerImpl::sendKernelImpl(MessagePtr msg, - const MQMessageQueue& mq, - CommunicationMode communicationMode, - SendCallback* sendCallback, - TopicPublishInfoPtr topicPublishInfo, - long timeout) { +std::unique_ptr DefaultMQProducerImpl::sendKernelImpl(MessagePtr msg, + const MQMessageQueue& mq, + CommunicationMode communicationMode, + SendCallback* sendCallback, + TopicPublishInfoPtr topicPublishInfo, + long timeout) { uint64_t beginStartTime = UtilAll::currentTimeMillis(); std::string brokerAddr = client_instance_->findBrokerAddressInPublish(mq.broker_name()); if (brokerAddr.empty()) { @@ -763,7 +762,7 @@ SendResult* DefaultMQProducerImpl::sendKernelImpl(MessagePtr msg, } } - SendResult* sendResult = nullptr; + std::unique_ptr sendResult; switch (communicationMode) { case ASYNC: { long costTimeAsync = UtilAll::currentTimeMillis() - beginStartTime; @@ -825,12 +824,12 @@ bool DefaultMQProducerImpl::tryToCompressMessage(Message& msg) { return false; } -SendResult* DefaultMQProducerImpl::sendSelectImpl(MessagePtr msg, - MessageQueueSelector* selector, - void* arg, - CommunicationMode communicationMode, - SendCallback* sendCallback, - long timeout) { +std::unique_ptr DefaultMQProducerImpl::sendSelectImpl(MessagePtr msg, + MessageQueueSelector* selector, + void* arg, + CommunicationMode communicationMode, + SendCallback* sendCallback, + long timeout) { auto beginStartTime = UtilAll::currentTimeMillis(); Validators::checkMessage(*msg, dynamic_cast(client_config_.get())->max_message_size()); @@ -869,7 +868,9 @@ TransactionListener* DefaultMQProducerImpl::getCheckListener() { return nullptr; }; -TransactionSendResult* DefaultMQProducerImpl::sendMessageInTransactionImpl(MessagePtr msg, void* arg, long timeout) { +std::unique_ptr DefaultMQProducerImpl::sendMessageInTransactionImpl(MessagePtr msg, + void* arg, + long timeout) { auto* transactionListener = getCheckListener(); if (nullptr == transactionListener) { THROW_MQEXCEPTION(MQClientException, "transactionListener is null", -1); @@ -879,7 +880,7 @@ TransactionSendResult* DefaultMQProducerImpl::sendMessageInTransactionImpl(Messa MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_TRANSACTION_PREPARED, "true"); MessageAccessor::putProperty(*msg, MQMessageConst::PROPERTY_PRODUCER_GROUP, client_config_->group_name()); try { - sendResult.reset(sendDefaultImpl(msg, SYNC, nullptr, timeout)); + sendResult = sendDefaultImpl(msg, SYNC, nullptr, timeout); } catch (MQException& e) { THROW_MQEXCEPTION(MQClientException, "send message Exception", -1); } @@ -923,7 +924,7 @@ TransactionSendResult* DefaultMQProducerImpl::sendMessageInTransactionImpl(Messa } // FIXME: setTransactionId will cause OOM? - TransactionSendResult* transactionSendResult = new TransactionSendResult(*sendResult.get()); + std::unique_ptr transactionSendResult(new TransactionSendResult(*sendResult)); transactionSendResult->set_transaction_id(msg->transaction_id()); transactionSendResult->set_local_transaction_state(localTransactionState); return transactionSendResult; diff --git a/src/producer/DefaultMQProducerImpl.h b/src/producer/DefaultMQProducerImpl.h index 57eef515d..3a3073cad 100644 --- a/src/producer/DefaultMQProducerImpl.h +++ b/src/producer/DefaultMQProducerImpl.h @@ -127,28 +127,28 @@ class DefaultMQProducerImpl : public std::enable_shared_from_this topicPublishInfo, - long timeout); + std::unique_ptr sendDefaultImpl(MessagePtr msg, + CommunicationMode communicationMode, + SendCallback* sendCallback, + long timeout); + + std::unique_ptr sendKernelImpl(MessagePtr msg, + const MQMessageQueue& mq, + CommunicationMode communicationMode, + SendCallback* sendCallback, + std::shared_ptr topicPublishInfo, + long timeout); bool tryToCompressMessage(Message& msg); - SendResult* sendSelectImpl(MessagePtr msg, - MessageQueueSelector* selector, - void* arg, - CommunicationMode communicationMode, - SendCallback* sendCallback, - long timeout); + std::unique_ptr sendSelectImpl(MessagePtr msg, + MessageQueueSelector* selector, + void* arg, + CommunicationMode communicationMode, + SendCallback* sendCallback, + long timeout); - TransactionSendResult* sendMessageInTransactionImpl(MessagePtr msg, void* arg, long timeout); + std::unique_ptr sendMessageInTransactionImpl(MessagePtr msg, void* arg, long timeout); void endTransaction(SendResult& sendResult, LocalTransactionState localTransactionState, diff --git a/src/protocol/RemotingCommand.cpp b/src/protocol/RemotingCommand.cpp index 4e6284f9c..02038fe63 100644 --- a/src/protocol/RemotingCommand.cpp +++ b/src/protocol/RemotingCommand.cpp @@ -22,8 +22,8 @@ #include // std::atomic #include // std::numeric_limits -#include "ByteOrder.h" #include "ByteBuffer.hpp" +#include "ByteOrder.h" #include "Logging.h" #include "MQVersion.h" #include "RemotingSerializable.h" @@ -133,7 +133,7 @@ static inline int32_t getHeaderLength(int32_t length) { return length & 0x00FFFFFF; } -static RemotingCommand* Decode(ByteBuffer& byteBuffer, bool hasPackageLength) { +static std::unique_ptr Decode(ByteBuffer& byteBuffer, bool hasPackageLength) { // decode package: [4 bytes(packageLength) +] 4 bytes(headerLength) + header + body int32_t length = byteBuffer.limit(); @@ -196,10 +196,10 @@ static RemotingCommand* Decode(ByteBuffer& byteBuffer, bool hasPackageLength) { LOG_DEBUG_NEW("code:{}, language:{}, version:{}, opaque:{}, flag:{}, remark:{}, headLen:{}, bodyLen:{}", code, language, version, opaque, flag, remark, headerLength, bodyLength); - return cmd.release(); + return cmd; } -RemotingCommand* RemotingCommand::Decode(ByteArrayRef array, bool hasPackageLength) { +std::unique_ptr RemotingCommand::Decode(ByteArrayRef array, bool hasPackageLength) { std::unique_ptr byteBuffer(ByteBuffer::wrap(std::move(array))); return rocketmq::Decode(*byteBuffer, hasPackageLength); } diff --git a/src/protocol/TopicList.h b/src/protocol/TopicList.h index bbcb7ccf6..af004c08d 100644 --- a/src/protocol/TopicList.h +++ b/src/protocol/TopicList.h @@ -26,7 +26,7 @@ namespace rocketmq { class TopicList { public: - static TopicList* Decode(const ByteArray& mem) { return new TopicList(); } + static std::unique_ptr Decode(const ByteArray& mem) { return std::unique_ptr(new TopicList()); } private: std::vector topic_list_; diff --git a/src/protocol/body/LockBatchResponseBody.hpp b/src/protocol/body/LockBatchResponseBody.hpp index af16bf2e4..f443f884f 100644 --- a/src/protocol/body/LockBatchResponseBody.hpp +++ b/src/protocol/body/LockBatchResponseBody.hpp @@ -28,7 +28,7 @@ namespace rocketmq { class LockBatchResponseBody { public: - static LockBatchResponseBody* Decode(const ByteArray& bodyData) { + static std::unique_ptr Decode(const ByteArray& bodyData) { Json::Value root = RemotingSerializable::fromJson(bodyData); auto& mqs = root["lockOKMQSet"]; std::unique_ptr body(new LockBatchResponseBody()); @@ -37,7 +37,7 @@ class LockBatchResponseBody { LOG_INFO_NEW("LockBatchResponseBody MQ:{}", mq.toString()); body->lock_ok_mq_set().push_back(std::move(mq)); } - return body.release(); + return body; } public: diff --git a/src/protocol/body/ResetOffsetBody.hpp b/src/protocol/body/ResetOffsetBody.hpp index 157e567f5..f5a5bfc11 100644 --- a/src/protocol/body/ResetOffsetBody.hpp +++ b/src/protocol/body/ResetOffsetBody.hpp @@ -26,7 +26,7 @@ namespace rocketmq { class ResetOffsetBody { public: - static ResetOffsetBody* Decode(const ByteArray& bodyData) { + static std::unique_ptr Decode(const ByteArray& bodyData) { // FIXME: object as key Json::Value root = RemotingSerializable::fromJson(bodyData); auto& qds = root["offsetTable"]; @@ -38,7 +38,7 @@ class ResetOffsetBody { int64_t offset = qds[member].asInt64(); body->offset_table_.emplace(std::move(mq), offset); } - return body.release(); + return body; } public: diff --git a/src/protocol/body/TopicRouteData.hpp b/src/protocol/body/TopicRouteData.hpp index 38e188975..887bcc383 100644 --- a/src/protocol/body/TopicRouteData.hpp +++ b/src/protocol/body/TopicRouteData.hpp @@ -106,7 +106,7 @@ typedef std::shared_ptr TopicRouteDataPtr; class TopicRouteData { public: - static TopicRouteData* Decode(const ByteArray& bodyData) { + static std::unique_ptr Decode(const ByteArray& bodyData) { Json::Value root = RemotingSerializable::fromJson(bodyData); std::unique_ptr trd(new TopicRouteData()); @@ -136,7 +136,7 @@ class TopicRouteData { } sort(trd->broker_datas().begin(), trd->broker_datas().end()); - return trd.release(); + return trd; } /** diff --git a/src/protocol/header/CommandHeader.cpp b/src/protocol/header/CommandHeader.cpp index 4a7e7cac4..b75757c72 100644 --- a/src/protocol/header/CommandHeader.cpp +++ b/src/protocol/header/CommandHeader.cpp @@ -95,7 +95,7 @@ void CreateTopicRequestHeader::SetDeclaredFieldOfCommandHeader(std::map CheckTransactionStateRequestHeader::Decode( std::map& extFields) { std::unique_ptr header(new CheckTransactionStateRequestHeader()); header->tranStateTableOffset = std::stoll(extFields.at("tranStateTableOffset")); @@ -116,7 +116,7 @@ CheckTransactionStateRequestHeader* CheckTransactionStateRequestHeader::Decode( header->offsetMsgId = it->second; } - return header.release(); + return header; } void CheckTransactionStateRequestHeader::SetDeclaredFieldOfCommandHeader( @@ -246,8 +246,9 @@ void SendMessageRequestHeader::setReconsumeTimes(int _reconsumeTimes) { // SendMessageRequestHeaderV2 //###################################### -SendMessageRequestHeaderV2* SendMessageRequestHeaderV2::createSendMessageRequestHeaderV2(SendMessageRequestHeader* v1) { - SendMessageRequestHeaderV2* v2 = new SendMessageRequestHeaderV2(); +std::unique_ptr SendMessageRequestHeaderV2::createSendMessageRequestHeaderV2( + SendMessageRequestHeader* v1) { + std::unique_ptr v2(new SendMessageRequestHeaderV2()); v2->a = v1->producerGroup; v2->b = v1->topic; v2->c = v1->defaultTopic; @@ -312,7 +313,8 @@ void SendMessageRequestHeaderV2::SetDeclaredFieldOfCommandHeader(std::map& extFields) { +std::unique_ptr SendMessageResponseHeader::Decode( + std::map& extFields) { std::unique_ptr header(new SendMessageResponseHeader()); header->msgId = extFields.at("msgId"); header->queueId = std::stoi(extFields.at("queueId")); @@ -323,7 +325,7 @@ SendMessageResponseHeader* SendMessageResponseHeader::Decode(std::maptransactionId = it->second; } - return header.release(); + return header; } void SendMessageResponseHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { @@ -378,13 +380,14 @@ void PullMessageRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& extFields) { +std::unique_ptr PullMessageResponseHeader::Decode( + std::map& extFields) { std::unique_ptr header(new PullMessageResponseHeader()); header->suggestWhichBrokerId = std::stoll(extFields.at("suggestWhichBrokerId")); header->nextBeginOffset = std::stoll(extFields.at("nextBeginOffset")); header->minOffset = std::stoll(extFields.at("minOffset")); header->maxOffset = std::stoll(extFields.at("maxOffset")); - return header.release(); + return header; } void PullMessageResponseHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { @@ -422,10 +425,11 @@ void GetMinOffsetRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& extFields) { +std::unique_ptr GetMinOffsetResponseHeader::Decode( + std::map& extFields) { std::unique_ptr header(new GetMinOffsetResponseHeader()); header->offset = std::stoll(extFields.at("offset")); - return header.release(); + return header; } void GetMinOffsetResponseHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { @@ -451,10 +455,11 @@ void GetMaxOffsetRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& extFields) { +std::unique_ptr GetMaxOffsetResponseHeader::Decode( + std::map& extFields) { std::unique_ptr header(new GetMaxOffsetResponseHeader()); header->offset = std::stoll(extFields.at("offset")); - return header.release(); + return header; } void GetMaxOffsetResponseHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { @@ -482,10 +487,11 @@ void SearchOffsetRequestHeader::SetDeclaredFieldOfCommandHeader(std::map& extFields) { +std::unique_ptr SearchOffsetResponseHeader::Decode( + std::map& extFields) { std::unique_ptr header(new SearchOffsetResponseHeader()); header->offset = std::stoll(extFields.at("offset")); - return header.release(); + return header; } void SearchOffsetResponseHeader::SetDeclaredFieldOfCommandHeader(std::map& requestMap) { @@ -524,11 +530,11 @@ void GetEarliestMsgStoretimeRequestHeader::SetDeclaredFieldOfCommandHeader( // GetEarliestMsgStoretimeResponseHeader //###################################### -GetEarliestMsgStoretimeResponseHeader* GetEarliestMsgStoretimeResponseHeader::Decode( +std::unique_ptr GetEarliestMsgStoretimeResponseHeader::Decode( std::map& extFields) { std::unique_ptr header(new GetEarliestMsgStoretimeResponseHeader()); header->timestamp = std::stoll(extFields.at("timestamp")); - return header.release(); + return header; } void GetEarliestMsgStoretimeResponseHeader::SetDeclaredFieldOfCommandHeader( @@ -570,11 +576,11 @@ void QueryConsumerOffsetRequestHeader::SetDeclaredFieldOfCommandHeader(std::map< // QueryConsumerOffsetResponseHeader //###################################### -QueryConsumerOffsetResponseHeader* QueryConsumerOffsetResponseHeader::Decode( +std::unique_ptr QueryConsumerOffsetResponseHeader::Decode( std::map& extFields) { std::unique_ptr header(new QueryConsumerOffsetResponseHeader()); header->offset = std::stoll(extFields.at("offset")); - return header.release(); + return header; } void QueryConsumerOffsetResponseHeader::SetDeclaredFieldOfCommandHeader( @@ -642,14 +648,15 @@ void ConsumerSendMsgBackRequestHeader::SetDeclaredFieldOfCommandHeader(std::map< // GetConsumerListByGroupResponseBody //###################################### -GetConsumerListByGroupResponseBody* GetConsumerListByGroupResponseBody::Decode(const ByteArray& bodyData) { +std::unique_ptr GetConsumerListByGroupResponseBody::Decode( + const ByteArray& bodyData) { Json::Value root = RemotingSerializable::fromJson(bodyData); auto& ids = root["consumerIdList"]; std::unique_ptr body(new GetConsumerListByGroupResponseBody()); for (unsigned int i = 0; i < ids.size(); i++) { body->consumerIdList.push_back(ids[i].asString()); } - return body.release(); + return body; } void GetConsumerListByGroupResponseBody::SetDeclaredFieldOfCommandHeader( @@ -659,7 +666,8 @@ void GetConsumerListByGroupResponseBody::SetDeclaredFieldOfCommandHeader( // ResetOffsetRequestHeader //###################################### -ResetOffsetRequestHeader* ResetOffsetRequestHeader::Decode(std::map& extFields) { +std::unique_ptr ResetOffsetRequestHeader::Decode( + std::map& extFields) { std::unique_ptr header(new ResetOffsetRequestHeader()); header->topic = extFields.at("topic"); header->group = extFields.at("group"); @@ -667,7 +675,7 @@ ResetOffsetRequestHeader* ResetOffsetRequestHeader::Decode(std::mapisForce = UtilAll::stob(extFields.at("isForce")); LOG_INFO_NEW("topic:{}, group:{}, timestamp:{}, isForce:{}", header->topic, header->group, header->timestamp, header->isForce); - return header.release(); + return header; } void ResetOffsetRequestHeader::setTopic(const std::string& tmp) { @@ -706,7 +714,7 @@ const bool ResetOffsetRequestHeader::getForceFlag() const { // GetConsumerRunningInfoRequestHeader //###################################### -GetConsumerRunningInfoRequestHeader* GetConsumerRunningInfoRequestHeader::Decode( +std::unique_ptr GetConsumerRunningInfoRequestHeader::Decode( std::map& extFields) { std::unique_ptr header(new GetConsumerRunningInfoRequestHeader()); header->consumerGroup = extFields.at("consumerGroup"); @@ -714,7 +722,7 @@ GetConsumerRunningInfoRequestHeader* GetConsumerRunningInfoRequestHeader::Decode header->jstackEnable = UtilAll::stob(extFields.at("jstackEnable")); LOG_INFO("consumerGroup:%s, clientId:%s, jstackEnable:%d", header->consumerGroup.c_str(), header->clientId.c_str(), header->jstackEnable); - return header.release(); + return header; } void GetConsumerRunningInfoRequestHeader::Encode(Json::Value& extFields) { @@ -758,11 +766,11 @@ void GetConsumerRunningInfoRequestHeader::setJstackEnable(const bool& jstackEnab // NotifyConsumerIdsChangedRequestHeader //###################################### -NotifyConsumerIdsChangedRequestHeader* NotifyConsumerIdsChangedRequestHeader::Decode( +std::unique_ptr NotifyConsumerIdsChangedRequestHeader::Decode( std::map& extFields) { std::unique_ptr header(new NotifyConsumerIdsChangedRequestHeader()); header->consumerGroup = extFields.at("consumerGroup"); - return header.release(); + return header; } const std::string& NotifyConsumerIdsChangedRequestHeader::getConsumerGroup() const { diff --git a/src/protocol/header/CommandHeader.h b/src/protocol/header/CommandHeader.h index 31c10eb8f..8963510f6 100644 --- a/src/protocol/header/CommandHeader.h +++ b/src/protocol/header/CommandHeader.h @@ -17,6 +17,7 @@ #ifndef ROCKETMQ_PROTOCOL_COMMANDHEADER_H_ #define ROCKETMQ_PROTOCOL_COMMANDHEADER_H_ +#include // std::unique_ptr #include // std::vector #include "ByteArray.h" @@ -71,7 +72,7 @@ class CheckTransactionStateRequestHeader : public CommandCustomHeader { public: CheckTransactionStateRequestHeader() : tranStateTableOffset(0), commitLogOffset(0) {} - static CheckTransactionStateRequestHeader* Decode(std::map& extFields); + static std::unique_ptr Decode(std::map& extFields); void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; std::string toString() const; @@ -139,7 +140,7 @@ class SendMessageRequestHeader : public CommandCustomHeader { class SendMessageRequestHeaderV2 : public CommandCustomHeader { public: - static SendMessageRequestHeaderV2* createSendMessageRequestHeaderV2(SendMessageRequestHeader* v1); + static std::unique_ptr createSendMessageRequestHeaderV2(SendMessageRequestHeader* v1); void Encode(Json::Value& outData) override; void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; @@ -167,7 +168,7 @@ class SendMessageResponseHeader : public CommandCustomHeader { public: SendMessageResponseHeader() : queueId(0), queueOffset(0) {} - static SendMessageResponseHeader* Decode(std::map& extFields); + static std::unique_ptr Decode(std::map& extFields); void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: @@ -209,7 +210,7 @@ class PullMessageResponseHeader : public CommandCustomHeader { public: PullMessageResponseHeader() : suggestWhichBrokerId(0), nextBeginOffset(0), minOffset(0), maxOffset(0) {} - static PullMessageResponseHeader* Decode(std::map& extFields); + static std::unique_ptr Decode(std::map& extFields); void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: @@ -241,7 +242,7 @@ class GetMinOffsetResponseHeader : public CommandCustomHeader { public: GetMinOffsetResponseHeader() : offset(0) {} - static GetMinOffsetResponseHeader* Decode(std::map& extFields); + static std::unique_ptr Decode(std::map& extFields); void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: @@ -264,7 +265,7 @@ class GetMaxOffsetResponseHeader : public CommandCustomHeader { public: GetMaxOffsetResponseHeader() : offset(0) {} - static GetMaxOffsetResponseHeader* Decode(std::map& extFields); + static std::unique_ptr Decode(std::map& extFields); void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: @@ -288,7 +289,7 @@ class SearchOffsetResponseHeader : public CommandCustomHeader { public: SearchOffsetResponseHeader() : offset(0) {} - static SearchOffsetResponseHeader* Decode(std::map& extFields); + static std::unique_ptr Decode(std::map& extFields); void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: @@ -322,7 +323,7 @@ class GetEarliestMsgStoretimeResponseHeader : public CommandCustomHeader { public: GetEarliestMsgStoretimeResponseHeader() : timestamp(0) {} - static GetEarliestMsgStoretimeResponseHeader* Decode(std::map& extFields); + static std::unique_ptr Decode(std::map& extFields); void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: @@ -355,7 +356,7 @@ class QueryConsumerOffsetResponseHeader : public CommandCustomHeader { public: QueryConsumerOffsetResponseHeader() : offset(0) {} - static QueryConsumerOffsetResponseHeader* Decode(std::map& extFields); + static std::unique_ptr Decode(std::map& extFields); void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: @@ -395,7 +396,7 @@ class ConsumerSendMsgBackRequestHeader : public CommandCustomHeader { class GetConsumerListByGroupResponseBody : public CommandCustomHeader { public: - static GetConsumerListByGroupResponseBody* Decode(const ByteArray& bodyData); + static std::unique_ptr Decode(const ByteArray& bodyData); void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; public: @@ -406,7 +407,7 @@ class ResetOffsetRequestHeader : public CommandCustomHeader { public: ResetOffsetRequestHeader() : timestamp(0), isForce(false) {} - static ResetOffsetRequestHeader* Decode(std::map& extFields); + static std::unique_ptr Decode(std::map& extFields); const std::string& getTopic() const; void setTopic(const std::string& tmp); @@ -431,7 +432,7 @@ class GetConsumerRunningInfoRequestHeader : public CommandCustomHeader { public: GetConsumerRunningInfoRequestHeader() : jstackEnable(false) {} - static GetConsumerRunningInfoRequestHeader* Decode(std::map& extFields); + static std::unique_ptr Decode(std::map& extFields); void Encode(Json::Value& extFields) override; void SetDeclaredFieldOfCommandHeader(std::map& requestMap) override; @@ -452,7 +453,7 @@ class GetConsumerRunningInfoRequestHeader : public CommandCustomHeader { class NotifyConsumerIdsChangedRequestHeader : public CommandCustomHeader { public: - static NotifyConsumerIdsChangedRequestHeader* Decode(std::map& extFields); + static std::unique_ptr Decode(std::map& extFields); const std::string& getConsumerGroup() const; void setConsumerGroup(const std::string& tmp); diff --git a/src/protocol/header/ReplyMessageRequestHeader.hpp b/src/protocol/header/ReplyMessageRequestHeader.hpp index 3aaab7ba5..bfeb35a9d 100644 --- a/src/protocol/header/ReplyMessageRequestHeader.hpp +++ b/src/protocol/header/ReplyMessageRequestHeader.hpp @@ -26,7 +26,7 @@ namespace rocketmq { class ReplyMessageRequestHeader : public CommandCustomHeader { public: - static ReplyMessageRequestHeader* Decode(std::map& extFields) { + static std::unique_ptr Decode(std::map& extFields) { std::unique_ptr header(new ReplyMessageRequestHeader()); header->producer_group_ = extFields.at("producerGroup"); @@ -61,7 +61,7 @@ class ReplyMessageRequestHeader : public CommandCustomHeader { header->store_host_ = extFields.at("storeHost"); header->store_timestamp_ = std::stoll(extFields.at("storeTimestamp")); - return header.release(); + return header; } public: diff --git a/src/transport/RequestProcessor.h b/src/transport/RequestProcessor.h index 2e6239178..15b58619a 100644 --- a/src/transport/RequestProcessor.h +++ b/src/transport/RequestProcessor.h @@ -26,7 +26,7 @@ class RequestProcessor { public: virtual ~RequestProcessor() = default; - virtual RemotingCommand* processRequest(TcpTransportPtr channel, RemotingCommand* request) = 0; + virtual std::unique_ptr processRequest(TcpTransportPtr channel, RemotingCommand* request) = 0; }; } // namespace rocketmq diff --git a/src/transport/TcpRemotingClient.cpp b/src/transport/TcpRemotingClient.cpp index 655a8110f..c524cb7eb 100644 --- a/src/transport/TcpRemotingClient.cpp +++ b/src/transport/TcpRemotingClient.cpp @@ -564,7 +564,7 @@ void TcpRemotingClient::messageReceived(ByteArrayRef msg, TcpTransportPtr channe void TcpRemotingClient::processMessageReceived(ByteArrayRef msg, TcpTransportPtr channel) { std::unique_ptr cmd; try { - cmd.reset(RemotingCommand::Decode(std::move(msg))); + cmd = RemotingCommand::Decode(std::move(msg)); } catch (...) { LOG_ERROR_NEW("processMessageReceived error"); return; @@ -635,7 +635,7 @@ void TcpRemotingClient::processRequestCommand(std::unique_ptr r auto* processor = it->second; doBeforeRpcHooks(channel->getPeerAddrAndPort(), *requestCommand, false); - response.reset(processor->processRequest(channel, requestCommand.get())); + response = processor->processRequest(channel, requestCommand.get()); doAfterRpcHooks(channel->getPeerAddrAndPort(), *response, response.get(), true); } catch (std::exception& e) { LOG_ERROR_NEW("process request exception. {}", e.what()); diff --git a/test/src/protocol/RemotingCommandTest.cpp b/test/src/protocol/RemotingCommandTest.cpp index 42ee77168..c5d062769 100644 --- a/test/src/protocol/RemotingCommandTest.cpp +++ b/test/src/protocol/RemotingCommandTest.cpp @@ -156,7 +156,7 @@ TEST(RemotingCommandTest, EncodeAndDecode) { remotingCommand2.set_body("123123"); package = remotingCommand2.encode(); - decodeRemtingCommand.reset(RemotingCommand::Decode(package, true)); + decodeRemtingCommand = RemotingCommand::Decode(package, true); auto* header = decodeRemtingCommand->decodeCommandCustomHeader(); EXPECT_EQ(requestHeader->getClientId(), header->getClientId()); From 342815dac52aaef89b2dca0dfa3489c9bd7ab760 Mon Sep 17 00:00:00 2001 From: James Yin Date: Wed, 7 Apr 2021 12:42:47 +0800 Subject: [PATCH 59/62] fix: IPPortToSockaddr for ipv6 --- src/transport/SocketUtil.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transport/SocketUtil.cpp b/src/transport/SocketUtil.cpp index 230db1a8e..d7de908d9 100644 --- a/src/transport/SocketUtil.cpp +++ b/src/transport/SocketUtil.cpp @@ -56,7 +56,7 @@ sockaddr* IPPortToSockaddr(const ByteArray& ip, uint16_t port) { sin->sin_port = htons(port); std::memcpy(&sin->sin_addr, ip.array(), kIPv4AddrSize); } else if (ip.size() == kIPv6AddrSize) { - auto* sin6 = reinterpret_cast(&ss); + auto* sin6 = reinterpret_cast(ss); sin6->sin6_family = AF_INET6; sin6->sin6_port = htons(port); std::memcpy(&sin6->sin6_addr, ip.array(), kIPv6AddrSize); From 5870109ca26be2dc5fd1a9a6e2174b5fe8e84378 Mon Sep 17 00:00:00 2001 From: James Yin Date: Wed, 7 Apr 2021 12:44:41 +0800 Subject: [PATCH 60/62] fix: decode storehost field --- src/message/MessageDecoder.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/message/MessageDecoder.cpp b/src/message/MessageDecoder.cpp index 08df4070a..675bac77b 100644 --- a/src/message/MessageDecoder.cpp +++ b/src/message/MessageDecoder.cpp @@ -136,9 +136,9 @@ MessageExtPtr MessageDecoder::decode(ByteBuffer& byteBuffer, bool readBody, bool msgExt->set_store_timestamp(storeTimestamp); // 12 STOREHOST - int storehostIPLength = (sysFlag & MessageSysFlag::STOREHOST_V6_FLAG) == 0 ? kIPv4AddrSize : kIPv6AddrSize; - ByteArray storeHost(bornHostLength); - byteBuffer.get(storeHost, 0, storehostIPLength); + int storeHostLength = (sysFlag & MessageSysFlag::STOREHOST_V6_FLAG) == 0 ? kIPv4AddrSize : kIPv6AddrSize; + ByteArray storeHost(storeHostLength); + byteBuffer.get(storeHost, 0, storeHostLength); int32_t storePort = byteBuffer.getInt(); msgExt->set_store_host(IPPortToSockaddr(storeHost, storePort)); From 4860dd650b8f6a3ceb909d6ba5de1c97bab8599b Mon Sep 17 00:00:00 2001 From: James Yin Date: Wed, 7 Apr 2021 16:57:03 +0800 Subject: [PATCH 61/62] fix: return nullptr when decode message failed --- src/message/MessageDecoder.cpp | 214 +++++++++++++++++---------------- 1 file changed, 110 insertions(+), 104 deletions(-) diff --git a/src/message/MessageDecoder.cpp b/src/message/MessageDecoder.cpp index 675bac77b..fdceea278 100644 --- a/src/message/MessageDecoder.cpp +++ b/src/message/MessageDecoder.cpp @@ -17,6 +17,7 @@ #include "MessageDecoder.h" #include // std::move +#include // std::exception #include // std::stringstream #ifndef WIN32 @@ -87,119 +88,124 @@ MessageExtPtr MessageDecoder::decode(ByteBuffer& byteBuffer, bool readBody) { } MessageExtPtr MessageDecoder::decode(ByteBuffer& byteBuffer, bool readBody, bool deCompressBody, bool isClient) { - auto msgExt = isClient ? std::make_shared() : std::make_shared(); - - // 1 TOTALSIZE - int32_t storeSize = byteBuffer.getInt(); - msgExt->set_store_size(storeSize); - - // 2 MAGICCODE sizeof(int) - byteBuffer.getInt(); - - // 3 BODYCRC - int32_t bodyCRC = byteBuffer.getInt(); - msgExt->set_body_crc(bodyCRC); - - // 4 QUEUEID - int32_t queueId = byteBuffer.getInt(); - msgExt->set_queue_id(queueId); - - // 5 FLAG - int32_t flag = byteBuffer.getInt(); - msgExt->set_flag(flag); - - // 6 QUEUEOFFSET - int64_t queueOffset = byteBuffer.getLong(); - msgExt->set_queue_offset(queueOffset); - - // 7 PHYSICALOFFSET - int64_t physicOffset = byteBuffer.getLong(); - msgExt->set_commit_log_offset(physicOffset); - - // 8 SYSFLAG - int32_t sysFlag = byteBuffer.getInt(); - msgExt->set_sys_flag(sysFlag); - - // 9 BORNTIMESTAMP - int64_t bornTimeStamp = byteBuffer.getLong(); - msgExt->set_born_timestamp(bornTimeStamp); - - // 10 BORNHOST - int bornHostLength = (sysFlag & MessageSysFlag::BORNHOST_V6_FLAG) == 0 ? kIPv4AddrSize : kIPv6AddrSize; - ByteArray bornHost(bornHostLength); - byteBuffer.get(bornHost, 0, bornHostLength); - int32_t bornPort = byteBuffer.getInt(); - msgExt->set_born_host(IPPortToSockaddr(bornHost, bornPort)); - - // 11 STORETIMESTAMP - int64_t storeTimestamp = byteBuffer.getLong(); - msgExt->set_store_timestamp(storeTimestamp); - - // 12 STOREHOST - int storeHostLength = (sysFlag & MessageSysFlag::STOREHOST_V6_FLAG) == 0 ? kIPv4AddrSize : kIPv6AddrSize; - ByteArray storeHost(storeHostLength); - byteBuffer.get(storeHost, 0, storeHostLength); - int32_t storePort = byteBuffer.getInt(); - msgExt->set_store_host(IPPortToSockaddr(storeHost, storePort)); - - // 13 RECONSUMETIMES - int32_t reconsumeTimes = byteBuffer.getInt(); - msgExt->set_reconsume_times(reconsumeTimes); - - // 14 Prepared Transaction Offset - int64_t preparedTransactionOffset = byteBuffer.getLong(); - msgExt->set_prepared_transaction_offset(preparedTransactionOffset); - - // 15 BODY - int uncompress_failed = false; - int32_t bodyLen = byteBuffer.getInt(); - if (bodyLen > 0) { - if (readBody) { - ByteArray body(byteBuffer.array() + byteBuffer.arrayOffset() + byteBuffer.position(), bodyLen); - byteBuffer.position(byteBuffer.position() + bodyLen); - - // decompress body - if (deCompressBody && (sysFlag & MessageSysFlag::COMPRESSED_FLAG) == MessageSysFlag::COMPRESSED_FLAG) { - std::string origin_body; - if (UtilAll::inflate(body, origin_body)) { - msgExt->set_body(std::move(origin_body)); + try { + auto msgExt = isClient ? std::make_shared() : std::make_shared(); + + // 1 TOTALSIZE + int32_t storeSize = byteBuffer.getInt(); + msgExt->set_store_size(storeSize); + + // 2 MAGICCODE sizeof(int) + byteBuffer.getInt(); + + // 3 BODYCRC + int32_t bodyCRC = byteBuffer.getInt(); + msgExt->set_body_crc(bodyCRC); + + // 4 QUEUEID + int32_t queueId = byteBuffer.getInt(); + msgExt->set_queue_id(queueId); + + // 5 FLAG + int32_t flag = byteBuffer.getInt(); + msgExt->set_flag(flag); + + // 6 QUEUEOFFSET + int64_t queueOffset = byteBuffer.getLong(); + msgExt->set_queue_offset(queueOffset); + + // 7 PHYSICALOFFSET + int64_t physicOffset = byteBuffer.getLong(); + msgExt->set_commit_log_offset(physicOffset); + + // 8 SYSFLAG + int32_t sysFlag = byteBuffer.getInt(); + msgExt->set_sys_flag(sysFlag); + + // 9 BORNTIMESTAMP + int64_t bornTimeStamp = byteBuffer.getLong(); + msgExt->set_born_timestamp(bornTimeStamp); + + // 10 BORNHOST + int bornHostLength = (sysFlag & MessageSysFlag::BORNHOST_V6_FLAG) == 0 ? kIPv4AddrSize : kIPv6AddrSize; + ByteArray bornHost(bornHostLength); + byteBuffer.get(bornHost, 0, bornHostLength); + int32_t bornPort = byteBuffer.getInt(); + msgExt->set_born_host(IPPortToSockaddr(bornHost, bornPort)); + + // 11 STORETIMESTAMP + int64_t storeTimestamp = byteBuffer.getLong(); + msgExt->set_store_timestamp(storeTimestamp); + + // 12 STOREHOST + int storeHostLength = (sysFlag & MessageSysFlag::STOREHOST_V6_FLAG) == 0 ? kIPv4AddrSize : kIPv6AddrSize; + ByteArray storeHost(storeHostLength); + byteBuffer.get(storeHost, 0, storeHostLength); + int32_t storePort = byteBuffer.getInt(); + msgExt->set_store_host(IPPortToSockaddr(storeHost, storePort)); + + // 13 RECONSUMETIMES + int32_t reconsumeTimes = byteBuffer.getInt(); + msgExt->set_reconsume_times(reconsumeTimes); + + // 14 Prepared Transaction Offset + int64_t preparedTransactionOffset = byteBuffer.getLong(); + msgExt->set_prepared_transaction_offset(preparedTransactionOffset); + + // 15 BODY + int uncompress_failed = false; + int32_t bodyLen = byteBuffer.getInt(); + if (bodyLen > 0) { + if (readBody) { + ByteArray body(byteBuffer.array() + byteBuffer.arrayOffset() + byteBuffer.position(), bodyLen); + byteBuffer.position(byteBuffer.position() + bodyLen); + + // decompress body + if (deCompressBody && (sysFlag & MessageSysFlag::COMPRESSED_FLAG) == MessageSysFlag::COMPRESSED_FLAG) { + std::string origin_body; + if (UtilAll::inflate(body, origin_body)) { + msgExt->set_body(std::move(origin_body)); + } else { + uncompress_failed = true; + } } else { - uncompress_failed = true; + msgExt->set_body(std::string(body.array(), body.size())); } } else { - msgExt->set_body(std::string(body.array(), body.size())); + // skip body + byteBuffer.position(byteBuffer.position() + bodyLen); } - } else { - // skip body - byteBuffer.position(byteBuffer.position() + bodyLen); } - } - // 16 TOPIC - int8_t topicLen = byteBuffer.get(); - ByteArray topic(topicLen); - byteBuffer.get(topic); - msgExt->set_topic(topic.array(), topic.size()); - - // 17 properties - int16_t propertiesLen = byteBuffer.getShort(); - if (propertiesLen > 0) { - ByteArray properties(propertiesLen); - byteBuffer.get(properties); - std::string propertiesString(properties.array(), properties.size()); - std::map propertiesMap = string2messageProperties(propertiesString); - MessageAccessor::setProperties(*msgExt, std::move(propertiesMap)); - } + // 16 TOPIC + int8_t topicLen = byteBuffer.get(); + ByteArray topic(topicLen); + byteBuffer.get(topic); + msgExt->set_topic(topic.array(), topic.size()); + + // 17 properties + int16_t propertiesLen = byteBuffer.getShort(); + if (propertiesLen > 0) { + ByteArray properties(propertiesLen); + byteBuffer.get(properties); + std::string propertiesString(properties.array(), properties.size()); + std::map propertiesMap = string2messageProperties(propertiesString); + MessageAccessor::setProperties(*msgExt, std::move(propertiesMap)); + } - // 18 msg ID - std::string msgId = createMessageId(msgExt->store_host(), (int64_t)msgExt->commit_log_offset()); - msgExt->MessageExtImpl::set_msg_id(msgId); + // 18 msg ID + std::string msgId = createMessageId(msgExt->store_host(), (int64_t)msgExt->commit_log_offset()); + msgExt->MessageExtImpl::set_msg_id(msgId); - if (uncompress_failed) { - LOG_WARN_NEW("can not uncompress message, id:{}", msgExt->msg_id()); - } + if (uncompress_failed) { + LOG_WARN_NEW("can not uncompress message, id:{}", msgExt->msg_id()); + } - return msgExt; + return msgExt; + } catch (const std::exception& e) { + byteBuffer.position(byteBuffer.limit()); + return nullptr; + } } std::vector MessageDecoder::decodes(ByteBuffer& byteBuffer) { From 2adad6162d5fa6ba7f72c95a6becde2f1a57d5da Mon Sep 17 00:00:00 2001 From: James Yin Date: Sun, 10 Oct 2021 04:06:46 +0800 Subject: [PATCH 62/62] fix: noexcept in std::function --- src/transport/TcpTransport.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transport/TcpTransport.h b/src/transport/TcpTransport.h index b870f69c2..a2476b1d9 100755 --- a/src/transport/TcpTransport.h +++ b/src/transport/TcpTransport.h @@ -44,8 +44,8 @@ class TcpTransportInfo { class TcpTransport : public noncopyable, public std::enable_shared_from_this { public: - typedef std::function ReadCallback; - typedef std::function CloseCallback; + typedef std::function ReadCallback; + typedef std::function CloseCallback; public: static TcpTransportPtr CreateTransport(ReadCallback readCallback,