Acknowledging Messages Received by Clients
The Solace Messaging API for JavaScript provides acknowledgments to the Solace event broker for the guaranteed messages that clients receive through a flow. The figure below shows the process of how the guaranteed messages that an application receives through a flow are acknowledged. During this flow, client applications can also send a negative acknowledgment (NACK) for malformed messages or messages that could not be processed.
Acknowledging Received Guaranteed Messages
API Acknowledgments
A Guaranteed message window size limits the number of messages that the API can receive before it must return an acknowledgment to the event broker to indicate that it received the messages in the window. After the API sends this acknowledgment, the Guaranteed message window reopens so that further messages can be sent to the API.
An application can adjust the windowed acknowledgments by changing the default acknowledgment timer and threshold parameters set through the flow properties. For more information, see Important Flow (Message Consumer) Properties). Changing these defaults is not usually required and will change the performance characteristics of a flow.
Application Acknowledgments
One of the two following application acknowledgment modes can be used for acknowledging a message:
- Auto-acknowledgment
- Client acknowledgment
The acknowledgment mode to use is set through one of the flow properties listed below. By default, the auto-acknowledgment mode is used.
To set the acknowledgment mode, use solace.MessageConsumerProperties.acknowledgeMode. Possible values are:
-
solace.MessageConsumerAcknowledgeMode.AUTO -
solace.MessageConsumerAcknowledgeMode.CLIENT
Auto-Acknowledgment Mode
When the auto-acknowledgment mode is used, the API automatically generates application-level acknowledgments.
Client Acknowledgment Mode
When the client acknowledgment mode is used the client must explicitly send an acknowledgment for the message ID of each message received. Optionally, you can use negative acknowledgments as well. For more information, see Negative Acknowledgments for Specific Messages.
To explicitly send a client acknowledgment, call solace.Message.acknowledge().
Acknowledgment is called on the message object.
Avoid allowing the number of outstanding unacknowledged messages to become excessively large (for example, 10,000 or more) because the egress message rate from the event broker can start to decline.
Negative Acknowledgments for Specific Messages
You can use negative acknowledgments (NACKs) if you have configured your applications for client acknowledgments (see Client Acknowledgment Mode). When you use NACKs, you can send a settlement outcome to let the event broker know the result from processing a guaranteed message that was received. Based on the settlement outcome, the event broker knows how to handle the message on its queue. You can use the following settlement outcomes:
- ACCEPTED—This ACK notifies the event broker that your client application successfully processed the guaranteed message. When the event broker receives this outcome it removes the message from its queue.
- When you call a settlement function/methods with an outcome of ACCEPTED, it is the same as calling an ACK function/methods in Client Acknowledgment Mode.
- FAILED—This NACK notifies the event broker that your client application did not process the message. When the event broker receives this NACK it attempts to redeliver the message while adhering to delivery count limits.
- REJECTED—This NACK notifies the event broker that your client application could process the message but it was not accepted (for example, failed validation). When the event broker receives this NACK it removes the message from its queue and then moves the message to the dead message queue (DMQ) if it is configured.
Before you can use NACKs, you must add the FAILED, REJECTED, or both outcomes as NACK types when you create the flow to prepare the flow to work with negative acknowledgments. You do not need to add the ACCEPTED outcome because it is always available. If you try to use an outcome that has not been added, you get an error of Required Settlement Outcome Not Supported.
- NACKs can be lost during transit (for example due to unexpected networking issues). Consider this fact as part of the logic for handling messages when you develop your application.
- NACKs are supported on event brokers 10.2.1 and later. If an event broker does not support NACKs, an
InvalidOperationExceptionoccurs during the flow bind request when an outcome is specified.
When you create a flow, enable and set the following properties on your message consumer to use negative acknowledgments:
requiredSettlementOutcomes: [MessageOutcome.FAILED, MessageOutcome.REJECTED]
MessageOutcome.ACCEPTED is not required to be set with requiredSettlementOutcomes and is always supported.
You can send an ACK or NACK using:
Message.settle(messageOutcome)
For the messageOutcome, you use one of the following values:
MessageOutcome.ACCEPTEDMessageOutcome.REJECTEDMessageOutcome.FAILED
Using NACKs with the Solace JavaScript API
The following sample code shows how to send NACKs using the Solace JavaScript API:
try {
// Create a message consumer with support for NACKs
const messageConsumer = session.createMessageConsumer({
// solace.MessageConsumerProperties
queueDescriptor: {
name: 'QueueName',
type: solace.QueueType.QUEUE,
durable: true
},
acknowledgeMode: solace.MessageConsumerAcknowledgeMode.CLIENT, // Enabling Client ack
// Session is created with SUPPORTED_MESSAGE_ACK_CLIENT to support negative acknowledgment outcomes.
// MessageOutcome.ACCEPTED is not required to be set and always supported.
requiredSettlementOutcomes: [
MessageOutcome.FAILED,
MessageOutcome.REJECTED
], // Sets the settlement outcome for the flow. Flow Type will be 0x03.
});
// Define message consumer event listeners
messageConsumer.on(solace.MessageConsumerEventName.UP, () => {
// Consumer is up
});
messageConsumer.on(solace.MessageConsumerEventName.CONNECT_FAILED_ERROR, (error) => {
// Error: The message consumer could not bind to queue
});
messageConsumer.on(solace.MessageConsumerEventName.DOWN, () => {
// The message consumer is down
});
messageConsumer.on(solace.MessageConsumerEventName.DOWN_ERROR, (details) => {
console.log(`Received "DOWN_ERROR" event - details: ${details}`);
});
// Define message received event listener
messageConsumer.on(solace.MessageConsumerEventName.MESSAGE, (message) => {
console.log(
`Received message: "${message.getBinaryAttachment()}", details:\n${message.dump()}`
);
// Use the new settle method to ACK/NACK the message from the router
message.settle(solace.MessageOutcome.ACCEPTED); // Same as message.acknowledge();
// Messages can also be settled with the FAILED and REJECTED outcomes on supported event broker sessions
// message.settle(solace.MessageOutcome.FAILED); // Same as message.acknowledge();
// message.settle(solace.MessageOutcome.REJECTED); // Same as message.acknowledge();
});
// Connect the message consumer
messageConsumer.connect();
} catch (error) {
// Error occurred while creating the message consumer
console.error(error.toString());
}