Skip to content

ADR-004: Task Delivery and Leases

Status: PROPOSED.

Context

CURRENT: Scan messages are pushed to Redis with LPush and consumed with BRPop.

Source references:

  • Queue key and queue interface: backend/internal/scans/service.go:18
  • Enqueue: backend/internal/scans/service.go:171
  • Dequeue: backend/internal/scans/worker.go:97

This removes the task from Redis before execution completes. It does not provide durable acknowledgement, visibility timeout, or lease ownership.

Proposal

Use PostgreSQL-backed task state and lease ownership, with Redis notifications as an optional wake-up mechanism.

Core concepts:

  • task;
  • attempt;
  • lease;
  • lease token;
  • attempt deadline;
  • idempotency key;
  • terminal state;
  • retry policy.

Gateway replicas acquire tasks through transactional state changes. Workers must renew leases for long-running scans. Result submission and completion are authorized against the active lease.

Delivery guarantee

The realistic guarantee is at-least-once task delivery with idempotent ingestion boundaries.

The architecture must not claim exactly-once execution.

Required behaviors

  • Lost Worker connection eventually expires the lease.
  • Expired attempts cannot overwrite newer attempts.
  • Duplicate result submission is rejected or idempotently ignored.
  • Completion requires the active lease.
  • Cancellation is durable and visible to Gateway and Worker.
  • Terminal failure is explicit.

Alternatives

  • Continue Redis list queue.
  • Redis Streams consumer groups.
  • Direct in-memory Gateway queue.

Consequences

  • Requires database schema design before implementation.
  • Redis can remain useful for notifications.
  • Reliability semantics become explicit and testable.

Unresolved

  • Exact task table schema.
  • Retry limits.
  • Dead-letter representation.
  • Lease duration defaults.
  • Long-running scan progress requirements.