I'm putting together a Solace Point-to-point solution in C#.
In my subscriber/listener, I am using ClientAck mode to ensure messages are successfully processed before being removed from the queue.
My question (probably due to my limited experience in messaging) is regarding failed messages, e.g. if I cannot process the message and hence not send the Ack, how is the message replayed?
An example of what I have is as follows:
using (ISession session = context.CreateSession(sessionProperties, null, null))
{
ReturnCode returnCode = session.Connect();
if (returnCode == ReturnCode.SOLCLIENT_OK)
{
var endpointProps = new EndpointProperties()
{
Permission = EndpointProperties.EndpointPermission.Consume,
AccessType = EndpointProperties.EndpointAccessType.Exclusive
};
using (IQueue queue = ContextFactory.Instance.CreateQueue(queueName))
{
session.Provision(queue, endpointProps,
ProvisionFlag.IgnoreErrorIfEndpointAlreadyExists | ProvisionFlag.WaitForConfirm, null);
_flow = session.CreateFlow(new FlowProperties { AckMode = MessageAckMode.ClientAck }, queue, null, HandleMessageEvent, HandleFlowEvent);
_flow.Start();
do { WaitEventWaitHandle.WaitOne(); } while (!cancellationToken.IsCancellationRequested);
};
return Task.CompletedTask;
}
else
{
throw new Exception($"Connection failed, return code: {returnCode}");
}
}
and then handling incoming messages
void HandleMessageEvent(object sender, MessageEventArgs args)
{
using (IMessage message = args.Message)
{
try
{
_handler(message.ApplicationMessageType, message.BinaryAttachment);
_flow.Ack(message.ADMessageId);
}
finally
{
WaitEventWaitHandle.Set();
}
}
}
So, if I don't Ack, message remains on queue as expected (and required), however, how (best-practice) can I re-process it without manual intervention?
After a message has been delivered to a consumer from a Solace PubSub+ queue, the message will only be resent if the client unbinds before sending an acknowledgement back. The exception to this is specific to JMS clients with the session.recover() action.
If a message needs to be re-delivered to a C# application after it has already been sent but not acknowledged, the client will need to unbind and rebind to the queue. Note that if there are other clients also bound to the queue, the message may be re-sent to those clients before your client rebinds.