I have a question about ActiveMQ 5.11 broker with a local C++ CMS Client 3.9.3. I modified the sample code from the official site to use the pthread_create function to spawn a new thread and trying to ack the message (CLIENT_ACK mode) from the new thread. It turns out there is segmentation fault. How can we achieve that returning the ack from the newly spawned thread rather than current thread? Does ActiveMQ C++ Client support multi-thread to ack the message?
void* sendAckThreadFunc(void *pMessage) {
sleep(1);
const Message* message = (const Message*) pMessage;
message->acknowledge();
printf("ACK sent out.");
return NULL;
}
virtual void onMessage(const Message* message) {
static int count = 0;
try {
count++;
const TextMessage* textMessage = dynamic_cast<const TextMessage*>(message);
string text = "";
if (textMessage != NULL) {
text = textMessage->getText();
} else {
text = "NOT A TEXTMESSAGE!";
}
if (clientAck) {
//message->acknowledge(); --> instead of ack the message in the onMessage function, they use pthread_create to generate a new thread and trying to ack the message from there. Is is a supported way??
pthread_t sendAckThread;
if (pthread_create(&sendAckThread, NULL, sendAckThreadFunc,
(void*) message)) {
printf("Error occured when create threads.");
}
}
printf("A Message #%d Received: %s\n", count, text.c_str());
} catch (CMSException& e) {
e.printStackTrace();
}
}
When I run the consumer, it even failed with trying to ack one message:
[root@amq6-283-1 examples]# ./simple_async_consumer
=====================================================
Starting the example:
-----------------------------------------------------
The Connection's Transport has been Restored.
Press 'q' to quit
A Message #1 Received: Hello world! from thread 140486368756208
Segmentation fault (core dumped)
The thing here is, once the message object exits the OnMessage function, all the resources are gone and cannot pass to other threads.
The CMS API documentation spells it out pretty clearly:
/**
* Called asynchronously when a new message is received, the message
* reference can be to any of the Message types. a dynamic cast is used
* to find out what type of message this is. The lifetime of this
* object is only guaranteed to be for the life of the onMessage function
* after this call-back returns the message may no longer exist. Users should
* copy the data or clone the message if they wish to retain information that
* was contained in this Message.
*
* It is considered a programming error for this method to throw an
* exception. The method has been tagged with the 'throw()' qualifier,
* this implies that you application will segfault if you throw an error
* from an implementation of this method.
*
* @param message
* Message object {const} pointer recipient does not own.
*/
I understand the sample is only for serial processing, but I would sincerely request to have parallel processing, which means All the things are not done in a single thread. If it is serial, Before the current message gets processed and returns the ack, the current thread cannot receive more batch of messages. It really does not meet the customer's performance needs.
So can anyone illustrate how CMS API is designed to handle parallelism? Receiver thread just focuses on receiving messages inside OnMessage
function while other business threads spawned focus on business processing and depending on the result to return the ack. I just want to know how CMS API is capable to handle the parallelism. That is how they used the CLIENT ACK Mode. Can anyone kindly provide a parallelism example?