This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new f8e9a768b634 CAMEL-25822: camel-aws2-sqs - the DST world drains until 
no progress instead of for a fixed time (#28139)
f8e9a768b634 is described below

commit f8e9a768b634e88a75b831bcd20df50a3e64624c
Author: allthingssecurity <[email protected]>
AuthorDate: Wed Oct 21 13:56:30 2026 +0530

    CAMEL-25822: camel-aws2-sqs - the DST world drains until no progress 
instead of for a fixed time (#28139)
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../org/apache/camel/catalog/docs/test-dst.adoc          | 16 ++++++++++++++--
 .../apache/camel/component/aws2/sqs/dst/SqsWorld.java    | 15 +++++++++++++--
 .../camel-test-dst/src/main/docs/test-dst.adoc           | 16 ++++++++++++++--
 3 files changed, 41 insertions(+), 6 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/test-dst.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/test-dst.adoc
index 7a001ec87504..74a55ce94812 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/test-dst.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/test-dst.adoc
@@ -226,12 +226,24 @@ dst.runFor(dst.between(0, 3L * visibilityTimeout * 1000));
 // faults cleared: the queue must drain
 faults = false;
 sqs.faults = false;
-long deadline = dst.now() + 20L * visibilityTimeout * 1000 + 30_000;
-while (!sqs.allDeleted() && dst.now() < deadline) {
+// drain while it makes progress: stop when no message was deleted for a 
while, or at a cap
+long quiet = 20L * visibilityTimeout * 1000 + 30_000;
+long cap = dst.now() + 3_600_000;
+int left = sqs.notDeleted().size();
+long lastProgress = dst.now();
+while (!sqs.allDeleted() && dst.now() < cap && dst.now() - lastProgress < 
quiet) {
     dst.runFor(100);
+    int remaining = sqs.notDeleted().size();
+    if (remaining < left) {
+        left = remaining;
+        lastProgress = dst.now();
+    }
 }
 ----
 
+Drain until progress stops, not for a fixed time. With a fixed drain time, 1 
of 20,000 seeds failed falsely: one
+consumer taking one message per poll was still deleting messages when the time 
ran out.
+
 Some faults legitimately cause what the invariant forbids. Record which fault 
excuses which violation, and only those:
 a failed `ChangeMessageVisibilityBatch` lets SQS deliver the messages of that 
batch again, so `FakeSqs` reports their
 ids (`onExtensionFault`) and the world does not count a redelivery of those 
messages.
diff --git 
a/components/camel-aws/camel-aws2-sqs/src/test/java/org/apache/camel/component/aws2/sqs/dst/SqsWorld.java
 
b/components/camel-aws/camel-aws2-sqs/src/test/java/org/apache/camel/component/aws2/sqs/dst/SqsWorld.java
index e8096e53480a..56873b7dc080 100644
--- 
a/components/camel-aws/camel-aws2-sqs/src/test/java/org/apache/camel/component/aws2/sqs/dst/SqsWorld.java
+++ 
b/components/camel-aws/camel-aws2-sqs/src/test/java/org/apache/camel/component/aws2/sqs/dst/SqsWorld.java
@@ -112,9 +112,20 @@ final class SqsWorld {
             // faults cleared: the queue must drain
             faults = false;
             sqs.faults = false;
-            long deadline = dst.now() + 20L * visibilityTimeout * 1000 + 
30_000;
-            while (!sqs.allDeleted() && dst.now() < deadline) {
+            // drain while it makes progress: stop when no message was deleted 
for a while, or at a cap. A fixed
+            // drain time failed falsely when the consumer was still deleting 
messages at its end (one consumer
+            // taking one message per poll with a 1 s delay, and short polling 
returning fewer messages than asked)
+            long quiet = 20L * visibilityTimeout * 1000 + 30_000;
+            long cap = dst.now() + 3_600_000;
+            int left = sqs.notDeleted().size();
+            long lastProgress = dst.now();
+            while (!sqs.allDeleted() && dst.now() < cap && dst.now() - 
lastProgress < quiet) {
                 dst.runFor(100);
+                int remaining = sqs.notDeleted().size();
+                if (remaining < left) {
+                    left = remaining;
+                    lastProgress = dst.now();
+                }
             }
             dst.check(
                     Invariants.of("no message is delivered again while the 
consumer holds it",
diff --git a/components/camel-test/camel-test-dst/src/main/docs/test-dst.adoc 
b/components/camel-test/camel-test-dst/src/main/docs/test-dst.adoc
index 7a001ec87504..74a55ce94812 100644
--- a/components/camel-test/camel-test-dst/src/main/docs/test-dst.adoc
+++ b/components/camel-test/camel-test-dst/src/main/docs/test-dst.adoc
@@ -226,12 +226,24 @@ dst.runFor(dst.between(0, 3L * visibilityTimeout * 1000));
 // faults cleared: the queue must drain
 faults = false;
 sqs.faults = false;
-long deadline = dst.now() + 20L * visibilityTimeout * 1000 + 30_000;
-while (!sqs.allDeleted() && dst.now() < deadline) {
+// drain while it makes progress: stop when no message was deleted for a 
while, or at a cap
+long quiet = 20L * visibilityTimeout * 1000 + 30_000;
+long cap = dst.now() + 3_600_000;
+int left = sqs.notDeleted().size();
+long lastProgress = dst.now();
+while (!sqs.allDeleted() && dst.now() < cap && dst.now() - lastProgress < 
quiet) {
     dst.runFor(100);
+    int remaining = sqs.notDeleted().size();
+    if (remaining < left) {
+        left = remaining;
+        lastProgress = dst.now();
+    }
 }
 ----
 
+Drain until progress stops, not for a fixed time. With a fixed drain time, 1 
of 20,000 seeds failed falsely: one
+consumer taking one message per poll was still deleting messages when the time 
ran out.
+
 Some faults legitimately cause what the invariant forbids. Record which fault 
excuses which violation, and only those:
 a failed `ChangeMessageVisibilityBatch` lets SQS deliver the messages of that 
batch again, so `FakeSqs` reports their
 ids (`onExtensionFault`) and the world does not count a redelivery of those 
messages.

Reply via email to