KubeMQ
Client SDKsRubyHow-to guidesError Handling

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

main.rb
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'
end

How It Works

  • The graceful shutdown sequence: cancel subscriptions, wait for threads to exit, then close the client.
  • CancellationToken.cancel signals the subscription thread to stop.
  • thread.join(3) waits up to 3 seconds for the background thread to exit.
  • client.close releases all remaining resources — gRPC channels, buffers, and senders.
  • Review timeouts, channel names, and client IDs before running against shared environments.

Was this page helpful?

On this page