Hello everyone,
I’m trying to implement the transactional client with timeout-based delivery in Solace leveraging the ClientAck mode but I’m struggling to understand what is the timeout setting used by Solace to redeliver a message in case the consumer that receives the message does not send the Ack within a specified time.
The scenario I’m working with is a pool of X .NET Core consumers subscribed to a non-exclusive durable queue in which a producer publishes persistent messages.
Consumer queue setup:
IQueue queue = ContextFactory.Instance.CreateQueue(queueName);
Flow = session.CreateFlow(new FlowProperties()
{
AckMode = MessageAckMode.ClientAck ,
AckTimerInMsecs = 500,
MaxUnackedMessages = -1,
WindowSize = 1 //set a persist message as one unit
},
queue, null, HandleMessageEvent, HandleFlowEvent);
Flow.Start();
// block the current thread until a confirmation received
WaitEventWaitHandle.WaitOne();
//dispose flow then restart the flow in the next loop
Flow.Stop();
Flow.Dispose();
GC.Collect();
Here the consumer code in which I added a “sleep” to simulate an high processing time. I expect at some point the message to be redelivered to another instance because the Ack has not been sent within N seconds:
// Received a message
Console.WriteLine("Solace: Received message.");
using (IMessage message = args.Message)
{
var msg =
Encoding.UTF8.GetString(Compression.Decompress(message.BinaryAttachment));
// process the message
Console.WriteLine("Processing message.. Is redelivered: " + message.Redelivered);
MessageEventHandle(message.Destination.Name, msg);
// process completed, we can Ack
if (Flow != null)
{
// to test how long it waits before redelivering to another consumer
Console.WriteLine(string.Format("Wait {0} millisec before sending ack", _delayMillisec));
Thread.Sleep(_delayMillisec);
Flow.Ack(message.ADMessageId);
Console.WriteLine("Message Ack at " + DateTime.Now.ToString());
}
}
I executed this code changing the _delayMillisec to simulate short and long processing times.
By running those experiments I was able to determine that:
- when the processing completes in less than 20 seconds the message is not redelivered to another instance
- when processing takes more than 30 seconds the message is always redelivered to another instance
- between 20 to 30 seconds it’s inconsistent: sometimes it’s redelivered sometimes not.
In summary this experiment shows that the internal timeout setting that Solace uses to decide when to redeliver a message is somewhat between 20 to 30 seconds.
However I was not able to find this number in the documentation nor where I could change it.
Could you please clarify how Solace decides when to redeliver the message when ClientAck mode is enabled in case the Ack is not received? Is it by a fixed timeout or is there any different logic it gets applied?
If it’s by fixed timeout, can this setting be changed and how?
Thanks,
Daniele