davsclaus commented on code in PR #27616:
URL: https://github.com/apache/camel/pull/27616#discussion_r4232854948


##########
components/camel-lumberjack/src/main/java/org/apache/camel/component/lumberjack/io/LumberjackMessageHandler.java:
##########
@@ -49,35 +50,22 @@ public void exceptionCaught(ChannelHandlerContext ctx, 
Throwable cause) throws E
 
     @Override
     protected void channelRead0(ChannelHandlerContext ctx, LumberjackWindow 
window) throws Exception {
-        try {
-            for (LumberjackMessage msg : window) {
-                if (process) {
-                    messageProcessor.onMessageReceived(msg.getPayload(), 
success -> {
-                        if (success) {
-                            notifyMessageProcessed(ctx, 
msg.getSequenceNumber(), window);
-                        } else {
-                            ctx.close();
-                            // Mark that we shouldn't process the next 
messages that are already decoded and are waiting in netty queues
-                            process = false;
+        // Count down from window size; when it reaches zero all messages have 
been processed successfully.
+        AtomicInteger remaining = new AtomicInteger(window.getSize());
+        for (LumberjackMessage msg : window) {
+            if (process) {
+                messageProcessor.onMessageReceived(msg.getPayload(), success 
-> {
+                    if (success) {
+                        if (remaining.decrementAndGet() == 0) {

Review Comment:
   Question on the root cause (non-blocking): in `LumberjackComponentTest` the 
route is `to("mock:output")`, which completes synchronously, so these callbacks 
fire in loop order on the channel's executor thread and the old `sequenceNumber 
== window.getSize()` gate already ACKed correctly there. The countdown is still 
the right behaviour for async routes; a test with a route where the last 
message completes before the first would cover it.



##########
components/camel-lumberjack/src/test/java/org/apache/camel/component/lumberjack/LumberjackUtil.java:
##########
@@ -97,7 +98,10 @@ protected void channelRead0(ChannelHandlerContext ctx, 
ByteBuf msg) {
             // send 5 frame windows, without pausing
             windows.stream().forEach(window -> 
channel.writeAndFlush(readSample(String.format("io/window%s.bin", window))));
             if (waitForResult) {
-                Awaitility.await().atMost(30, TimeUnit.SECONDS).until(() -> 
windows.size() == responses.size());
+                Awaitility.await().atMost(30, TimeUnit.SECONDS).untilAsserted(
+                        () -> Assertions.assertThat(responses)
+                                .as("Expected one ACK per window frame sent 
(%d), but received: %s", windows.size(), responses)
+                                .hasSize(windows.size()));

Review Comment:
   `responses` is read here without the `synchronized (responses)` used 
elsewhere in this method. On every failed poll AssertJ builds the failure 
message (the `%s` argument and the actual value), iterating the list while the 
Netty thread may be adding to it; a `ConcurrentModificationException` is not 
retried by Awaitility (only `AssertionError` is), so the test would fail with a 
confusing stack trace instead of this message. Asserting on a snapshot avoids 
that:
   
   ```suggestion
                   Awaitility.await().atMost(30, 
TimeUnit.SECONDS).untilAsserted(() -> {
                       List<Integer> received;
                       synchronized (responses) {
                           received = new ArrayList<>(responses);
                       }
                       Assertions.assertThat(received)
                               .as("Expected one ACK per window frame sent 
(%d), but received: %s", windows.size(), received)
                               .hasSize(windows.size());
                   });
   ```



-- 
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]

Reply via email to