workqueuecfg

package
v10.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 15, 2026 License: AGPL-3.0 Imports: 8 Imported by: 0

Documentation

Overview

Package workqueuecfg assembles a work queue from environment configuration.

There is one thing to build and one dependency to build it from: a database.Client speaking Postgres. The dialect is not configured here at all — it comes off the client, so the SQL cannot disagree with the database it runs against.

NewQueue is generic over the key type, which the caller names at the call site. That is the only part of a queue the environment cannot express: a key is a Go type, so a config file has nothing to say about it.

Why there is no Config here

Every other config subpackage in this module declares its own Config, and this one deliberately does not — it takes *workqueue.Config directly.

Those types earn their place by being a different shape than any single leaf config: cachecfg.Config selects a provider and carries a circuit breaker, outboxcfg.Config pairs a message queue with a relay, webhookscfg.Config gathers a worker, an HTTP client, and a breaker. Where one of them does nest a leaf package's config, that config is named for the role it plays there — audit.RetentionConfig, saga.WorkerConfig, outbox.RelayConfig.

A work queue has exactly one thing to configure, so a wrapper here would hold a single workqueue.Config field and nothing else. It would carry env:",init" with no envPrefix, leaving every variable name identical; its EnsureDefaults and ValidateWithContext would each forward one call to the leaf's; and workqueue.New already rejects a nil config, applies defaults, and validates, so the forwarding would run twice. That is a level of nesting in JSON and YAML in exchange for nothing.

Resist adding one back for symmetry. A consumer that wants the queue under its own key nests workqueue.Config in its application config the way uploadscfg.Config nests objectstorage.Config.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewQueue

func NewQueue[K comparable](
	ctx context.Context,
	cfg *workqueue.Config,
	client database.Client,
	opts ...Option,
) (*workqueue.Queue[K], error)

NewQueue builds a Queue from configuration.

client must speak Postgres: this package's SQL is written against it rather than reduced to a portable subset, and workqueue.New returns dialect.ErrUnsupported for anything else. See the workqueue package doc for which construct is the binding one.

K is the key type the queue schedules work for, and is the caller's to name:

queue, err := workqueuecfg.NewQueue[OrderID](ctx, cfg, client)

Explicit options run after the config-derived ones, so a caller can still override anything — including the key codec, which configuration has no way to express.

The config is defaulted and validated by workqueue.New rather than here, so there is one place that decides what a usable queue config is.

The returned Queue owns a goroutine and must be Closed.

func RegisterQueue

func RegisterQueue[K comparable](i do.Injector)

RegisterQueue registers a *workqueue.Queue[K] with the injector. It is generic because a queue schedules work for one concrete key type; an application draining two kinds of work registers each separately.

Prerequisites: *workqueue.Config and database.Client must be registered in the injector before the Queue is invoked.

A Queue owns a goroutine and has to be Closed, and the injector will not do it: do recognizes a Shutdown method, and this module's background components spell that Close. Close it from the same place you shut the rest of them down — after ingress is gone, so a request still in flight can finish enqueueing.

Types

type Option

type Option func(*options)

Option configures how this package's constructors assemble what they build.

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.

WithQueueOptions passes options through to the queue itself. It cannot be a second variadic on the constructor: Go allows one per function, and that slot is what makes the observability optional.

func WithLogger

func WithLogger(logger logging.Logger) Option

WithLogger attaches a logger. An absent logger logs nowhere.

func WithMetricsProvider

func WithMetricsProvider(metricsProvider metrics.Provider) Option

WithMetricsProvider attaches a metrics provider. An absent provider records nothing — including the depth and age gauges, which are the only way to see that a queue has stopped draining.

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 WithQueueOptions

func WithQueueOptions(opts ...workqueue.Option) Option

WithQueueOptions passes opts to NewQueue, which applies them after the options it derives from configuration — so a caller can override anything. It is how a custom key codec reaches a queue built from configuration, since a codec is a Go value the environment cannot name.

func WithTracerProvider

func WithTracerProvider(tracerProvider tracing.Provider) Option

WithTracerProvider attaches a tracer provider, enabling spans on the instrumented operations. An absent tracer provider traces nowhere.

Jump to

Keyboard shortcuts

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