qianye1001 opened a new issue, #1321: URL: https://github.com/apache/rocketmq-clients/issues/1321
### Before Creating the Bug Report - [x] I found a bug, not just a question. - [x] I searched existing issues and discussions and did not find a duplicate. - [x] I confirmed that the behavior is in this client repository. ### Programming Language of the Client Java ### Runtime Platform Environment Linux on Kubernetes. The fault was injected by an external h2c proxy between the Java client and RocketMQ Proxy; the client-to-proxy TCP connection and other HTTP/2 streams remained alive. ### RocketMQ Version of the Client/Server - Java client: current `master` at `9abb7f39ce9f74b41873a4f5253ab82af052d7a7` - Server: RocketMQ 5.x gRPC Proxy/Broker deployment ### Run or Compiler Version OpenJDK 11 ### Describe the Bug `ProcessQueueImpl` can replace the attempt ID before a receive request has actually returned messages to the client: 1. On a receive RPC failure, the current implementation preserves the request attempt ID only for `DEADLINE_EXCEEDED`. Other transport failures clear it, so the retry uses a new attempt ID. 2. After a successful but empty receive response, the next receive also uses a new attempt ID. This is observable with FIFO consumption when the server has completed the receive/POP operation but the corresponding HTTP/2 response is lost. The previous attempt may still own the server-side FIFO order state. Retrying with a different attempt ID cannot recover that result and can be blocked by the existing order lock. An attempt ID should identify consecutive receive retries until a response actually contains messages, rather than identify every client-side RPC invocation. ### Steps to Reproduce 1. Create a new FIFO topic and FIFO consumer group. 2. Start a Java `PushConsumer` and send one FIFO message. 3. Put an external HTTP/2-aware proxy in front of RocketMQ Proxy. 4. After the server sends response DATA for one `ReceiveMessage` RPC, reset only that HTTP/2 stream. Keep the TCP connection and unrelated streams alive. 5. Observe the receive error and the attempt IDs used by subsequent receive requests. 6. Repeat the scenario several times because the timing depends on whether the server has completed POP before the stream is reset. In a deterministic run, the old client received `CANCELLED: RST_STREAM`, discarded the request attempt ID, generated new IDs for subsequent receives, returned only empty results, and did not invoke the message callback within 180 seconds. For comparison, a response blackhole that ends as `DEADLINE_EXCEEDED` does not reproduce the same behavior because the old implementation already preserves the attempt ID for that status. ### What Did You Expect to See? - Reuse the request attempt ID after any failed receive RPC. - Reuse it after a successful response that contains no messages. - Generate a new attempt ID only after the raw receive response contains at least one message. - Preserve the existing acknowledgement and redelivery semantics. ### What Did You See Instead? After a non-deadline stream failure, the next request used a new attempt ID. In the FIFO scenario above, the new attempt was unable to recover the message associated with the previous attempt and remained blocked behind the existing FIFO order state. ### Additional Context With the proposed behavior, the retry after the same injected stream reset reused the previous attempt ID, received the original FIFO message in about one second with `deliveryAttempt=1`, and acknowledged it successfully. The decision to rotate must be based on messages in the raw receive response, before client-side filtering. If an interceptor filters every returned message, the server still returned messages for that attempt and the next receive should use a new ID. `SimpleConsumer` does not set an attempt ID in its receive request, so its behavior is outside the scope of this bug. This change does not provide exactly-once delivery and does not alter ACK behavior. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
