Cached Query
Use server-side query response caching for KubeMQ queries with the C# SDK RPC client.
Overview
Query response caching lets the broker answer repeat requests without re-running your handler — useful when a query is expensive to compute (a database lookup, an aggregation, a downstream call) but the same input is asked for repeatedly in a short window. Only the first request pays the processing cost; every other caller gets the same answer straight from the broker.
Set CacheKey and CacheTtlSeconds on the QueryMessage. The first query with a given key is a miss: it reaches the handler, and the broker stores the response under that key for the TTL. A subsequent query with the same key is a hit — the broker returns the stored response directly without invoking the handler. CacheHit on the response tells you which happened.
Gotchas: the cache is keyed by the string you choose, not by the query body — if the underlying data changes mid-TTL, callers can get a stale answer until it expires. Keys are scoped per channel, so the same key on another channel is a separate entry. Caching only helps when requests genuinely repeat with the same key.
Prerequisites
- KubeMQ server running on
localhost:50000 - C# SDK installed (
dotnet add package KubeMQ.SDK.CSharp)
Code
// KubeMQ .NET SDK — Queries: Cached Response
//
// This example demonstrates query caching. The server caches the response
// and returns it directly for subsequent queries with the same cache key,
// without forwarding to the handler.
//
// Prerequisites:
// - KubeMQ server running on localhost:50000
// - Run Queries.HandleQuery in a separate terminal first
// - dotnet run
using KubeMQ.Sdk.Client;
using KubeMQ.Sdk.Queries;
using KubeMQ.Sdk.Exceptions;
using System.Text;
await using var client = new KubeMQClient(new KubeMQClientOptions
{
ClientId = "csharp-queries-cached-response-client",
});
await client.ConnectAsync();
Console.WriteLine("Connected to KubeMQ server");
try
{
// First query — will be forwarded to the handler
var response1 = await client.SendQueryAsync(new QueryMessage
{
Channel = "csharp-queries.cached-response",
Body = Encoding.UTF8.GetBytes("get-user:42"),
TimeoutInSeconds = 10,
CacheKey = "user-42",
CacheTtlSeconds = 60
});
Console.WriteLine($"First query - CacheHit: {response1.CacheHit}");
Console.WriteLine($"Response: {Encoding.UTF8.GetString(response1.Body.Span)}");
// Second query with same cache key — served from cache
var response2 = await client.SendQueryAsync(new QueryMessage
{
Channel = "csharp-queries.cached-response",
Body = Encoding.UTF8.GetBytes("get-user:42"),
TimeoutInSeconds = 10,
CacheKey = "user-42",
CacheTtlSeconds = 60
});
Console.WriteLine($"\nSecond query - CacheHit: {response2.CacheHit}");
Console.WriteLine($"Response: {Encoding.UTF8.GetString(response2.Body.Span)}");
}
catch (KubeMQTimeoutException)
{
Console.WriteLine("Query timed out — no handler responded within 10 seconds");
}
catch (KubeMQOperationException ex)
{
Console.WriteLine($"Operation error: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Unexpected error: {ex.Message}");
}
Console.WriteLine("Done.");
How It Works
CacheKey = "user-42"andCacheTtlSeconds = 60onQueryMessageactivate server-side response caching. The first query is forwarded to the handler; subsequent queries with the sameCacheKeyare served from the broker's cache without reaching the handler.response1.CacheHitisfalseon the first call (cache miss, handler invoked).response2.CacheHitistrueon the second call (served from cache, no handler round-trip).CacheTtlSecondscontrols how long the cached response is retained. After expiry, the next query with that key triggers a fresh handler invocation.- Cache keys are scoped to the channel — the same key on different channels produces independent cache entries.
Related
Was this page helpful?