How to ack message?

I am using JCSMP 10.9.1 API in my code.
I want to control the acki'ng of the messages on the consumer side instead of relying on auto_ack. So, I set the message ack mode to client_ack. And I am calling message.ackMessage() after every 1000 message. However, after 20000 number of messages, my consumer stops getting messages from the Solace. In solace router side, Max Delivered unacked msgs is set to 20000. It seems iike I am not acking fast enough. So my question is what is the proper way of acking. I have also set JCSMPGlobalProperties.setConsumerDefaultFlowCongestionLimit to 20000



  • chauhraj
    chauhraj Member Posts: 2

    I forgot to add. I was expecting that if I ack the message, then by default all the messages delivered before the acked messages will also be acked. Atleast, that was my understanding especially when there is no public API to ack messages given on the message Id. Thanks to this post, I got to know about the non-public API which for the time being, I am using until I get a reply to my original problem. However, is there any API which can tell me yet unacked message. Lets say there are 1024 messages on queue. If I decide to ack after every 100 messages, then last 24 will remain unacked until I ack them. If the API exists then its great else I have to use some timer logic to ack the messages.

  • TomF
    TomF Member, Employee Posts: 405 Solace Employee

    Hi @chauhraj, having a single call to acknowledge cause the acknowledgement of all previous unacknowledged messages is a JMS concept and isn't how JCSMP works - that's why things aren't working as you expect. In JCSMP, message.ackMessage() works on a per message basis - it only acknowledges that particular message.

    So, our recommended best practice is to use JCSMPProperties.SUPPORTED_MESSAGE_ACK_CLIENT, which you are doing, but then to call ackMessage() on each individual message once you've finished processing it. That way you can be sure that all the messages remaining on the queue still need to be processed, reducing the need to de-duplicate.

    Please don't use 'FlowHandle', it's an internal class and using it is not supported.

    If you're dealing with messages in bulk - say getting a batch of messages and writing them all at the same time to a database - acknowledge the messages at the same time one-by-one in the batch processing block.

  • Aaron
    Aaron Member, Administrator, Moderator, Employee Posts: 497 admin

    Or maybe sounds like a Kafka-type approach... checkpointing..?

    But yes, as Tom said, you ack() each individual message when you are done with it.

  • amackenzie
    amackenzie Member, Employee Posts: 259 Solace Employee

    Just to add on to what @TomF said... the ack all previous messages is a JMS concept and is the behavior you see if the JMS ack mode is: CLIENT_ACKNOWLEDGE. It's honestly not a great mode because unless you are acking every message, there could be messages before you call the message.acknowledge() that should not be ack'd (like in an error state within your application and you had already moved on to the next message). For this reason, Solace JMS has a custom ack mode called SOL_CLIENT_ACKNOWLEDGE which behaves like @TomF mentions above, acking only the previous message. Incidentally, Solace isn't the only broker than sees the default JMS client acknowledgement as not entirely "useful" ;) Tibco also has a custom ack mode called EXPLICIT_CLIENT_ACKNOWLEDGE which also only acks the previous 1 message.

    Of course that whole discussion is about JMS. You are using JCSMP and Tom's description is spot on. I just wanted to explain the behavior if you were coming from a JMS background.