Skip to content

NativeAck endpoint mode for Pulsar (must force individual acks) #4047

Description

@jeremydmiller

Adopter issue from the #3715 triage. Carries a correctness trap — read before starting.

The trap

The #3715 starting analysis called Pulsar "straightforward" because individual acks are supported. Verification says otherwise: PulsarListener.CompleteAsync (src/Transports/Pulsar/Wolverine.Pulsar/PulsarListener.cs:278) does not ack directly — it delegates to _ackHandler.CompleteAsync(...), and the ack strategy is configurable per #3180, including cumulative.

A cumulative ack is precisely the defect that disqualifies Kafka. Under EndpointMode.NativeAck the execution block completes messages in handler-completion order, not delivery order, so a cumulative ack of a later message would silently settle every earlier in-flight delivery — turning the mode's no-loss guarantee into silent loss. This is the same hazard #3706 fixed for RabbitMQ by making every ack multiple: false.

Note the retry-consumer path already acks individually unconditionally; it is the primary consumer's configurable strategy that is the problem.

Work

  1. Decide and implement one of: force individual acks for a NativeAck endpoint regardless of the configured strategy, or reject the NativeAck + cumulative-ack combination at configuration time with a message naming both settings. Do not let the combination be configurable-and-silently-wrong — that is the exact failure Validate or warn on silently-ignored listener configuration combos (Inline + partitioning/parallelism) #3712 exists to prevent.
  2. supportsNativeAck => true on the Pulsar endpoint once (1) is in place.
  3. Mode-default tuning: receiver queue size as the prefetch equivalent, covering every lane that can be busy at once.
  4. Check UseNativeRedelivery / negative-ack backoff interacts sanely with lane-based retry.
  5. Flip this transport's line in the release-gate test; update the transport docs page.

Acceptance

Parent: #3715. Mode: #3708.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions