LiteBus
CatalogTransport

Manual Acknowledgement Model

  • ID: transport.manual-acknowledgement
  • Name: Manual acknowledgement model
  • Maturity: GA
  • Summary: Every inbound delivery exposes explicit accept, discard, and requeue operations mapped to broker-specific ack semantics.

What It Does

TransportMessage wraps broker acknowledgement as three user-facing methods. AcceptAsync signals successful processing. DiscardAsync rejects without requeue (delete, complete without retry, or dead-letter depending on broker). ReturnToQueueAsync rejects with requeue so the broker redelivers the message. Adapters supply AckAsync and NackAsync(requeue) delegates through TransportConsumerAckHandlers.

Each adapter maps these calls to its native API. The Architecture resilience matrix documents the minimum behavior per provider.

ProviderAcceptRequeueNotes
AMQPbasic.ackbasic.nack requeueChannel shutdown stops consumer
InMemoryRemove from channelRe-enqueueIn-process only
Azure Service BusCompleteMessageAbandonMessageExponential processor restart on errors
AWS SQSDeleteMessageChangeMessageVisibility with backoffUses receive count when present
KafkaOffset commitSeek to failed offsetNo queue-style lease; offset not advanced until accept

Public Surface

APIRole
TransportMessage.AcceptAsync(CancellationToken)Acknowledge successful processing
TransportMessage.DiscardAsync(CancellationToken)Reject without requeue
TransportMessage.ReturnToQueueAsync(CancellationToken)Reject with requeue
TransportMessage.RedeliveredBroker redelivery hint
TransportMessage.AckAsync / NackAsyncLow-level delegates used by mappers
TransportConsumerAckHandlersFactory for ack delegates on mapped messages

Packages

  • LiteBus.Transport.Abstractions
  • Broker adapters in LiteBus.Transport.*

Requires

  • transport.publish-consume-contracts

Invariants

  • Handlers that return without calling an ack method leave deliveries unacknowledged; broker behavior varies (peek-lock renewal, visibility timeout, or uncommitted Kafka offset).
  • Raw IMessageConsumer hosts have no LiteBus redelivery cap at the transport layer; poison handling requires DiscardAsync, broker DLQ policy, or inbox ingress.
  • Kafka commits offset only after AcceptAsync; ReturnToQueueAsync seeks back before the next read.

Non-Goals

  • Store-backed retry budgets, dead-letter tables, or idempotency enforcement (inbox processor and ingress own those).
  • Exactly-once delivery at the broker.
  • Automatic ack on successful handler return (explicit ack is required).

Observability

  • TransportMessage.Redelivered surfaces on Azure Service Bus when DeliveryCount > 1.
  • Process spans record destination, message id, and redelivery state when tracing is enabled.
  • No dedicated ack success/failure counters at the transport layer.

Test Coverage

Covered

Test methodProject
PublishAsync_ThenConsume_AcknowledgesMessageLiteBus.Transport.IntegrationTests (Amqp/)
ConsumeAsync_NackWithRequeue_RedeliversMessageLiteBus.Transport.IntegrationTests (Amqp/)
ReturnToQueue_ShouldRedeliverMessageLiteBus.Transport.UnitTests
ToTransportMessage_ShouldExposeCommitDelegateLiteBus.Transport.UnitTests
ToTransportMessage_ReturnToQueueAsync_ShouldSeekToConsumedOffsetLiteBus.Transport.UnitTests
ToTransportMessage_DiscardAsync_ShouldNotSeekLiteBus.Transport.UnitTests
ToTransportMessage_ShouldExposeAckDelegatesLiteBus.Transport.UnitTests
ComputeRequeueVisibilityTimeout_shouldHonorReceiveCountLiteBus.Transport.UnitTests
RequeueEnabled_WithTransientStoreFailure_ShouldEventuallyAcceptLiteBus.Durable.IntegrationTests (Ingress/InMemory/, Ingress/Amqp/, Ingress/AwsSqs/, Ingress/AzureServiceBus/)
RequeueDisabled_WithPoisonMessage_ShouldDiscardWithoutStoreWriteLiteBus.Durable.IntegrationTests (Ingress/InMemory/)
RequeueDisabled_WithPoisonMessage_ShouldDrainQueueLiteBus.Durable.IntegrationTests (Ingress/AwsSqs/)
TransientAcceptFailure_ShouldRedeliverSameOffsetWithoutRestartLiteBus.Durable.IntegrationTests (Ingress/Kafka/)

Untested

  • Azure Service Bus DiscardAsync dead-letter path when DLQ is configured.
  • SQS ack failure after successful handler completion at raw consumer layer.
  • AMQP ack when channel closes mid-handler.

Out-of-Scope

  • Store-backed retry budgets, dead-letter tables, or idempotency enforcement.
  • Exactly-once delivery at the broker.
  • Automatic ack on successful handler return.

Deep Docs

On this page