API Reference
Constructors and the public method surface of the watermill-kubemq Publisher, Subscriber, and CQPublisher types, plus repository Make targets.
This page documents the public API surface of the watermill-kubemq plugin: the three
constructors and the methods on each returned type. The configuration fields those
constructors accept — and the enums, validation rules, and marshaling contract — are in the
Configuration reference. Every entry is drawn from the plugin source.
Constructors
The package exposes three constructors. Each validates its config (mutating it in place to
apply defaults), opens or reuses a kubemq-go/v2 client, and returns a ready-to-use instance.
| Constructor | Signature | Returns |
|---|---|---|
NewPublisher | NewPublisher(config PublisherConfig) | (*Publisher, error) |
NewSubscriber | NewSubscriber(config SubscriberConfig) | (*Subscriber, error) |
NewCQPublisher | NewCQPublisher(config CQConfig) | (*CQPublisher, error) |
pub, err := kubemq.NewPublisher(kubemq.PublisherConfig{
Address: "localhost:50000",
Pattern: kubemq.PatternEvents,
})
sub, err := kubemq.NewSubscriber(kubemq.SubscriberConfig{
Address: "localhost:50000",
Pattern: kubemq.PatternEvents,
})
cq, err := kubemq.NewCQPublisher(kubemq.CQConfig{
Address: "localhost:50000",
DefaultTimeout: 5 * time.Second,
})When ExistingClient is set on any config, the constructor reuses that client and ignores
Address, ClientID, AuthToken, and TLS. In that case the caller owns the client and is
responsible for closing it; calling Close() on the Publisher, Subscriber, or CQPublisher will
not close a client it does not own.
Publisher API
Publisher implements Watermill's message.Publisher interface and is safe for concurrent
use. Each instance serves a single pattern (Events, EventsStore, or Queues), selected at
construction.
| Method | Signature | Description |
|---|---|---|
Publish | Publish(topic string, messages ...*message.Message) error | Publishes one or more messages to topic using the configured pattern. |
Close | Close() error | Closes the active streaming handle and, if the client is owned, the gRPC client. Idempotent. |
HealthCheck | HealthCheck(ctx context.Context) error | Pings the broker to verify connectivity. |
msg := message.NewMessage(watermill.NewUUID(), []byte("hello events"))
if err := pub.Publish("my-topic", msg); err != nil {
log.Printf("publish error: %v", err)
}
defer pub.Close()A few behaviors worth noting:
Publishreturns an error if the publisher has already been closed, or iftopicis empty.- By default the publisher uses KubeMQ's streaming send path. Setting
DisableStreaming: trueswitches to synchronous per-message sends. Closeis guarded by an atomic compare-and-swap, so calling it more than once is safe and only the first call has any effect.
Subscriber API
Subscriber implements Watermill's message.Subscriber interface. A single subscriber serves
one pattern but supports multiple concurrent Subscribe calls on different topics — each
gets its own goroutine and output channel.
| Method | Signature | Description |
|---|---|---|
Subscribe | Subscribe(ctx context.Context, topic string) (<-chan *message.Message, error) | Subscribes to topic and returns a channel of Watermill messages. |
Close | Close() error | Cancels all active subscriptions, waits for their goroutines to drain, and closes the client if owned. Idempotent. |
HealthCheck | HealthCheck(ctx context.Context) error | Pings the broker to verify connectivity. |
messages, err := sub.Subscribe(context.Background(), "my-topic")
if err != nil {
log.Fatal(err)
}
for msg := range messages {
log.Printf("received: %s", string(msg.Payload))
msg.Ack() // only meaningful for the Queues pattern
}Subscribereturns an error if the subscriber is closed ortopicis empty.- For the Queues pattern, each delivered message is bridged to KubeMQ settlement: calling
msg.Ack()acknowledges and removes it, whilemsg.Nack()returns it to the queue for redelivery. For Events and EventsStore, ack/nack on the Watermill message has no effect on the broker. Closecancels every active subscription's context and blocks until all subscription goroutines (and per-message ack/nack bridge goroutines) have finished.
CQPublisher API
CQPublisher is a separate API — it does not implement message.Publisher. It wraps
KubeMQ's native Commands and Queries for low-latency request-reply.
| Method | Signature | Description |
|---|---|---|
SendCommand | SendCommand(ctx, channel string, msg *message.Message, timeout time.Duration) (*kubemqSDK.CommandResponse, error) | Sends a command and returns the native KubeMQ command response. |
SendQuery | SendQuery(ctx, channel string, msg *message.Message, timeout time.Duration) (*message.Message, error) | Sends a query and returns the reply as a Watermill message. |
SendQueryWithCache | SendQueryWithCache(ctx, channel string, msg *message.Message, timeout time.Duration, cacheKey string, cacheTTL time.Duration) (*message.Message, error) | Like SendQuery, but with explicit per-call cache key and TTL. |
Close | Close() error | Closes the client if owned. Idempotent. |
import "time"
cq, _ := kubemq.NewCQPublisher(kubemq.CQConfig{
Address: "localhost:50000",
DefaultTimeout: 5 * time.Second,
})
defer cq.Close()
// Query (request-reply with a returned payload)
q := message.NewMessage(watermill.NewUUID(), []byte(`{"prompt":"classify this text"}`))
reply, err := cq.SendQuery(ctx, "ml.classify", q, 10*time.Second)
if err != nil {
log.Fatalf("query failed: %v", err)
}
log.Printf("reply: %s", string(reply.Payload))
// Command (request-reply with execution confirmation)
c := message.NewMessage(watermill.NewUUID(), []byte(`{"action":"deploy"}`))
resp, err := cq.SendCommand(ctx, "ops.deploy", c, 30*time.Second)Behavior notes:
- If
timeoutis<= 0on any send call, theDefaultTimeoutfromCQConfigis used. SendQueryandSendQueryWithCachereturn an error when the responder reports the query as not executed.- When
CacheKeyis set onCQConfig,SendQueryapplies it (andCacheTTL) to every query.SendQueryWithCacheinstead takes the cache key and TTL per call.
For the full request-reply walkthrough — including the Watermill requestreply component over
Queues — see Commands & Queries.
Make targets
The repository Makefile provides the following targets:
| Target | Command | Purpose |
|---|---|---|
test | go test -v -count=1 ./pkg/kubemq/... | Unit tests. |
test-race | go test -v -race -count=1 ./pkg/kubemq/... | Unit tests with the race detector. |
test-integration | go test ... -tags=integration -timeout=5m ./pkg/kubemq/... | Integration tests (require a running broker). |
test-compatibility | go test ... -tags=compatibility -timeout=10m ./pkg/kubemq/... | Watermill pubsub/tests.TestPubSub compatibility suite. |
lint | golangci-lint run ./... | Lint. |
coverage | go test ... -coverprofile=coverage.out ./pkg/kubemq/... | Coverage profile and total summary. |
make test
make test-race
docker-compose up -d
make test-integration
make test-compatibilityRelated
Was this page helpful?
Queues with Ack/Nack & DLQ
Use the reliable Queues pattern with explicit acknowledgment, competing consumers, delayed and expiring messages, and dead-letter queues.
Configuration Reference
Every PublisherConfig, SubscriberConfig, CQConfig, QueueMessagePolicy, and TLSConfig field, plus enums, validation rules, marshaling, and metadata keys.