Close a KubeMQ Kotlin Client
Close a KubeMQ Kotlin client cleanly to release the gRPC connection and free server-side resources.
Overview
Closing a client isn't an afterthought — it tells the broker and your own process that this connection is done, so both sides release what they were holding for it. A KubeMQ client is more than a socket: it's a gRPC channel plus whatever subscriptions and in-flight sends it's servicing. Skip the close and those linger — subscriptions keep streaming, the channel stays open — and in short-lived processes or test suites you leak connections until the process is killed.
Kotlin's use { } block is the idiomatic way to guarantee close() runs when the block exits, even on exception, since every client type (PubSubClient, QueuesClient, CQClient) implements Closeable. Calling close() explicitly, in a finally block, gives the same guarantee with more control over when shutdown happens.
Gotchas: the drain window is bounded, not unlimited, so a slow consumer can still lose the tail of a burst if you close mid-stream; a closed client is dead forever — no reconnect on the same instance, build a new one; and when managing multiple clients, close them in reverse creation order so nothing gets routed to a channel that's already tearing down.
Prerequisites
- KubeMQ server running on
localhost:50000 - Kotlin SDK installed (
implementation("io.kubemq.sdk:kubemq-sdk-kotlin:1.0.1"))
Code
package io.kubemq.sdk.examples.connection
import io.kubemq.sdk.client.KubeMQClient
import kotlinx.coroutines.runBlocking
private const val ADDRESS = "localhost:50000"
private const val CLIENT_ID = "kotlin-connection-close"
fun main() = runBlocking {
useBlockExample()
explicitCloseExample()
multiClientCloseExample()
println("\nClose examples completed.")
}
private suspend fun useBlockExample() {
println("=== Kotlin use { } Pattern (try-with-resources) ===\n")
// Client auto-closes when leaving use block
KubeMQClient.queues {
address = ADDRESS
clientId = "$CLIENT_ID-use"
}.use { client ->
val info = client.ping()
println("Connected: ${info.host}")
println("Client will be auto-closed when leaving this block.\n")
}
println("Client has been automatically closed.\n")
}
private suspend fun explicitCloseExample() {
println("=== Explicit Close Pattern ===\n")
var client: io.kubemq.sdk.pubsub.PubSubClient? = null
try {
client = KubeMQClient.pubSub {
address = ADDRESS
clientId = "$CLIENT_ID-explicit"
}
val info = client.ping()
println("Connected: ${info.host}")
} catch (e: Exception) {
println("Error: ${e.message}")
} finally {
client?.close()
println("Client explicitly closed.\n")
}
}
private suspend fun multiClientCloseExample() {
println("=== Multi-Client Close ===\n")
var pubSubClient: io.kubemq.sdk.pubsub.PubSubClient? = null
var queuesClient: io.kubemq.sdk.queues.QueuesClient? = null
var cqClient: io.kubemq.sdk.cq.CQClient? = null
try {
pubSubClient = KubeMQClient.pubSub {
address = ADDRESS
clientId = "$CLIENT_ID-pubsub"
}
queuesClient = KubeMQClient.queues {
address = ADDRESS
clientId = "$CLIENT_ID-queues"
}
cqClient = KubeMQClient.cq {
address = ADDRESS
clientId = "$CLIENT_ID-cq"
}
println("Three clients created.")
pubSubClient.ping()
queuesClient.ping()
cqClient.ping()
println("All clients connected.\n")
} catch (e: Exception) {
println("Error: ${e.message}")
} finally {
// Close in reverse order
cqClient?.close()
println("CQClient closed.")
queuesClient?.close()
println("QueuesClient closed.")
pubSubClient?.close()
println("PubSubClient closed.")
}
}How It Works
- The
use { }block is the idiomatic Kotlin approach -- the client is automatically closed when the block exits, even on exceptions. - Explicit
close()in afinallyblock provides the same guarantee with more control. - When managing multiple clients, close them in reverse creation order to avoid dependency issues.
- All client types (
PubSubClient,QueuesClient,CQClient) implementCloseable.
Related
Was this page helpful?