Request-Reply
Implement the synchronous request-reply pattern over KubeMQ queries in Ruby, sending a request and waiting for the responder's reply.
Overview
Request-reply gives you synchronous RPC on top of KubeMQ's messaging fabric: a caller sends a query and blocks until the handler actually processing the request sends back a real answer — not just an acknowledgment. Reach for it whenever the caller needs a return value to proceed — a lookup, a computed result, a status check — the same shape as an HTTP call, but routed by KubeMQ instead of a service mesh or DNS.
A handler block passed to subscribe_to_queries builds a QueryResponseMessage with request_id: query.id and reply_channel: query.reply_channel before calling send_response — copying those fields is what lets KubeMQ route the response to the one caller waiting, not broadcast it. The caller's send_query blocks until that reply arrives or its timeout elapses, returning a result with a body.
Gotchas: if no subscriber is listening — or the handler crashes before replying — send_query simply times out; there's no way to distinguish "no handler" from "handler is slow" from the timeout alone. request_id and reply_channel must echo back the incoming query's values unchanged, or the reply is silently dropped or misrouted. If you don't actually need a return value, use commands instead — they only need an ack, so they don't tie up a caller waiting on a round trip.
Prerequisites
- KubeMQ server running on
localhost:50000 - Ruby SDK installed (
gem install kubemq)
Code
require 'kubemq'
address = ENV.fetch('KUBEMQ_ADDRESS', 'localhost:50000')
channel = 'ruby-patterns.request-reply'
begin
client = KubeMQ::CQClient.new(address: address, client_id: 'rpc-pattern-example')
puts "Connected to #{address}"
cancel = KubeMQ::CancellationToken.new
sub = KubeMQ::CQ::QueriesSubscription.new(channel: channel)
client.subscribe_to_queries(sub, cancellation_token: cancel, on_error: ->(e) { puts "Error: #{e.message}" }) do |query|
puts "Handler received query: #{query.metadata}"
response = KubeMQ::CQ::QueryResponseMessage.new(
request_id: query.id,
reply_channel: query.reply_channel,
executed: true,
body: "answer-to-#{query.metadata}"
)
client.send_response(response)
end
sleep 1
%w[get-user get-settings].each do |action|
msg = KubeMQ::CQ::QueryMessage.new(channel: channel, timeout: 10_000, metadata: action, body: 'request')
result = client.send_query(msg)
puts "Reply: #{result.body}"
end
rescue KubeMQ::Error => e
puts "KubeMQ error: #{e.message}"
ensure
cancel&.cancel
client&.close
puts 'Done'
endHow It Works
- The request-reply pattern uses queries for synchronous RPC with data responses.
- The server subscribes and responds; the client sends queries and receives replies.
- Review timeouts, channel names, and client IDs before running against shared environments.
Related
Was this page helpful?