Custom Timeouts
Configure connection and per-operation timeouts on the KubeMQ Go client to tune latency and failure behavior.
Overview
Every client operation has an implicit deadline — how long to wait for the initial connection, how long before a dead socket is detected, how long a single RPC blocks before giving up, how long Close() waits for in-flight work to drain. The defaults are reasonable for a healthy local network, but they're wrong for high-latency links, connections that pass through load balancers or NAT gateways, or servers that occasionally run slow under load. Tuning timeouts explicitly is how you trade fast-fail behavior against tolerance for transient slowness.
Each timeout targets a different phase of the client lifecycle. WithConnectionTimeout bounds the initial dial; WithKeepaliveTime / WithKeepaliveTimeout configure gRPC HTTP/2 keepalive pings that detect a stale connection before you try to use it; WithDrainTimeout bounds how long Close() waits for outstanding calls to finish before it forces the transport shut. Gotchas: a connection timeout shorter than your network's real handshake latency causes spurious startup failures, not faster detection of a genuinely down server; keepalive pings set too aggressively can flag a slow-but-healthy link as dead; and raising WithMaxReceiveMessageSize / WithMaxSendMessageSize only helps if the server's own limits are raised to match — otherwise you've just moved the failure from client to server.
Prerequisites
- KubeMQ server running on
localhost:50000 - Go SDK installed (
go get github.com/kubemq-io/kubemq-go/v2)
Code
// Example: connection/custom-timeouts
//
// Demonstrates how to configure custom timeouts for the KubeMQ client
// including connection timeout, keepalive, and drain timeout.
//
// Channel: go-connection.custom-timeouts
// Client ID: go-connection-custom-timeouts-client
//
// Run with a KubeMQ server on localhost:50000
// (see https://docs.kubemq.io/deploy).
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/kubemq-io/kubemq-go/v2"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// Create a client with custom timeout configuration.
client, err := kubemq.NewClient(ctx,
kubemq.WithAddress("localhost", 50000),
kubemq.WithClientId("go-connection-custom-timeouts-client"),
// Custom connection timeout (default: 10s)
kubemq.WithConnectionTimeout(15*time.Second),
// Custom keepalive settings (default: 10s interval, 5s timeout)
kubemq.WithKeepaliveTime(30*time.Second),
kubemq.WithKeepaliveTimeout(10*time.Second),
// Custom drain timeout for Close() (default: 5s)
kubemq.WithDrainTimeout(10*time.Second),
// Max message sizes
kubemq.WithMaxReceiveMessageSize(50*1024*1024), // 50 MB
kubemq.WithMaxSendMessageSize(50*1024*1024), // 50 MB
)
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
defer client.Close()
info, err := client.Ping(ctx)
if err != nil {
log.Fatalf("Ping failed: %v", err)
}
fmt.Printf("Connected with custom timeouts: host=%s version=%s\n",
info.Host, info.Version)
}
How It Works
WithConnectionTimeout(15 * time.Second)caps the initial gRPC dial; if the server does not respond within this window,NewClientreturns an error.WithKeepaliveTimeandWithKeepaliveTimeoutconfigure gRPC HTTP/2 keepalive pings — useful for detecting stale connections through NATs or load balancers that silently drop idle TCP flows.WithDrainTimeout(10 * time.Second)sets the budget forclient.Close()to finish in-flight operations before forcibly closing the transport.WithMaxReceiveMessageSize/WithMaxSendMessageSizeoverride gRPC's default 4 MB limit; increase these only when you know your payloads are large — oversized limits waste memory on every RPC.
Related
Was this page helpful?