Documentation
¶
Overview ¶
Package babelqueue is the framework-agnostic Go core of BabelQueue — "Polyglot Queues, Simplified".
It implements the canonical wire envelope so a Go service interoperates byte-for-byte with the PHP/Laravel, Python, ... SDKs over any broker, with no language-specific serialization on the wire:
env, _ := babelqueue.Make("urn:babel:orders:created", map[string]any{"order_id": 1042})
body, _ := env.Encode() // publish body to Redis / RabbitMQ / ...
in, _ := babelqueue.Decode(body)
if in.Accepts() {
switch in.URN() {
case "urn:babel:orders:created":
// handle in.Data ...
}
}
The package depends only on the standard library.
Full spec: https://babelqueue.com
Index ¶
- Constants
- Variables
- func BypassExternalEffects(ctx context.Context, fn func() error) error
- func HeadersFromContext(ctx context.Context) map[string]string
- func IsReplay(ctx context.Context) bool
- func TruncateDeclaredVersion(v string) string
- type App
- func (a *App) Consume(ctx context.Context, queue ...string) error
- func (a *App) Drain(ctx context.Context, queue string, max int) (int, error)
- func (a *App) Handle(urn string, handler Handler)
- func (a *App) Publish(ctx context.Context, urn string, data map[string]any, opts ...Option) (string, error)
- func (a *App) PublishWithHeaders(ctx context.Context, urn string, data map[string]any, ...) (string, error)
- func (a *App) Run(ctx context.Context) error
- type AppOption
- func WithAckErrorHandler(fn func(ctx context.Context, msg *ReceivedMessage, err error)) AppOption
- func WithDeadLetter(enabled bool) AppOption
- func WithDeadLetterErrorHandler(fn func(ctx context.Context, msg *ReceivedMessage, err error)) AppOption
- func WithDeadLetterQueue(queue string) AppOption
- func WithDeadLetterSuffix(suffix string) AppOption
- func WithDefaultQueue(queue string) AppOption
- func WithMaxAttempts(n int) AppOption
- func WithPollTimeout(d time.Duration) AppOption
- func WithReleaseErrorHandler(fn func(ctx context.Context, msg *ReceivedMessage, err error)) AppOption
- func WithRetryBackoff(d time.Duration) AppOption
- func WithRewindPause(d time.Duration) AppOption
- func WithUnknownURNReleaseDelay(d time.Duration) AppOption
- func WithUnknownURNStrategy(strategy string) AppOption
- type DeadLetter
- type Envelope
- type Handler
- type HeaderPublisher
- type InMemoryTransport
- func (t *InMemoryTransport) Ack(_ context.Context, _ *ReceivedMessage) error
- func (t *InMemoryTransport) Pop(_ context.Context, queue string, _ time.Duration) (*ReceivedMessage, error)
- func (t *InMemoryTransport) Publish(_ context.Context, queue, body string) error
- func (t *InMemoryTransport) PublishWithHeaders(_ context.Context, queue, body string, headers map[string]string) error
- func (t *InMemoryTransport) Size(queue string) int
- type Meta
- type Option
- type ReceivedMessage
- type RedriveItem
- type RedriveOptions
- type RedriveResult
- type Releaser
- type Rewinder
- type RoutedPublisher
- type Transport
Constants ¶
const ( StrategyFail = "fail" // surface an error; let the worker decide StrategyDelete = "delete" // drop the message StrategyRelease = "release" // requeue for another consumer StrategyDeadLetter = "dead_letter" // route to the dead-letter queue )
Unknown-URN strategies: what a consumer does with a message whose URN has no registered handler. These mirror the constants in every other SDK core.
const HeaderReplayBypass = "bq-replay-bypass"
HeaderReplayBypass is the out-of-band transport header Redrive stamps (when its options set Bypass) on a replayed message, and that the App runtime surfaces to the handler as IsReplay. It lets a handler skip external side-effects that already ran, with no change to the frozen envelope (ADR-0027).
const SchemaVersion = 1
SchemaVersion is the wire envelope schema version this core implements. It is versioned independently of the module's release (package) version: the wire format only changes when this number does.
const SourceLang = "go"
SourceLang is stamped into meta.lang for envelopes produced by this core.
Variables ¶
var ( // ErrEmptyURN is returned by Make when the URN is blank — a polyglot message // must expose a stable, non-empty URN so consumers can identify it without // relying on any language-specific class name. ErrEmptyURN = errors.New("babelqueue: a polyglot message must expose a stable, non-empty URN") // ErrUnknownURN signals that no handler is mapped for a message URN. ErrUnknownURN = errors.New("babelqueue: no handler is mapped for the message URN") // ErrReleaseUnsupported is returned (or wrapped) by a [Releaser] that cannot // release this particular message in place — e.g. a client lacking the broker's // release call, or a message without a reservation handle. Only this error makes // the [App] fall back to re-publish + ack; any other Release error leaves the // message reserved so the broker redelivers it (it is never deleted). ErrReleaseUnsupported = errors.New("babelqueue: in-place release is unsupported for this message") )
Sentinel errors returned by the core.
Functions ¶
func BypassExternalEffects ¶ added in v1.5.0
BypassExternalEffects runs fn unless the current message is a replay (see IsReplay), in which case fn is skipped and nil is returned. Wrap the external, non-idempotent side of a handler — sending an email, charging a card, calling a third party — so a replay re-runs the idempotent core but does not re-fire effects that already happened:
app.Handle("urn:babel:orders:created", func(ctx context.Context, env babelqueue.Envelope) error {
saveOrder(env) // idempotent core — always runs
return babelqueue.BypassExternalEffects(ctx, func() error {
return sendConfirmationEmail(env) // external effect — skipped on replay
})
})
func HeadersFromContext ¶ added in v1.6.0
HeadersFromContext returns the out-of-band transport headers that arrived with the message currently being handled, or nil when none were carried (or the transport does not surface headers). The returned map is read-only — do not mutate it. It is the consume-side counterpart of HeaderPublisher: a handler or an optional wrapper (e.g. the otel module's WrapHandler) reads per-message metadata that travels beside the frozen envelope, never in it (GR-1).
func IsReplay ¶ added in v1.5.0
IsReplay reports whether the message currently being handled was redriven with the replay-bypass marker set — i.e. this is a deliberate replay, and external side-effects that already happened should be skipped. It reads the marker the runtime put on the context from the HeaderReplayBypass transport header.
func TruncateDeclaredVersion ¶ added in v1.11.0
TruncateDeclaredVersion caps a rejected bq-schema-version value at 64 characters (runes) followed by "...", so a huge header cannot inflate a log line, a route or a DLQ record. A value of at most 64 characters is returned unchanged. Transports apply it to the rejected value before reporting it or building the reserved route; the gate comparison itself always uses the full, untrimmed value.
Types ¶
type App ¶ added in v0.2.0
type App struct {
// contains filtered or unexported fields
}
App is the optional BabelQueue runtime: it produces and consumes polyglot messages over a Transport. Routing is by URN; the wire format is the canonical envelope (via the same core codec), so it interoperates with the PHP/Laravel, Python, ... SDKs. Retry uses the top-level attempts counter; failures past MaxAttempts go to a dead-letter queue when enabled.
The core codec (Make/[Encode]/Decode) has zero dependencies; the App adds no dependencies either (broker drivers live in separate modules). An App is safe for concurrent Publish calls; run Consume from a single goroutine per queue.
func (*App) Consume ¶ added in v0.2.0
Consume processes messages from the default queue (or the optional override) until ctx is cancelled. It blocks; run it in its own goroutine. A single bad message never stops the loop — it is retried or dead-lettered.
func (*App) Drain ¶ added in v0.2.0
Drain processes up to max messages from queue and returns the count, stopping early when the queue is empty. With max <= 0 it drains until empty. Useful for tests and one-shot workers.
func (*App) Handle ¶ added in v0.2.0
Handle registers handler as the consumer for urn (the last registration wins).
func (*App) Publish ¶ added in v0.2.0
func (a *App) Publish(ctx context.Context, urn string, data map[string]any, opts ...Option) (string, error)
Publish builds the canonical envelope for (urn, data) and publishes it. It returns the message id (meta.id). Pass envelope options such as WithQueue or WithTraceID to override the target queue or continue a trace.
func (*App) PublishWithHeaders ¶ added in v1.6.0
func (a *App) PublishWithHeaders( ctx context.Context, urn string, data map[string]any, headers map[string]string, opts ...Option, ) (string, error)
PublishWithHeaders builds the canonical envelope for (urn, data) and publishes it together with out-of-band transport headers, returning the message id (meta.id). The headers ride beside the frozen envelope on the transport's per-message metadata channel (e.g. a W3C traceparent for cross-hop span linkage, ADR-0028) — the envelope itself is never touched (GR-1).
It is the produce-side counterpart of the headers the runtime surfaces to a handler via HeadersFromContext. When the transport implements HeaderPublisher the headers are propagated; otherwise it transparently falls back to a plain publish (the headers are dropped, exactly as Redrive degrades — no error, no regression), so callers need not branch on transport capability. Passing nil or empty headers is equivalent to App.Publish.
type AppOption ¶ added in v0.2.0
type AppOption func(*App)
AppOption customizes NewApp.
func WithAckErrorHandler ¶ added in v1.9.0
func WithAckErrorHandler(fn func(ctx context.Context, msg *ReceivedMessage, err error)) AppOption
WithAckErrorHandler registers fn to observe a failed acknowledgement (e.g. an SQS DeleteMessage error). An ack failure is reported distinctly and never treated as a handler failure: a message whose handler succeeded is not retried, released or dead-lettered because its ack failed — the broker redelivers it once its reservation lapses, which consumer-side idempotency absorbs. Without a handler the error is ignored.
func WithDeadLetter ¶ added in v0.2.0
WithDeadLetter enables routing exhausted/failed messages to a dead-letter queue.
func WithDeadLetterErrorHandler ¶ added in v1.11.0
func WithDeadLetterErrorHandler(fn func(ctx context.Context, msg *ReceivedMessage, err error)) AppOption
WithDeadLetterErrorHandler registers fn to observe a failed dead-letter write of a version-gated delivery (the publish to the DLQ, or the record's encoding, failed). Such a delivery is never acknowledged on that path: the App logs the failure, reports it here, hands the message back to the broker (see Rewinder) and never retries it or runs a handler, so the gate rejects it again on redelivery and the dead-letter write is retried. Without a handler the error is only logged.
func WithDeadLetterQueue ¶ added in v0.2.0
WithDeadLetterQueue overrides the dead-letter queue name (default: the source queue plus the dead-letter suffix).
func WithDeadLetterSuffix ¶ added in v0.2.0
WithDeadLetterSuffix sets the suffix appended to the source queue to derive the dead-letter queue name (default ".dlq").
func WithDefaultQueue ¶ added in v0.2.0
WithDefaultQueue sets the queue used by Publish/Consume when none is given (default "default").
func WithMaxAttempts ¶ added in v0.2.0
WithMaxAttempts sets how many delivery attempts a message gets before it is dead-lettered or dropped (default 3).
func WithPollTimeout ¶ added in v0.2.0
WithPollTimeout sets how long Pop blocks waiting for a message each iteration (default 1s). Ignored by transports that do not block.
func WithReleaseErrorHandler ¶ added in v1.9.0
func WithReleaseErrorHandler(fn func(ctx context.Context, msg *ReceivedMessage, err error)) AppOption
WithReleaseErrorHandler registers fn to observe a failed in-place release (e.g. an SQS ChangeMessageVisibility error such as AccessDenied). A failed release is still treated as handled: the message is neither re-published nor acked, and the broker redelivers it once its reservation lapses — so the retry waits for the queue's visibility timeout instead of WithRetryBackoff. ErrReleaseUnsupported is not reported (it is a capability signal, answered by re-publish + ack). Without a handler the error is ignored.
func WithRetryBackoff ¶ added in v1.9.0
WithRetryBackoff sets how long a failed message waits before it is redelivered (default 0 = immediately). It applies to transports implementing Releaser (e.g. SQS, where it becomes the ChangeMessageVisibility timeout); transports without that capability re-publish the retry immediately.
func WithRewindPause ¶ added in v1.11.0
WithRewindPause sets how long the App waits after handing an unsettled version-gated message back to the broker before polling again (default 1s), so a persistent dead-letter outage does not spin.
func WithUnknownURNReleaseDelay ¶ added in v1.9.0
WithUnknownURNReleaseDelay sets the redelivery delay for the StrategyRelease unknown-URN strategy — the contract's unknown_urn_release_delay (default 0). Like WithRetryBackoff, it takes effect on transports implementing Releaser.
func WithUnknownURNStrategy ¶ added in v0.2.0
WithUnknownURNStrategy sets what happens to a message whose URN has no handler: one of StrategyFail, StrategyDelete, StrategyRelease, StrategyDeadLetter.
type DeadLetter ¶
type DeadLetter struct {
Reason string `json:"reason"`
Error *string `json:"error"` // null when no cause was supplied
Exception *string `json:"exception"` // null when no cause was supplied
FailedAt int64 `json:"failed_at"` // Unix milliseconds, UTC
OriginalQueue string `json:"original_queue"`
Attempts int `json:"attempts"`
Lang string `json:"lang"`
}
DeadLetter is the additive block appended to an envelope when a message is dead-lettered. The original envelope is preserved unchanged alongside it, so a consumer in any language can still read the original job, data and trace_id.
type Envelope ¶
type Envelope struct {
Job string `json:"job"` // the message URN (never a class name)
TraceID string `json:"trace_id"` // correlation id, preserved across hops
Data map[string]any `json:"data"` // the message payload
Meta Meta `json:"meta"`
Attempts int `json:"attempts"` // top-level transport retry counter
DeadLetter *DeadLetter `json:"dead_letter,omitempty"` // present only once dead-lettered
// contains filtered or unexported fields
}
Envelope is the canonical BabelQueue wire message: a strict, language-neutral JSON shape ({job, trace_id, data, meta, attempts}) that every SDK produces and consumes identically. The field order below is significant — it matches the other cores so the envelope frame encodes identically across languages. (Key order inside the user-supplied Data map is JSON-insignificant; encoding/json emits it sorted, where PHP/Python preserve insertion order — same JSON.)
func Annotate ¶
Annotate returns a copy of the envelope with a dead_letter block attached, recording why and where it failed; it does not mutate the original. A non-nil cause fills in the error message and its Go type; both serialize as JSON null when cause is nil.
func Decode ¶
Decode parses a raw JSON body into an Envelope. It accepts "urn" as an inbound alias for "job" (resolving it into Job). Unknown top-level and meta keys are kept and re-emitted by Encode; forbidden keys (message-envelope.md §10) are dropped with a warning (see Envelope.Warnings). It does not validate the contents — use Accepts for consumer-side validation. A non-object data block (e.g. a JSON array) is rejected with an error.
func Make ¶
Make builds the canonical envelope for a (urn, data) pair. It mints a fresh trace id unless WithTraceID is given, starts attempts at 0, and stamps meta with a unique id, the source language ("go"), the schema version and a millisecond timestamp. It returns ErrEmptyURN when urn is blank.
func (Envelope) Accepts ¶
Accepts reports whether a consumer should accept this envelope. It rejects a missing URN, an unsupported meta.schema_version, a blank trace_id, or missing data — the consumer-side counterpart to the producer JSON Schema. (It accepts the urn alias, unlike the stricter producer schema.)
func (Envelope) Encode ¶
Encode renders the envelope as compact UTF-8 JSON with HTML escaping disabled (unescaped slashes and unicode) — the canonical wire form shared by every SDK. The envelope frame is identical across languages; key order within the Data map follows encoding/json (sorted), which is semantically the same JSON. Unknown keys captured by Decode are written after the known fields of their object.
func (Envelope) MarshalJSON ¶ added in v1.9.0
MarshalJSON renders the known fields in canonical order, then any unknown keys captured by Decode (sorted, verbatim). An envelope without unknown keys encodes byte-for-byte as the plain struct would.
func (Envelope) URN ¶
URN returns the message URN — the canonical job, with the urn alias already resolved by Decode.
func (*Envelope) UnmarshalJSON ¶ added in v1.9.0
UnmarshalJSON decodes the known fields and captures unknown top-level and meta keys for re-emission. Forbidden keys are recorded as warnings and dropped.
func (Envelope) Warnings ¶ added in v1.9.0
Warnings returns the non-fatal problems Decode found, such as a forbidden non-canonical key (message-envelope.md §10) that was dropped. Each warning names the offending key as a JSON pointer (e.g. "/meta/max_retries"). It is empty for a clean envelope and for envelopes built with Make.
Warnings only reflect the body as the consumer received it: a transport that reconciles attempts by re-encoding the body on redelivery (SQS, Kafka, Pulsar, Artemis, Azure Service Bus) has already dropped any forbidden key there, so a redelivered message may carry no warning even though its first delivery did.
type Handler ¶ added in v0.2.0
Handler processes one decoded message. Returning an error triggers the retry / dead-letter path; returning nil acknowledges the message.
type HeaderPublisher ¶ added in v1.5.0
type HeaderPublisher interface {
PublishWithHeaders(ctx context.Context, queue, body string, headers map[string]string) error
}
HeaderPublisher is an optional Transport capability: publish a body together with out-of-band transport headers (e.g. the replay-bypass marker), for brokers that carry per-message metadata. A transport that does not implement it simply does not propagate headers — callers fall back to plain Publish (ADR-0027).
type InMemoryTransport ¶ added in v0.2.0
type InMemoryTransport struct {
// contains filtered or unexported fields
}
func NewInMemoryTransport ¶ added in v0.2.0
func NewInMemoryTransport() *InMemoryTransport
NewInMemoryTransport returns an empty in-process transport.
func (*InMemoryTransport) Ack ¶ added in v0.2.0
func (t *InMemoryTransport) Ack(_ context.Context, _ *ReceivedMessage) error
Ack is a no-op: Pop already removed the message.
func (*InMemoryTransport) Pop ¶ added in v0.2.0
func (t *InMemoryTransport) Pop(_ context.Context, queue string, _ time.Duration) (*ReceivedMessage, error)
Pop removes and returns the head of queue, or (nil, nil) when it is empty.
func (*InMemoryTransport) Publish ¶ added in v0.2.0
func (t *InMemoryTransport) Publish(_ context.Context, queue, body string) error
Publish appends body to the in-memory queue.
func (*InMemoryTransport) PublishWithHeaders ¶ added in v1.5.0
func (t *InMemoryTransport) PublishWithHeaders(_ context.Context, queue, body string, headers map[string]string) error
PublishWithHeaders appends body plus out-of-band headers (HeaderPublisher).
func (*InMemoryTransport) Size ¶ added in v0.2.0
func (t *InMemoryTransport) Size(queue string) int
Size reports how many messages are pending on queue (test helper).
type Meta ¶
type Meta struct {
ID string `json:"id"`
Queue string `json:"queue"`
Lang string `json:"lang"`
SchemaVersion int `json:"schema_version"`
CreatedAt int64 `json:"created_at"` // Unix milliseconds, UTC
}
Meta is the immutable per-message metadata block.
type Option ¶
type Option func(*makeConfig)
Option customizes Make.
func WithTraceID ¶
WithTraceID reuses an existing trace id (trace continuation) instead of minting a fresh one. A blank value is ignored.
type ReceivedMessage ¶ added in v0.2.0
type ReceivedMessage struct {
Body string
Queue string
Handle any
// Headers are out-of-band transport headers a [HeaderPublisher] carried with the
// message (e.g. the bq-replay-bypass marker). Nil for transports that don't surface
// them; reads are nil-safe.
Headers map[string]string
// DeliveryCount is the broker's native delivery count for this reservation
// (1 on the first delivery), or 0 when the transport does not track one. The
// [App] treats DeliveryCount−1 as a floor for the envelope's attempts, so the
// WithMaxAttempts bound and dead-lettering still hold when a message is released
// in place and its body cannot carry the counter (e.g. it does not decode).
DeliveryCount int
// RouteURN is an optional routing override: when non-empty the [App] looks the
// handler up by this URN instead of the decoded body's URN. A transport whose
// broker carries the URN out of band (e.g. the Pulsar bq-job property) fills it so
// routing follows the property while the body is left untouched — the handler,
// retries and the dead-letter record all keep the producer's original body.
// Empty means "route on the body URN" (the default for every other transport).
RouteURN string
}
ReceivedMessage is a message reserved from a queue, plus a transport-internal handle the transport uses to acknowledge it.
type RedriveItem ¶ added in v1.4.0
type RedriveItem struct {
MessageID string // meta.id ("" if absent or undecodable)
TraceID string
URN string
Reason string // dead_letter.reason
From string // the DLQ it was read from
To string // target queue (the plan, even on a dry run; "" when skipped/undecodable)
Redriven bool // true only when actually re-published to To
Bypassed bool // true when the bq-replay-bypass header was stamped on the redriven message
}
RedriveItem records what happened to one message during a Redrive run.
type RedriveOptions ¶ added in v1.4.0
type RedriveOptions struct {
// ToQueue overrides where messages are re-published. When empty, each message goes back
// to its own dead_letter.original_queue; set it to a sandbox queue to replay safely.
ToQueue string
// Max caps how many messages are pulled from the DLQ (0 = all currently available).
Max int
// DryRun inspects without redriving: every message is read, reported, and returned to the
// DLQ unchanged — nothing is re-published to a source/sandbox queue.
DryRun bool
// Select, when non-nil, picks which messages to redrive (e.g. by reason or URN).
// Unselected messages are returned to the DLQ unchanged.
Select func(Envelope) bool
// Bypass stamps the bq-replay-bypass transport header on each redriven message, so a
// handler can skip external side-effects that already ran (see [BypassExternalEffects]).
// It takes effect only when the transport is a [HeaderPublisher]; otherwise it is a no-op
// and the per-item Bypassed flag stays false (ADR-0027).
Bypass bool
// Timeout is the per-pop wait passed to the transport (default 1s).
Timeout time.Duration
}
RedriveOptions configures a Redrive run.
type RedriveResult ¶ added in v1.4.0
type RedriveResult struct {
Redriven int
Skipped int
Items []RedriveItem
}
RedriveResult summarizes a Redrive run.
func Redrive ¶ added in v1.4.0
func Redrive(ctx context.Context, t Transport, dlq string, opts RedriveOptions) (RedriveResult, error)
Redrive moves dead-lettered messages off the dlq queue and re-publishes each to its source queue (its dead_letter.original_queue) or to opts.ToQueue, resetting it for reprocessing: the dead_letter block is removed and attempts reset to 0, while job, trace_id, data and meta are preserved verbatim. It is the operator-side counterpart to the runtime's dead-letter routing — the contract leaves redrive to tooling, and this is that tool (ADR-0026).
Messages are drained from the DLQ first and then processed, so restored messages (skipped, dry-run, or undecodable) are never re-encountered in the same run. A DLQ message is acknowledged only after its re-publish succeeds; an undecodable body is restored, not lost.
type Releaser ¶ added in v1.9.0
type Releaser interface {
Release(ctx context.Context, msg *ReceivedMessage, delay time.Duration) error
}
Releaser is an optional Transport capability: return a reserved message to its queue in place, to be redelivered after delay, instead of re-publishing a copy and acknowledging the original. Brokers whose contract binding mandates an in-place release (e.g. SQS §3: ChangeMessageVisibility on the receipt handle, with the broker's receive count as the authoritative attempt counter) implement it. When Release returns ErrReleaseUnsupported the App falls back to re-publish + ack; any other error leaves the message reserved (not acked), so the broker redelivers it once its reservation lapses.
type Rewinder ¶ added in v1.11.0
type Rewinder interface {
Rewind(ctx context.Context, msg *ReceivedMessage) error
}
Rewinder is an optional Transport capability: hand an unacknowledged reserved message back to the broker so it is redelivered, and make sure nothing the consumer acknowledges afterwards can move past it. The App uses it when a version-gated delivery could not be dead-lettered and must not be lost: for an offset-committing broker (Kafka, where a commit is cumulative) it rewinds the consumer to the message's offset; for a lock-based broker it releases or abandons the lock. A transport whose unacknowledged messages already come back on their own (SQS visibility timeout) need not implement it. It must never delete or acknowledge the message, and must not alter its body or attempt counters.
type RoutedPublisher ¶ added in v1.10.0
type RoutedPublisher interface {
PublishRouted(ctx context.Context, queue, body, routeURN string) error
}
RoutedPublisher is an optional Transport capability: re-publish a body while keeping the routing identity the broker's own routing property carried on the original delivery (see ReceivedMessage.RouteURN). The App uses it for its retry and unknown-URN release re-publishes when the received message was routed on a URN that differs from its body, so a routing-property mismatch does not flip to the body URN on the next attempt (contract §5.2/§5.7). routeURN is non-empty; a transport that does not implement this falls back to plain Publish.
type Transport ¶ added in v0.2.0
type Transport interface {
// Publish appends an already-encoded envelope to queue.
Publish(ctx context.Context, queue, body string) error
// Pop reserves the next message from queue, blocking up to timeout. It returns
// (nil, nil) when no message arrives before the timeout.
Pop(ctx context.Context, queue string, timeout time.Duration) (*ReceivedMessage, error)
// Ack acknowledges (removes) a previously reserved message.
Ack(ctx context.Context, msg *ReceivedMessage) error
}
Transport is the minimal broker contract the App runtime talks to: publish a raw (already-encoded) body, reserve the next message, and acknowledge it. The runtime is broker-agnostic — implement this to back it with any broker. The github.com/babelqueue/babelqueue-go/redis and .../amqp modules provide Redis and RabbitMQ implementations; InMemoryTransport backs tests and local runs.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
amqp
module
|
|
|
artemis
module
|
|
|
asynq
module
|
|
|
azureservicebus
module
|
|
|
Package gdpr is the RUNTIME half of ADR-0030: SDK-side field-level encryption of the data fields a registry declared x-gdpr-sensitive.
|
Package gdpr is the RUNTIME half of ADR-0030: SDK-side field-level encryption of the data fields a registry declared x-gdpr-sensitive. |
|
Package idempotency adds optional, dependency-free dedupe to a babelqueue consumer: it wraps a babelqueue.Handler so a message whose meta.id was already processed is skipped instead of run again (ADR-0022).
|
Package idempotency adds optional, dependency-free dedupe to a babelqueue consumer: it wraps a babelqueue.Handler so a message whose meta.id was already processed is skipped instead of run again (ADR-0022). |
|
idempotency-postgres
module
|
|
|
idempotency-redis
module
|
|
|
kafka
module
|
|
|
machinery
module
|
|
|
otel
module
|
|
|
Package outbox adds an optional, dependency-free transactional outbox to a babelqueue producer (ADR-0029): the message is persisted into the same database, in the same transaction, as the business data — so it commits or rolls back atomically with it — and a separate Relay publishes the durable rows afterwards.
|
Package outbox adds an optional, dependency-free transactional outbox to a babelqueue producer (ADR-0029): the message is persisted into the same database, in the same transaction, as the business data — so it commits or rolls back atomically with it — and a separate Relay publishes the durable rows afterwards. |
|
pulsar
module
|
|
|
redis
module
|
|
|
Package schema adds optional, dependency-free per-URN payload validation to a babelqueue producer or consumer (ADR-0024).
|
Package schema adds optional, dependency-free per-URN payload validation to a babelqueue producer or consumer (ADR-0024). |
|
sqs
module
|