Documentation
¶
Overview ¶
Package messagequeuecfg selects and builds messagequeue publisher and consumer providers from configuration, over Redis, SQS, GCP Pub/Sub, Kafka, or noop.
The publishing and the consuming halves are configured independently — Config holds a MessageQueueConfig for each, with its own provider and credentials — so a service that reads from Kafka and writes to SQS is expressible, and so a process that only publishes never has to name a consumer it will not build.
Index ¶
- Constants
- Variables
- func NewConsumerProvider(ctx context.Context, c *Config, opts ...Option) (messagequeue.ConsumerProvider, error)
- func NewPublisherProvider(ctx context.Context, c *Config, opts ...Option) (messagequeue.PublisherProvider, error)
- func RegisterMessageQueue(i do.Injector)
- type Config
- type MessageQueueConfig
- type Option
Constants ¶
const ( // ProviderRedis is used to refer to redis. ProviderRedis provider = "redis" // ProviderSQS is used to refer to sqs. ProviderSQS provider = "sqs" // ProviderPubSub is used to refer to GCP Pub/Sub. ProviderPubSub provider = "pubsub" // ProviderKafka is used to refer to Kafka. ProviderKafka provider = "kafka" // ProviderNoop discards published messages and consumes nothing. It must be // selected deliberately — it is never what an unrecognized provider falls // back to. ProviderNoop provider = "noop" )
Variables ¶
var (
ErrNilConfig = errors.New("nil config provided")
)
Functions ¶
func NewConsumerProvider ¶
func NewConsumerProvider(ctx context.Context, c *Config, opts ...Option) (messagequeue.ConsumerProvider, error)
NewConsumerProvider provides a ConsumerProvider.
Each provider is built into a variable and returned only once its error is known to be nil. The provider constructors return their own concrete types, so returning one straight through would convert a nil *redis.ConsumerProvider into a non-nil messagequeue.ConsumerProvider on the error path, and a caller testing the result against nil would find a value that panics on first use.
func NewPublisherProvider ¶
func NewPublisherProvider(ctx context.Context, c *Config, opts ...Option) (messagequeue.PublisherProvider, error)
NewPublisherProvider provides a PublisherProvider.
Each provider is built into a variable and returned only once its error is known to be nil. The provider constructors return their own concrete types, so returning one straight through would convert a nil *redis.PublisherProvider into a non-nil messagequeue.PublisherProvider on the error path, and a caller testing the result against nil would find a value that panics on first use.
func RegisterMessageQueue ¶
RegisterMessageQueue registers both messagequeue.ConsumerProvider and messagequeue.PublisherProvider with the injector.
Types ¶
type Config ¶
type Config struct {
Consumer MessageQueueConfig `envPrefix:"CONSUMER_" json:"consumer,omitzero" yaml:"consumer,omitempty"`
Publisher MessageQueueConfig `envPrefix:"PUBLISHER_" json:"publisher,omitzero" yaml:"publisher,omitempty"`
// contains filtered or unexported fields
}
Config is used to indicate how the messaging provider should be configured.
func (*Config) ValidateWithContext ¶
ValidateWithContext validates a Config struct.
Both halves are invoked explicitly, for the reason MessageQueueConfig's own validation gives: naming a struct-valued field to ozzo is indistinguishable from not naming it, because it dereferences the field pointer before looking for the pointer-receiver Validatable. A zero Config validated clean.
type MessageQueueConfig ¶
type MessageQueueConfig struct {
Kafka kafka.Config `envPrefix:"KAFKA_" json:"kafka,omitzero" yaml:"kafka,omitempty"`
Provider provider `env:"PROVIDER" json:"provider,omitempty" yaml:"provider,omitempty"`
SQS sqs.Config `envPrefix:"SQS_" json:"sqs,omitzero" yaml:"sqs,omitempty"`
PubSub pubsub.Config `envPrefix:"PUBSUB_" json:"pubSub,omitzero" yaml:"pubSub,omitempty"`
Redis redis.Config `envPrefix:"REDIS_" json:"redis,omitzero" yaml:"redis,omitempty"`
// contains filtered or unexported fields
}
MessageQueueConfig is used to indicate how the messaging provider should be configured.
func (*MessageQueueConfig) ValidateWithContext ¶
func (c *MessageQueueConfig) ValidateWithContext(ctx context.Context) error
ValidateWithContext validates a MessageQueueConfig struct.
The selected provider's own block is validated and the others are skipped. Naming the provider used to be the whole of it, which left every leaf provider's rules unreachable: a redis queue with no addresses, a kafka one with no brokers and a pubsub one with no project all validated clean and then failed — or, for redis, did not fail, and returned a provider holding a nil client.
The sub-configs here are values rather than pointers, and each is validated through an explicit validation.By rather than left to ozzo. ValidateStruct dereferences the field pointer it is handed before looking for a Validatable, so `validation.Field(&c.Kafka)` offers ozzo a kafka.Config value — and every ValidateWithContext in this module has a pointer receiver, which a value does not satisfy. Naming the field was therefore indistinguishable from not naming it. The pointer sub-configs elsewhere in this module do not have the problem, because dereferencing a **Config leaves a *Config.
type Option ¶
type Option func(*options)
Option configures how this package's constructors assemble their providers.
The observability dependencies are options rather than parameters because every one of them is genuinely optional: an absent logger logs nowhere, an absent tracer provider traces nowhere, and an absent metrics provider records nothing. Requiring them positionally made a caller that wanted none of the three name all three anyway, usually as noops.
func WithLogger ¶
WithLogger attaches a logger. An absent logger logs nowhere.
func WithMetricsProvider ¶
WithMetricsProvider attaches a metrics provider. An absent provider records nothing.
func WithPillars ¶
func WithPillars(p *observability.Pillars) Option
WithPillars attaches a logger, tracer provider, and metrics provider in one go, for the common case where a caller has already built them together. A nil Pillars attaches nothing.
It is applied in order with the individual options, so a caller can hand over its pillars and then override one of them.
func WithTracerProvider ¶
WithTracerProvider attaches a tracer provider, enabling spans on the instrumented operations. An absent tracer provider traces nowhere.