sqs

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 20, 2026 License: MIT Imports: 11 Imported by: 0

README

babelqueue-go/sqs

Amazon SQS transport for the BabelQueue Go runtime — "Polyglot Queues, Simplified."

It implements §3 of the broker-bindings contract: the canonical envelope is the message body, and the contract fields are projected onto native SQS MessageAttributes so a PHP/Python/… peer can route and correlate without parsing the body.

Install

go get github.com/babelqueue/babelqueue-go/sqs

Use

ctx := context.Background()

tr, err := sqs.New(ctx,
    sqs.WithRegion("eu-central-1"),
    // sqs.WithEndpoint("http://localhost:4566"), // LocalStack/ElasticMQ
)
if err != nil { log.Fatal(err) }

app := babelqueue.NewApp(tr, babelqueue.WithDefaultQueue("orders"))

// produce
app.Publish(ctx, "urn:babel:orders:created", map[string]any{"order_id": 1042})

// consume
app.Handle("urn:babel:orders:created", func(ctx context.Context, env babelqueue.Envelope) error {
    // env.Data, env.TraceID ...
    return nil
})
app.Run(ctx)

Credentials come from the standard AWS default provider chain (env vars, shared profile, instance role, IRSA, SSO). FIFO queues: add sqs.WithFIFO(true) (the queue name must end in .fifo).

How it maps to the contract (§3)

Envelope SQS
body MessageBody (byte-identical across SDKs)
job (URN) MessageAttributes.bq-job
trace_id MessageAttributes.bq-trace-id
meta.id MessageAttributes.bq-message-id
meta.schema_version MessageAttributes.bq-schema-version (Number)
meta.lang MessageAttributes.bq-source-lang
meta.created_at MessageAttributes.bq-created-at (Number, ms)
attempts reconciled to ApproximateReceiveCount − 1 on receive
reserve / ack visibility timeout → DeleteMessage
out-of-band headers (e.g. traceparent) extra String MessageAttributes (see below)

The envelope is unchanged (schema_version stays 1); SQS is purely additive.

Out-of-band transport headers

This transport implements the optional babelqueue.HeaderPublisher capability: out-of-band headers ride as String MessageAttributes beside the frozen envelope, never in it (GR-1), and are surfaced back to the consumer on ReceivedMessage.Headers. So the optional otel module's W3C traceparent (ADR-0028) — and the bq-replay-bypass marker (ADR-0027) — propagate over SQS for true cross-hop span parent-child linkage. Headers are merged beside the contract bq-* attributes without clobbering them, and bounded by the 10-attribute SQS limit (the contract attributes are always preserved first).

Test

go test ./...                       # unit (fake SQS client, no broker)
go test -tags=integration ./...     # integration (needs LocalStack at SQS_ENDPOINT)

The default unit run fakes the AWS client. The New config-loading path is covered by the LocalStack integration test (-tags=integration).

License

MIT

Documentation

Overview

Package sqs is an Amazon SQS-backed babelqueue.Transport for the BabelQueue Go runtime. Producing sends the canonical envelope as the message body and projects the contract envelope fields onto native SQS MessageAttributes (bq-job = URN, bq-trace-id = trace_id, bq-message-id = meta.id, plus bq-schema-version / bq-source-lang / bq-created-at) — so a PHP/Python/... peer can route on bq-job and correlate on bq-trace-id without parsing the body. Consuming uses the visibility-timeout reservation model (ReceiveMessage → process → DeleteMessage); the authoritative attempt count is the broker's ApproximateReceiveCount, reconciled onto the envelope as attempts = count − 1.

tr, _ := sqs.New(ctx, sqs.WithRegion("eu-central-1"))
app := babelqueue.NewApp(tr, babelqueue.WithDefaultQueue("orders"))

This binding implements §3 of the BabelQueue broker-bindings contract. The envelope is unchanged (schema_version stays 1); SQS is purely additive.

It also implements the optional babelqueue.HeaderPublisher capability: out-of-band transport headers (e.g. a W3C traceparent for cross-hop span linkage, ADR-0028, or the bq-replay-bypass marker, ADR-0027) ride as String MessageAttributes beside the frozen envelope — never in it (GR-1) — and are surfaced back to the consumer on babelqueue.ReceivedMessage.Headers.

Full spec: https://babelqueue.com

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type API

type API interface {
	SendMessage(ctx context.Context, in *awssqs.SendMessageInput, optFns ...func(*awssqs.Options)) (*awssqs.SendMessageOutput, error)
	ReceiveMessage(ctx context.Context, in *awssqs.ReceiveMessageInput, optFns ...func(*awssqs.Options)) (*awssqs.ReceiveMessageOutput, error)
	DeleteMessage(ctx context.Context, in *awssqs.DeleteMessageInput, optFns ...func(*awssqs.Options)) (*awssqs.DeleteMessageOutput, error)
	GetQueueUrl(ctx context.Context, in *awssqs.GetQueueUrlInput, optFns ...func(*awssqs.Options)) (*awssqs.GetQueueUrlOutput, error)
}

API is the subset of the AWS SQS client the transport uses. The concrete *github.com/aws/aws-sdk-go-v2/service/sqs.Client satisfies it; a fake satisfies it in tests.

type Option

type Option func(*Transport)

Option customizes New / NewWithClient.

func WithClient

func WithClient(client API) Option

WithClient injects a preconfigured SQS client (or a fake in tests), bypassing AWS config loading.

func WithContentDedup

func WithContentDedup(enabled bool) Option

WithContentDedup uses the queue's content-based deduplication instead of meta.id as the MessageDeduplicationId (FIFO only).

func WithEndpoint

func WithEndpoint(endpoint string) Option

WithEndpoint overrides the SQS endpoint — point it at LocalStack/ElasticMQ for local/CI (e.g. "http://localhost:4566").

func WithFIFO

func WithFIFO(enabled bool) Option

WithFIFO marks the queue as FIFO (its name must end in ".fifo"). Sends then carry a MessageGroupId (see WithMessageGroupID, default the queue name) and, unless content-based dedup is enabled, a MessageDeduplicationId = meta.id.

func WithMessageGroupID

func WithMessageGroupID(id string) Option

WithMessageGroupID sets the FIFO ordering group (default: the queue name).

func WithQueueURLPrefix

func WithQueueURLPrefix(prefix string) Option

WithQueueURLPrefix sets a base queue-URL so a queue name resolves to "<prefix>/<name>" without a GetQueueUrl call (e.g. "https://sqs.eu-central-1.amazonaws.com/123456789012"). When unset, the transport resolves names via GetQueueUrl and caches the result.

func WithRegion

func WithRegion(region string) Option

WithRegion sets the AWS region (otherwise resolved from the environment/config).

func WithVisibilityTimeout

func WithVisibilityTimeout(seconds int32) Option

WithVisibilityTimeout sets the reservation window (seconds) applied on receive. Zero leaves the queue default.

func WithWaitTimeSeconds

func WithWaitTimeSeconds(seconds int32) Option

WithWaitTimeSeconds caps the ReceiveMessage long-poll wait (0–20). The runtime's per-iteration poll timeout still bounds it; this caps the upper limit.

type Transport

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

Transport implements babelqueue.Transport over Amazon SQS. It is safe for concurrent use; the queue-URL cache is guarded by a mutex.

func New

func New(ctx context.Context, opts ...Option) (*Transport, error)

New builds a transport, loading AWS configuration (the default credential provider chain) unless a client was injected with WithClient. Apply WithRegion/WithEndpoint to target a region or LocalStack/ElasticMQ.

func NewWithClient

func NewWithClient(client API, opts ...Option) *Transport

NewWithClient builds a transport over a preconfigured client (or fake). It never touches AWS config; useful for tests and dependency injection.

func (*Transport) Ack

Ack deletes the reserved message (DeleteMessage on its receipt handle).

func (*Transport) Pop

func (t *Transport) Pop(ctx context.Context, queue string, timeout time.Duration) (*babelqueue.ReceivedMessage, error)

Pop reserves the next message (long-poll up to timeout, capped at 20s and by WithWaitTimeSeconds). It reconciles attempts to max(body.attempts, ApproximateReceiveCount − 1) so a crash-redelivered message reflects its true delivery count. Returns (nil, nil) when no message arrives.

func (*Transport) Publish

func (t *Transport) Publish(ctx context.Context, queue, body string) error

Publish sends body to queue with the contract MessageAttributes projection.

func (*Transport) PublishWithHeaders added in v1.1.0

func (t *Transport) PublishWithHeaders(ctx context.Context, queue, body string, headers map[string]string) error

PublishWithHeaders sends body together with out-of-band transport headers (babelqueue.HeaderPublisher). The headers ride as String MessageAttributes beside the frozen envelope (GR-1) — e.g. a W3C traceparent for cross-hop span linkage (ADR-0028) — merged on top of the contract bq-* attributes without clobbering them, and bounded by the 10-attribute SQS limit. A nil/empty map behaves exactly like Transport.Publish.

Jump to

Keyboard shortcuts

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