I can’t agree more, just like what I’ve said in PR 12195: > At any case, when you choose `sendAsync`, you should always make use of the > returned future to confirm the result of all messages. In Kafka, it's the > send callback.
But I found many users are confused about the current behavior, especially those are used to Kafka’s close semantics. They might expect a simple try to flush existing messages, which works at a simple test environment, even there's no guarantee for exception cases. > 2021年9月28日 下午4:37,Joe F <joefranc...@gmail.com> 写道: > > Clients should not depend on any of this behaviour, since the broker is at > the other end of an unreliable network connection. The > semantic differences are kind of meaningless from a usability point, since > flushing on close =/= published. What exactly does "graceful" convey > here? Flush the buffer on the client end and hope it makes it to the > server. > > Is there a difference whether you flush(or process) pending messages or > not? There is no guarantee that either case will ensure the message is > published. > > The only way to ensure that messages are published is to wait for the ack. > The correct model should be to wait for return on the blocking API, or wait > for future completion of the async API, then handle any publish errors and > then only close the producer. > > > On Mon, Sep 27, 2021 at 8:50 PM Yunze Xu <y...@streamnative.io.invalid> > wrote: > >> Hi all, >> >> Recently I found a PR (https://github.com/apache/pulsar/pull/12195 < >> https://github.com/apache/pulsar/pull/12195>) that >> modifies the existing semantics of producer close. There're already some >> communications in this PR, but I think it's better to start a discussion >> here >> to let more know. >> >> The existing implementation of producer close is: >> 1. Cancel all timers, including send and batch container >> (`batchMessageContainer`). >> 2. Complete all pending messages (`pendingMessages`) with >> `AlreadyCloseException`. >> >> See `ProducerImpl#closeAsync` for details. >> >> But the JavaDoc of `Producer#closeAsync` is: >> >>> No more writes will be accepted from this producer. Waits until all >> pending write request are persisted. >> >> Anyway, the document and implementation are inconsistent. But specifically, >> we need to define the behavior for how to process `pendingMessages` and >> `batchMessageContainer` when producer call `closeAsync`. >> >> 1. batchMessageContainer: contains the buffered single messages >> (`Message<T>`). >> 2. pendingMessages: all inflight messages (`OpSendMsg`) in network. >> >> IMO, from the JavaDoc, only `pendingMessages` should be processed and the >> messages in `batchMessageContainer` should be discarded. >> >> Since other clients might have already implemented the similar semantics of >> Java clients. If we changed the semantics now, the behaviors among >> different >> clients might be inconsistent. >> >> Should we add a configuration to support graceful close to follow the >> docs? Or >> just change the current behavior? >> >> Thanks, >> Yunze