diff --git a/bridged/src/main/java/dev/ltms/bridged/msg/MessageService.java b/bridged/src/main/java/dev/ltms/bridged/msg/MessageService.java index 5db11cc..c35076d 100644 --- a/bridged/src/main/java/dev/ltms/bridged/msg/MessageService.java +++ b/bridged/src/main/java/dev/ltms/bridged/msg/MessageService.java @@ -333,9 +333,30 @@ public final class MessageService { } /** - * Drain (peek + ack) all pending inbox replies for {@code target}. At-least-once: returns the - * messages and acknowledges them; an in-flight failure between returning and the caller - * processing them re-surfaces them on a subsequent drain (the ack is local). + * Drain (peek + ack) all pending inbox replies for {@code target}. + * + *

The ack happens here, before the caller has the messages — before the MCP + * or REST response carrying them has been written, and long before the client has processed + * them. That ordering is what the two adapters disagree about, so do not read this method as + * "at-least-once" without qualifying which inbox is behind it (CB-529): + * + *

+ * + *

So the loss window is the response write, and it is a genuine loss rather than a + * redelivery. This is accepted, not overlooked: the alternative — ack on the next poll — turns + * every normal drain into a double delivery, which costs more than the window it closes. A + * caller that needs certainty re-polls; that is idempotent for every case except this one. + * + *

Any change here must be checked against both adapters. The previous version of + * this javadoc claimed "the ack is local", which was true when only the in-memory inbox existed + * and silently became false when the AMQP adapter landed. * * @return the drained messages, newest last (FIFO); empty list if none */