Nack All
Reject all messages in a poll transaction for retry.
Overview
Bulk nack rejects an entire polled batch of queue messages in a single call instead of settling each one individually. It's the operation you reach for when a failure affects the whole batch at once — a downstream dependency is down, a shared resource lock couldn't be acquired, or a transient error means none of the messages can be processed right now — and retrying them one-by-one would just be extra round-trips for the same outcome.
It works with manual-ack polling: KubeMQ.Client.poll_queue returns a poll result holding the messages without settling them, and KubeMQ.PollResponse.nack_all/1 sends one negative-acknowledge that settles every message in that result, returning them all to the queue for redelivery.
Gotchas: the receive count increments on every message in the batch, so an unbounded retry loop is one bad nack_all/1 call away — pair it with a max-receive-count and a dead-letter policy. nack_all/1 is all-or-nothing: you can't use it to keep a few messages and reject the rest — that needs per-message settlement. And calling it on an empty poll result is a wasted round-trip.
Prerequisites
- KubeMQ server running on
localhost:50000 - Elixir SDK installed (
{:kubemq, "~> 1.0"}in mix.exs)
Code
channel = "elixir-queues.nack-all"
{:ok, client} = KubeMQ.Client.start_link(address: "localhost:50000", client_id: "elixir-qs-nackall")
for i <- 1..3 do
{:ok, _} = KubeMQ.Client.send_queue_message(client,
KubeMQ.QueueMessage.new(channel: channel, body: "Retriable msg #{i}"))
end
IO.puts("Sent 3 messages")
case KubeMQ.Client.poll_queue(client,
channel: channel,
max_items: 10,
wait_timeout: 5_000
) do
{:ok, poll} ->
IO.puts("Polled #{length(poll.messages)} messages")
IO.puts("Simulating processing failure — nacking all...")
case KubeMQ.PollResponse.nack_all(poll) do
{:ok, _} -> IO.puts("All messages nacked (returned to queue for retry)")
{:error, err} -> IO.puts("Nack failed: #{err.message}")
end
{:error, err} ->
IO.puts("Poll failed: #{err.message}")
end
Process.sleep(500)
case KubeMQ.Client.receive_queue_messages(client, channel,
max_messages: 10,
wait_timeout: 3_000
) do
{:ok, result} ->
IO.puts("After nack, #{result.messages_received} messages available again")
{:error, _} ->
IO.puts("No messages available")
end
KubeMQ.Client.close(client)How It Works
PollResponse.nack_all/1rejects all messages, returning them to the queue- Messages become available again for other consumers or retry attempts
- Useful when a processing failure affects an entire batch
Related
Was this page helpful?