Blocking send operation

Adyc
Adyc Member Posts: 2

Is there a way to invoke the send method in a blocking way? I would like to wait for the ack/nack/timeout, and continue only after I have the result.

My current solution is a wrapper of the original send method, that keeps track of the sent messages and waits for the event from the event broker.

Best Answer

  • TomF
    TomF Member, Employee Posts: 412 Solace Employee
    #2 Answer ✓

    Hi @Adyc, have you seen the SendBlocking session property? It doesn't do what you want (it blocks only until the message is accepted by the transport), but in the description it does say:

    The API does not support a synchronous (send and wait for acknowledgement operation), however such an operation can be easily implemented in an application by waiting for a Acknowledgement

    Sorry!

Answers

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

    Hi @Adyc, welcome to the Community!

    Which language, API, protocol are you asking about? We have many. Some of our newer APIs already have this built-in. JMS 1.1 also has this built-in by spec. Coding this yourself for JCSMP is pretty simple, just need some threading locking/coordinating code. Other answers for other languages. Let us know.

  • Adyc
    Adyc Member Posts: 2

    We have it in c#, so we use the nuget package SolaceSystems.Solclient.Messaging 10.18.0

  • TomF
    TomF Member, Employee Posts: 412 Solace Employee
    #5 Answer ✓

    Hi @Adyc, have you seen the SendBlocking session property? It doesn't do what you want (it blocks only until the message is accepted by the transport), but in the description it does say:

    The API does not support a synchronous (send and wait for acknowledgement operation), however such an operation can be easily implemented in an application by waiting for a Acknowledgement

    Sorry!

  • Aaron
    Aaron Member, Administrator, Moderator, Employee Posts: 636 admin
    edited April 2023 #6

    Yeah, I'm not a C# dev, but in Java the code to implement this behaviour is not that hard. Essentially make your own send() method that does the actual API send, and then block on an object / thread coordinator (e.g. a CountDownLatch of size 1). The latch (or whatever) should probably be keyed on the MessageID that the API assigns to the message after the send() call returns... or make sure the CorrelationKey is set to the message or something unique; this is in case you have multiple threads publishing in parallel. Then in the callback where publish ACKs are received from the broker, you can check the CorrelationKey assigned to the ACK, find the Latch (or whatever) that is for that specific message and unblock it. This will release your other thread to continue. Obviously, if you receive a NACK (negative acknowledgement instead) you'd want to throw an exception to the latch so that your publishing thread knows it has a problem.

    Note that in C# the API has only one thread (Context thread) for doing everything, so you CANNOT publish from this thread and block as it would block up other processes the API needs to run. So make sure you're publishing from an application-owned thread.