rabbitmq

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2026 License: MIT Imports: 11 Imported by: 0

README

go-queue RabbitMQ compatibility adapter

This module preserves the backend-neutral go-queue worker contract while delegating RabbitMQ connections, publishing, consumption, recovery, and broker settlement to go-rabbitmq-queues. New RabbitMQ-native applications should use that package directly.

Install

go get github.com/faustbrian/go-queue/rabbitmq

Quick start

config := rabbitmq.NativeConfig{
    Connection: rabbitmqqueue.ConnectionConfig{
        Endpoints: []rabbitmqqueue.Endpoint{{Host: "rabbitmq.internal", Port: 5671}},
        VirtualHost: "/orders",
        Credentials: credentialProvider,
        TLS: rabbitmqqueue.TLSConfig{ServerName: "rabbitmq.internal"},
        DialTimeout: 5 * time.Second,
        Heartbeat: 30 * time.Second,
        Recovery: rabbitmqqueue.RecoveryPolicy{
            MaxAttempts: 8,
            InitialDelay: 100 * time.Millisecond,
            MaxDelay: 5 * time.Second,
        },
    },
    Producer: rabbitmqqueue.ProducerConfig{
        Limits: rabbitmqqueue.DefaultLimits(),
        MaxOutstanding: 256,
        PublishTimeout: 5 * time.Second,
    },
    Consumer: rabbitmqqueue.ConsumerConfig{
        Limits: rabbitmqqueue.DefaultLimits(),
        Queue: rabbitmqqueue.QueueReference{Name: "orders", Type: rabbitmqqueue.QueueQuorum},
        Name: "orders-worker",
        Prefetch: 32,
        Concurrency: 8,
        HandlerTimeout: time.Minute,
        MaxRequeues: 1,
        Failure: rabbitmqqueue.Reject(false),
    },
    MessageID: func(task core.TaskMessage) (string, error) {
        return stableApplicationID(task)
    },
}

worker, err := rabbitmq.NewWorkerE(
    rabbitmq.WithNativeConfig(config),
    rabbitmq.WithQueue("orders"),
    rabbitmq.WithTag("orders-worker"),
    rabbitmq.WithExchangeName("orders.events"),
    rabbitmq.WithExchangeType(rabbitmq.ExchangeTopic),
    rabbitmq.WithRoutingKey("orders.created"),
)

The producer opens during construction. The consumer opens lazily on the first Request, so publishing never creates a consumer.

API reference

  • NativeConfig binds the adapter to explicit native connection, producer, consumer, queue-type, and message-identity policy.
  • NewWorkerE returns setup failures; NewWorker retains the legacy panic-on- construction-failure behavior.
  • Worker.Queue, Worker.Request, Worker.Run, and Worker.Shutdown preserve the go-queue worker surface.
  • Existing routing and lifecycle options remain source-compatible where the adapter can preserve their semantics. WithNativeConfig is mandatory.

The complete exported API is available on pkg.go.dev.

Topology ownership

Production exchanges, queues, bindings, dead-letter policy, and permissions remain infrastructure-owned, preferably by the RabbitMQ Kubernetes Operators. Configure NativeConfig with the same identities and queue type. The adapter does not declare or repair production topology.

Settlement and failure policy

  • Successful handlers ACK only after the native broker settlement completes.
  • A bare Nack and canceled or infrastructure failures requeue the source.
  • Retryable failures publish a mandatory persistent replacement with the same message ID and an incremented bounded attempt, then ACK the source only after confirmation.
  • Permanent, malformed, and exhausted failures publish to the configured terminal route with stable classification and source metadata before ACK.
  • Returned, rejected, not-sent, ambiguous, or failed replacement publications leave the source recoverable.

Replacement publication and source acknowledgement remain separate effects. A crash after the replacement is confirmed but before the source ACK can produce a duplicate. Applications must remain idempotent. The adapter never claims exactly-once processing.

Migration and rollback

  1. Create operator-owned source and terminal topology matching NativeConfig.
  2. Supply a stable outbound MessageID. For legacy deliveries without an AMQP message ID, optionally supply DeliveryMessageID; an error or empty result requeues the source.
  3. Deploy one bounded canary worker and verify publish confirmations, redeliveries, retry attempts, terminal records, backlog, and shutdown.
  4. Expand only after the old and adapter workers demonstrate compatible job outcomes. Do not run both implementations against incompatible topology or retry policy.
  5. Roll back by draining adapter consumers before restoring the prior worker. Retain the same topology and message-ID derivation so confirmed replacements and redeliveries remain deduplicatable.

Limitations

  • WithNativeConfig is required.
  • Manual acknowledgement is required; WithAutoAck(true) is rejected.
  • Direct and topic exchanges are supported. Fanout and headers are rejected because their legacy job migration semantics have not been established.
  • Native event distribution, RPC, independent fan-out, topology APIs, and advanced RabbitMQ policy are intentionally not projected through go-queue.
  • TLS verification is mandatory through go-rabbitmq-queues.

Security

Credential providers must return fresh owned credentials. Do not include credentials, certificates, payloads, or arbitrary headers in logs or errors. Message identity and failure codes must be stable, bounded, and non-sensitive.

CI broker evidence runs with Go 1.27.0 on Ubuntu 24.04 amd64 and RabbitMQ 4.3.5 over verified TLS.

FAQ

Should new services use this module?

Only when they must participate in a go-queue job workflow. Use go-rabbitmq-queues for RabbitMQ-native messaging.

Does a successful publish mean the handler ran?

No. It means RabbitMQ confirmed the mandatory publication and did not return it as unroutable. Consumer execution and settlement happen later.

Does broker recovery make processing exactly once?

No. Delivery and settlement remain at least once, and replacement publication has an explicit duplicate window.

Release notes

See CHANGELOG.md for module-specific behavior and migration changes. This module uses directory-prefixed tags such as rabbitmq/v1.0.0.

Documentation

Overview

Package rabbitmq adapts the backend-neutral go-queue worker contract to the RabbitMQ-native policy implemented by github.com/faustbrian/go-rabbitmq-queues.

Applications that need exchanges, independent fan-out, queue-type-specific policy, native publications, or direct delivery settlement should use go-rabbitmq-queues instead. This module exists for bounded migration of go-queue job workers.

Index

Examples

Constants

View Source
const (
	ExchangeDirect  = "direct"
	ExchangeFanout  = "fanout"
	ExchangeTopic   = "topic"
	ExchangeHeaders = "headers"
)

Predefined RabbitMQ exchange types for use in configuration. - ExchangeDirect: Direct exchange type. - ExchangeFanout: Fanout exchange type. - ExchangeTopic: Topic exchange type. - ExchangeHeaders: Headers exchange type.

Variables

This section is empty.

Functions

This section is empty.

Types

type DeadLetterConfig

type DeadLetterConfig struct {
	Exchange            string
	Queue               string
	RoutingKey          string
	MaxDeliveryAttempts uint32
}

DeadLetterConfig owns RabbitMQ terminal routing and bounded delivery policy.

type NativeConfig

type NativeConfig struct {
	Connection        rabbitmqqueue.ConnectionConfig
	Producer          rabbitmqqueue.ProducerConfig
	Consumer          rabbitmqqueue.ConsumerConfig
	MessageID         func(core.TaskMessage) (string, error)
	DeliveryMessageID func(rabbitmqqueue.Delivery, *job.Message) (string, error)
}

NativeConfig supplies explicit native connection, resource bounds, queue type, and stable application message identity to the compatibility adapter.

type Option

type Option func(*options)

Option is a functional option type for configuring the options struct. It allows for flexible and composable configuration of RabbitMQ workers and queues.

func WithAddr deprecated

func WithAddr(addr string) Option

WithAddr retains source compatibility with the legacy direct-AMQP worker. NativeConfig.Connection owns endpoints, credentials, virtual host, and TLS; the compatibility adapter does not use this URI.

Deprecated: configure WithNativeConfig instead.

func WithAutoAck

func WithAutoAck(val bool) Option

WithAutoAck enables or disables automatic message acknowledgment.

Parameters: - val: true to enable auto-ack, false to disable.

Returns: - Option: Functional option to set autoAck.

func WithDeadLetter

func WithDeadLetter(config DeadLetterConfig) Option

WithDeadLetter identifies the infrastructure-owned durable terminal exchange, queue, routing key, and maximum delivery attempts. The adapter publishes to the exchange and routing key but does not declare or repair the queue.

func WithExchangeName

func WithExchangeName(val string) Option

WithExchangeName sets the name of the AMQP exchange.

Parameters: - val: The exchange name.

Returns: - Option: Functional option to set the exchange name.

Exchanges are AMQP 0-9-1 entities where messages are sent to. Exchanges take a message and route it into zero or more queues.

func WithExchangeType

func WithExchangeType(val string) Option

WithExchangeType sets the type of the AMQP exchange. The compatibility adapter accepts direct and topic exchanges. Fanout and headers constants remain for source compatibility but NewWorkerE rejects them.

Parameters: - val: The exchange type (direct, fanout, topic, headers).

Returns: - Option: Functional option to set the exchange type.

The routing algorithm used depends on the exchange type and rules called bindings. AMQP 0-9-1 brokers provide four exchange types: - Direct exchange (Empty string) and amq.direct - Fanout exchange amq.fanout - Topic exchange amq.topic - Headers exchange amq.match (and amq.headers in RabbitMQ)

func WithLogger

func WithLogger(l queue.Logger) Option

WithLogger sets a custom logger for the worker or queue.

Parameters: - l: The logger instance.

Returns: - Option: Functional option to set the logger.

func WithNativeConfig

func WithNativeConfig(config NativeConfig) Option

WithNativeConfig enables the compatibility adapter with explicit native connection, resource, queue-type, and stable message-identity policy.

func WithPublishTimeout

func WithPublishTimeout(timeout time.Duration) Option

WithPublishTimeout bounds each RabbitMQ publish operation.

func WithQueue

func WithQueue(val string) Option

WithQueue sets the name of the queue to use.

Parameters: - val: The queue name.

Returns: - Option: Functional option to set the queue name.

func WithReconnectConfig deprecated

func WithReconnectConfig(config ReconnectConfig) Option

WithReconnectConfig retains source compatibility with the legacy worker. NativeConfig.Connection.Recovery owns startup and runtime recovery.

Deprecated: configure WithNativeConfig instead.

func WithRequestTimeout

func WithRequestTimeout(timeout time.Duration) Option

WithRequestTimeout sets how long Request waits for a RabbitMQ delivery.

func WithRoutingKey

func WithRoutingKey(val string) Option

WithRoutingKey sets the AMQP routing key.

Parameters: - val: The routing key.

Returns: - Option: Functional option to set the routing key.

func WithRunFunc

func WithRunFunc(fn func(context.Context, core.TaskMessage) error) Option

WithRunFunc sets the function to execute for each task.

Parameters: - fn: The function to run for each task message.

Returns: - Option: Functional option to set the run function.

func WithTag

func WithTag(val string) Option

WithTag sets the consumer tag for the worker.

Parameters: - val: The consumer tag.

Returns: - Option: Functional option to set the tag.

type ReconnectConfig

type ReconnectConfig struct {
	MaxRetries   int
	InitialDelay time.Duration
	MaxDelay     time.Duration
}

ReconnectConfig is retained for source compatibility. NativeConfig.Connection.Recovery owns runtime recovery for compatibility-adapter workers.

type Worker

type Worker struct {
	// contains filtered or unexported fields
}

Worker preserves the go-queue worker contract while delegating RabbitMQ policy and resource ownership to go-rabbitmq-queues.

func NewWorker

func NewWorker(opts ...Option) *Worker

NewWorker creates a compatibility worker and panics when its explicit native policy is invalid or its producer cannot be opened.

func NewWorkerE

func NewWorkerE(opts ...Option) (*Worker, error)

NewWorkerE creates a compatibility worker with an eagerly opened producer. The consumer remains unopened until Request is called.

Example
package main

import (
	"context"
	"time"

	"github.com/faustbrian/go-queue/core"
	rabbitmq "github.com/faustbrian/go-queue/rabbitmq"

	rabbitmqqueue "github.com/faustbrian/go-rabbitmq-queues"
)

func main() {
	credentials := rabbitmqqueue.CredentialProviderFunc(
		func(context.Context) (rabbitmqqueue.Credentials, error) {
			return rabbitmqqueue.Credentials{Username: "worker", Password: []byte("owned-secret")}, nil
		},
	)
	_, _ = rabbitmq.NewWorkerE(
		rabbitmq.WithNativeConfig(rabbitmq.NativeConfig{
			Connection: rabbitmqqueue.ConnectionConfig{
				Endpoints:   []rabbitmqqueue.Endpoint{{Host: "rabbitmq.internal", Port: 5671}},
				VirtualHost: "/", Credentials: credentials,
				TLS:         rabbitmqqueue.TLSConfig{ServerName: "rabbitmq.internal"},
				DialTimeout: 5 * time.Second, Heartbeat: 30 * time.Second,
				Recovery: rabbitmqqueue.RecoveryPolicy{
					MaxAttempts: 8, InitialDelay: 100 * time.Millisecond, MaxDelay: 5 * time.Second,
				},
			},
			Producer: rabbitmqqueue.ProducerConfig{
				Limits: rabbitmqqueue.DefaultLimits(), MaxOutstanding: 256,
				PublishTimeout: 5 * time.Second,
			},
			Consumer: rabbitmqqueue.ConsumerConfig{
				Limits: rabbitmqqueue.DefaultLimits(),
				Queue:  rabbitmqqueue.QueueReference{Name: "jobs", Type: rabbitmqqueue.QueueQuorum},
				Name:   "jobs-worker", Prefetch: 32, Concurrency: 8,
				HandlerTimeout: time.Minute, MaxRequeues: 1,
				Failure: rabbitmqqueue.Reject(false),
			},
			MessageID: func(core.TaskMessage) (string, error) { return "stable-job-id", nil },
		}),
		rabbitmq.WithQueue("jobs"),
		rabbitmq.WithTag("jobs-worker"),
		rabbitmq.WithExchangeName("jobs.events"),
		rabbitmq.WithExchangeType(rabbitmq.ExchangeTopic),
		rabbitmq.WithRoutingKey("jobs.created"),
	)
}

func (*Worker) BackendName

func (*Worker) BackendName() string

BackendName identifies RabbitMQ in lifecycle events.

func (*Worker) Queue

func (worker *Worker) Queue(task core.TaskMessage) error

Queue publishes one mandatory persistent task and waits for a definitive broker confirmation.

func (*Worker) QueueName

func (worker *Worker) QueueName() string

QueueName returns the configured RabbitMQ queue.

func (*Worker) Request

func (worker *Worker) Request() (core.TaskMessage, error)

Request returns one decoded task from the bounded native delivery bridge.

func (*Worker) Run

func (worker *Worker) Run(ctx context.Context, task core.TaskMessage) error

Run executes the configured go-queue handler.

func (*Worker) Shutdown

func (worker *Worker) Shutdown() error

Shutdown closes consumer and producer resources once. Repeated calls return queue.ErrQueueShutdown.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL