Graceful Shutdown
Perform a clean KubeMQ shutdown in Ruby by cancelling subscriptions and releasing client resources before the process exits.
Overview
A graceful shutdown stops a KubeMQ client without dropping in-flight messages or leaking server-side subscription state. Killing a process outright, or closing the client mid-callback, can truncate a handler or leave the server thinking a consumer is still there. In a container platform that sends SIGTERM before force-killing a pod, an orderly shutdown sequence turns a rolling deploy into a clean handoff instead of a burst of errors.
The pattern has a fixed order: stop new work by cancelling the subscription, then close the client so remaining resources — gRPC channels, buffers, senders — are released. CancellationToken#cancel signals the background subscription thread to stop, thread.join(3) waits a bounded interval for that thread to exit, and only then is client.close called.
Gotchas: calling client.close before the thread has joined can race the connection teardown — always cancel and join first. Wrapping the sequence in ensure (as this example does) guarantees cleanup still runs if a KubeMQ::Error is raised mid-flow; skip it and an exception can orphan the subscription thread.
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-error-handling.graceful-shutdown'
begin
client = KubeMQ::PubSubClient.new(address: address, client_id: 'shutdown-example')
puts "Connected to #{address}"
cancel = KubeMQ::CancellationToken.new
sub = KubeMQ::PubSub::EventsSubscription.new(channel: channel)
thread = client.subscribe_to_events(sub, cancellation_token: cancel, on_error: ->(e) { puts "Error: #{e.message}" }) do |event|
puts "Received: #{event.metadata}"
end
sleep 1
puts 'Subscription active, sending events...'
2.times do |i|
msg = KubeMQ::PubSub::EventMessage.new(channel: channel, metadata: "shutdown-msg-#{i}", body: "data-#{i}")
client.send_event(msg)
sleep 0.2
end
sleep 1
puts 'Cancelling subscription...'
cancel.cancel
thread.join(3)
puts 'Subscription cancelled'
client.close
puts 'Client closed — shutdown complete'
rescue KubeMQ::Error => e
puts "KubeMQ error: #{e.message}"
ensure
puts 'Done'
endHow It Works
- The graceful shutdown sequence: cancel subscriptions, wait for threads to exit, then close the client.
CancellationToken.cancelsignals the subscription thread to stop.thread.join(3)waits up to 3 seconds for the background thread to exit.client.closereleases all remaining resources — gRPC channels, buffers, and senders.- Review timeouts, channel names, and client IDs before running against shared environments.
Related
Was this page helpful?