Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JetStream should reject out-of-window acks. #4786

Open
davidmcote opened this issue Nov 9, 2023 · 1 comment
Open

JetStream should reject out-of-window acks. #4786

davidmcote opened this issue Nov 9, 2023 · 1 comment
Assignees
Labels
proposal Enhancement idea or proposal stale This issue has had no activity in a while

Comments

@davidmcote
Copy link
Contributor

davidmcote commented Nov 9, 2023

Proposed change

Per https://docs.nats.io/nats-concepts/jetstream/consumers#ackpolicy,

If an ack is required but is not received within the AckWait window, the message will be redelivered.

⚠️ The server may consider an ack arriving out of the window. If a first process fails to ack within the window it's entirely possible, for instance in queue situation, that the message has been redelivered to another consumer. Since this will technically restart the window, the ack from the first consumer will be considered.

JetStream's willingness to accept AckProgress (or any Ack) beyond a stream consumer's AckWait is undesirable.

Applications who wish to employ exactly-once-processing semantics need to implement careful local time-keeping to be certain that they are still the sole processor for a message and that their AckAck, AckNack, AckTerm, or AckProgress request won't be interpreted by JetStream as acknowledgement of another consumer's redelivery. Even using a request-reply to double-ack with JetStream, the client will be uncertain about which delivery attempt it acked.

The reply subject of jetstream messages has a structure which encodes the message's metadata, including its monotonically increasing delivery count. It seems that this metadata is unique per redelivery per message. JetStream could use it to decide whether an ACK is still valid or refuse ACKs for a since-expired delivery attempt.

Backward compatibility considerations:
This new capability would not require any modification to the wire protocol if it leverages the JetStream metadata already contained in the structured reply subject.

However, this behavior is stricter than what exists in JetStream today and risks breaking clients who are unwittingly on the wrong side of a race with AckWait. Because of this, it may be desirable to extend the AckType message or ConsumerConfiguration to include an option requesting this stricter behavior.

Use case

With this proposal, JetStream could distinguish between message receipts like SQS does with its notion of receipt handles and reject out-of-window ACKs, reducing the local-timekeeping and heuristics that consumers currently must perform to achieve at-most-once-processing.

TL;DR:
A client would be able to confidently interpret a successful AckProgress double-ack as permission to continue processing for another AckWait period.

@davidmcote davidmcote added the proposal Enhancement idea or proposal label Nov 9, 2023
@davidmcote
Copy link
Contributor Author

davidmcote commented Nov 10, 2023

Related: In nats-io/nats.java#1042, I proposed that the Java NATS client introduce a double-acked Message.inProgressSync(), which would benefit further from this proposal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal Enhancement idea or proposal stale This issue has had no activity in a while
Projects
None yet
Development

No branches or pull requests

3 participants