KubeMQ
Client SDKsC#How-to guidesQueues

Poll Mode

Pull KubeMQ queue messages on demand with polling mode using the C# SDK for controlled consumption.

Overview

Poll mode is a pull-based way to consume queue messages: the consumer decides exactly when to ask for work and how much, instead of holding an open stream the broker pushes into. That control matters for batch jobs, cron-triggered workers, and any consumer that only runs intermittently and would rather ask "is there anything for me?" than keep a subscription alive.

A single call to PollAsync on a QueueDownstreamReceiver sends a channel, MaxMessages, and WaitTimeoutSeconds; the broker holds the request open as a long poll and returns once enough messages are available or the timeout elapses, so the call never spins on an empty queue. AutoAck = true settles the whole batch on delivery, with no separate AckAsync step.

Gotchas: auto-ack removes messages the instant they're delivered — a crash mid-processing loses them, so set AutoAck = false and ack manually when work can fail; the timeout bounds latency, not throughput, so a small MaxMessages on a busy queue means many round trips; and check batch.HasMessages before assuming work is done — an empty batch just means nothing arrived in that window, not that the queue is drained for good.

Prerequisites

  • KubeMQ server running on localhost:50000
  • C# SDK installed (dotnet add package KubeMQ.SDK.CSharp)

Code

Program.cs
// KubeMQ .NET SDK — QueuesStream: Poll Mode
//
// This example demonstrates using the poll-based queue consumption pattern
// with the downstream receiver API. Messages are fetched on demand, giving
// the consumer full control over when to receive and process messages.
//
// Prerequisites:
//   - KubeMQ server running on localhost:50000
//   - dotnet run

using KubeMQ.Sdk.Client;
using KubeMQ.Sdk.Queues;
using System.Text;

await using var client = new KubeMQClient(new KubeMQClientOptions
{
    ClientId = "csharp-queues-poll-mode-client",
});
await client.ConnectAsync();

Console.WriteLine("Connected to KubeMQ server");

for (var i = 1; i <= 10; i++)
{
    await client.SendQueueMessageAsync(new QueueMessage
    {
        Channel = "csharp-queues.poll-mode",
        Body = Encoding.UTF8.GetBytes($"Poll Message #{i}")
    });
}

Console.WriteLine("Sent 10 messages");

await using var receiver = await client.CreateQueueDownstreamReceiverAsync();

var batchNum = 1;
while (true)
{
    var batch = await receiver.PollAsync(new QueuePollRequest
    {
        Channel = "csharp-queues.poll-mode",
        MaxMessages = 3,
        WaitTimeoutSeconds = 5,
        AutoAck = true,
    });

    if (!batch.HasMessages)
    {
        Console.WriteLine("No more messages. Exiting poll loop.");
        break;
    }

    Console.WriteLine($"Poll batch #{batchNum}: received {batch.Messages.Count} messages");
    foreach (var msg in batch.Messages)
    {
        Console.WriteLine($"  {Encoding.UTF8.GetString(msg.Body.Span)}");
    }

    batchNum++;
}

Console.WriteLine("Done.");

How It Works

  • The while (true) loop calls PollAsync repeatedly with MaxMessages = 3. Each call fetches up to 3 messages; WaitTimeoutSeconds = 5 keeps the poll from spinning when the queue is empty.
  • AutoAck = true means the broker acknowledges all returned messages automatically — no manual AckAsync is needed. The loop exits when batch.HasMessages is false.
  • This pattern gives the consumer full control over concurrency and batch size, unlike push-based subscriptions.
  • Reduce MaxMessages to 1 for strict ordered processing; increase for higher throughput at the cost of larger in-flight windows.

Was this page helpful?

On this page