Documentation
¶
Overview ¶
Package redisstream implements the internal/coachapi/queue.TaskQueue port (ADR-006, docs/architecture/ADR-006-watermill-queue-abstraction.md) on top of Watermill's Redis Streams pub/sub (github.com/ThreeDotsLabs/watermill-redisstream), for coach's non-AWS / self-hosted deployment target. Enqueue publishes through a Watermill Publisher; Complete and permanent Nack acknowledge through the underlying Watermill message, so ADR-006 rule 5's "successful handler -> Ack, retryable error -> Nack, permanent error -> Ack plus publication to a poison-task destination" holds at the wire level. Redis pending-entry lists, consumer groups, XCLAIM, and Watermill's *message.Message are not exposed: callers only see queue.Task and queue.Claim.
Index ¶
- type Config
- type Queue
- func (q *Queue) Claim(ctx context.Context) (queue.Claim, bool, error)
- func (q *Queue) Close() error
- func (q *Queue) Complete(ctx context.Context, claim queue.Claim) error
- func (q *Queue) Enqueue(ctx context.Context, task queue.Task) error
- func (q *Queue) Nack(ctx context.Context, claim queue.Claim, permanent bool) error
- func (q *Queue) PoisonTasks(ctx context.Context) ([]queue.Task, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Address is the Redis server address (host:port), e.g. "redis:6379".
Address string
// Password is the Redis AUTH password. Empty means no auth.
Password string
// DB selects the Redis logical database index.
DB int
// Stream is the Redis Stream (and Watermill topic) task attempts are
// published to and consumed from; ADR-006's "taskQueue" name.
Stream string
// ConsumerGroup is the Redis Streams consumer group every Queue
// instance for Stream shares. It is what makes claims competing: at
// most one consumer in the group receives a given stream entry.
ConsumerGroup string
// Consumer names this Queue instance's Redis Streams consumer within
// ConsumerGroup. A generated id is used when empty.
Consumer string
// ClaimAfter is how long an unresolved claim (neither Complete nor
// Nack called) may be held before Claim treats it as abandoned and
// reclaims it for another attempt -- this Queue's equivalent of a
// visibility timeout. See Queue's doc comment for why this is
// enforced against the injected Clock rather than Redis server time.
ClaimAfter time.Duration
// DialTimeout bounds the initial Redis connection attempt. Defaults
// to defaultDialTimeout when zero or negative.
DialTimeout time.Duration
}
Config matches ADR-006's "Provider configuration" Redis Streams shape (address, consumerGroup, claimAfter; docs/architecture/ADR-006-watermill-queue-abstraction.md).
type Queue ¶
type Queue struct {
// contains filtered or unexported fields
}
Queue implements internal/coachapi/queue.TaskQueue against Redis Streams. It also exposes PoisonTasks, which is not part of that port but is required by internal/acceptanceharness/queueconformance.Queue (see redisstream_conformance_test.go for the adapter that reconciles the two packages' structurally-identical-but-distinctly-named Task and Claim types).
A single Queue is safe for concurrent use: Claim/Complete/Nack all serialize access to the shared pending-claims map via mu.
func NewQueue ¶
func NewQueue(cfg Config, clock acceptanceharness.Clock) (*Queue, error)
NewQueue connects to Redis and returns a Queue consuming cfg.Stream under cfg.ConsumerGroup. clock defaults to acceptanceharness.RealClock when nil; tests inject acceptanceharness.FakeClock to force reclaims deterministically (see maxWatermillIdleTime's doc comment).
func (*Queue) Claim ¶
Claim first reclaims any pending claim whose ClaimAfter has elapsed (per the injected Clock), and only if none did, waits up to claimPollWindow for a newly delivered message. ok=false means neither happened before the wait window (or ctx) elapsed.
func (*Queue) Complete ¶
Complete acknowledges claim's task attempt as durably finished. It fails if claim.Token has been invalidated by a reclaim.
func (*Queue) Enqueue ¶
Enqueue publishes task onto the Redis Stream via the Watermill Publisher (an XADD under the hood).
func (*Queue) Nack ¶
Nack reports claim's task attempt failed. A retryable failure (permanent=false) makes the task claimable again with Attempt incremented. A permanent failure (permanent=true) acknowledges the underlying message (ADR-006 rule 5) and republishes the task onto the poison-task destination stream; PoisonTasks reads that stream back. Nack fails under the same stale-token condition as Complete.
func (*Queue) PoisonTasks ¶
PoisonTasks returns every task a permanent Nack has routed to the poison-task destination stream, oldest first. It is not part of queue.TaskQueue; internal/acceptanceharness/queueconformance.Queue requires it so both this package's own tests and the shared conformance suite can assert the poison destination actually received a task.