🎄 Happy Holidays! 🥳

Most of Solace is closed December 24–January 1 so our employees can spend time with their families. We will re-open Thursday, January 2, 2024. Please expect slower response times during this period and open a support ticket for anything needing immediate assistance.

Happy Holidays!

Please note: most of Solace is closed December 25–January 2, and will re-open Tuesday, January 3, 2023.

What's the best Java based API (JCMSP, JMS or new Java) to achieve blocking publish behaviour?

ChristianHoltfurth
ChristianHoltfurth Member, Employee Posts: 75 Solace Employee

Hi All,

What's the best Java based API (JCMSP, JMS or new Java) to achieve blocking publish behaviour?

The application team is using JCSMP currently and having a hard time achieving the behaviour they are looking for, which is:

  1. Publish a message
  2. Wait for Ack or Nack (and do error handling)
  3. Repeat

They have strict ordering requirements and can't publish the next message until the first one is confirmed.

With JCSMP it's quite hard to achieve, requiring coordination between the publishing thread and the ack/nack listener thread via latches or similar.

Bonus points for code snippets. ;)

Best Answers

  • rlawrence
    rlawrence Member, Employee Posts: 14 Solace Employee
    edited May 2022 #2 Answer ✓

    Hi Christian

    This is the exact behaviour for JMS, since Solace JMS API supports JMS version 1.1 which only supports a synchronous sends, so API publish call waits for an ack/nack from the broker before returning.

    The JCSMP API is more flexible and supports a publisher window, which could be configured to 1 to give you similar behaviour, but as you say requires some coordination between the publisher and listener threads. See a blog on setting the publisher window size (including code snippets!) here.

    HTH

  • marc
    marc Member, Administrator, Moderator, Employee Posts: 963 admin
    #3 Answer ✓

    Hi @ChristianHoltfurth,

    I would also point out that the PubSub+ Messaging API for Java supports a blocking send as well with the publishAwaitAcknowledgement method. Docs here.

    @Aaron recently added a GuaranteedBlockingPublisher sample that highlights how to use it.


    Hope that helps!

Answers

  • rlawrence
    rlawrence Member, Employee Posts: 14 Solace Employee
    edited May 2022 #4 Answer ✓

    Hi Christian

    This is the exact behaviour for JMS, since Solace JMS API supports JMS version 1.1 which only supports a synchronous sends, so API publish call waits for an ack/nack from the broker before returning.

    The JCSMP API is more flexible and supports a publisher window, which could be configured to 1 to give you similar behaviour, but as you say requires some coordination between the publisher and listener threads. See a blog on setting the publisher window size (including code snippets!) here.

    HTH

  • ChristianHoltfurth
    ChristianHoltfurth Member, Employee Posts: 75 Solace Employee

    Thanks @rlawrence,

    That's the answer I was looking for!

    Just to add a bit more detail for future reference, I found the following code example in the Solace repositories, but it only publishes one message and doesn't do any error handling:

    https://github.com/SolaceSamples/solace-samples-jms/blob/master/src/main/java/com/solace/samples/TopicPublisher.java

    How would one enhance that to get the behaviour as described above?

    My coding skills are a bit rusty, but from memory, the messageProducer.send() method does throw an Exception, if a message nack instead of an ack was received back from the broker, correct?

    So you would have to wrap that in an exception handling block and loop to achieve the functionality described above, correct?

  • marc
    marc Member, Administrator, Moderator, Employee Posts: 963 admin
    #6 Answer ✓

    Hi @ChristianHoltfurth,

    I would also point out that the PubSub+ Messaging API for Java supports a blocking send as well with the publishAwaitAcknowledgement method. Docs here.

    @Aaron recently added a GuaranteedBlockingPublisher sample that highlights how to use it.


    Hope that helps!

  • ChristianHoltfurth
    ChristianHoltfurth Member, Employee Posts: 75 Solace Employee

    Thanks Marc, that's great additional detail and another good option!


    So in summary, from the 3 Java based APIs, JCSMP is more suited for parallel publishing at the highest possible performance, while both the JMS API as well as the new Java API make it easier to keep control of the order of your published messages by providing a blocking send method.

  • VvT
    VvT Member, Employee Posts: 15 Solace Employee

    An additional note: a link to the official docs how to configure the Publish Window Size can be found here:

    https://docs.solace.com/API/API-Developer-Guide/Sending-Guaranteed-Messages.htm?Highlight=guaranteed%20publish

  • ChristianHoltfurth
    ChristianHoltfurth Member, Employee Posts: 75 Solace Employee

    Hi @VvT ,

    Thanks for the link to configuring publishing windows size. This is a useful additional setting, however, it doesn't solve the requirements completely on its own as I understand it.

    If you set the window to 1, then it will block you from sending more than one message at a time, but it will immediately unblock when you receive either an ack or a nak. So you might send your first message, then enter the API call for the second message. As soon as you receive an nack for the first message, the second message will be send and you can't stop that from happening and intervene to re-send your first message instead.

    Having said that, there's a way to achieve the above behaviour with JCSMP as well. Thanks to @Aaron for pointing that out to me out-of-band. Solace has produced a code sample for this case that is making use of a CyclicBarrier to block the next send from happening until the response from the first one has been fully processed and any error handling taken care of.

    https://github.com/SolaceSamples/solace-samples-java-jcsmp/blob/master/src/main/java/com/solace/samples/jcsmp/features/BlockingSynchronousSendGuaranteed.java