[ 
https://issues.apache.org/jira/browse/CAMEL-25809?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Claus Ibsen updated CAMEL-25809:
--------------------------------
    Fix Version/s: 4.24.0

> camel-aws2-sqs - with extendMessageVisibility=true and maxMessagesPerPoll > 
> 10, the first extension can come after the visibility timeout ran out when 
> the poll waited for a long-polling receive
> -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25809
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25809
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-aws2
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>             Fix For: 4.24.0
>
>
> With {{extendMessageVisibility=true}} the SQS consumer keeps the messages it 
> processes invisible: its {{TimeoutExtender}} runs every {{max(1, 
> visibilityTimeout / 2)}} seconds and extends a message whose deadline falls 
> before its next run. The deadline is 80 % of {{visibilityTimeout}} counted 
> from the moment the message is registered with the extender, at the start of 
> {{processBatch}} (since CAMEL-25700; {{Sqs2Consumer}} lines 142-147 and 532 
> on main 62c9a3ebe409). SQS counts the visibility timeout from the receive.
> Normally the two are milliseconds apart. Not when a poll sends several 
> receive requests: with {{maxMessagesPerPoll}} greater than 10, 
> {{PollingTask}} sends one {{ReceiveMessage}} per 10 messages concurrently and 
> joins them ({{CompletableFuture.get}}), so the batch starts only when the 
> last request returned. With long polling ({{waitTimeSeconds}}), a request 
> that finds no more messages waits up to {{waitTimeSeconds}}, while the 
> messages returned by the first request are already counting down.
> With a gap L between the receive and the start of the batch, the first 
> extension comes between {{L + 0.3 x visibilityTimeout}} and {{L + 0.8 x 
> visibilityTimeout}} after the receive (depending on the phase of the 
> extender). It is late as soon as L is more than about 20 % of 
> {{visibilityTimeout}}:
> ||visibilityTimeout||waitTimeSeconds (gap L)||first extension after the 
> receive||late for||
> |30|20|29 to 44 s|14 of 15 phases|
> |30|10|19 to 34 s|4 of 15 phases|
> |60|20|38 to 68 s|8 of 30 phases|
> |10|5|8 to 13 s|3 of 5 phases|
> A late message becomes visible again while the route still processes it, and 
> another consumer (another instance, or {{concurrentConsumers}} > 1) receives 
> it: it is processed twice, which is what {{extendMessageVisibility}} is for. 
> The extender's {{ChangeMessageVisibility}} then fails ({{MessageNotInflight}} 
> / {{ReceiptHandleIsInvalid}}) and is only logged. This was noted as a 
> follow-up in the review of CAMEL-25700 (apache/camel#27985).
> Trigger: {{extendMessageVisibility=true}}, {{maxMessagesPerPoll}} > 10, long 
> polling with {{waitTimeSeconds}} (or the queue's 
> {{ReceiveMessageWaitTimeSeconds}}) above about 20 % of {{visibilityTimeout}}, 
> and a queue that does not fill every receive request of a poll at once (a 
> quiet or moderately busy queue). With the default {{maxMessagesPerPoll}}, or 
> without long polling, the gap stays small and nothing changes.
> *Fix*: the messages of a poll are dated from the start of the poll (which is 
> never after their receive), and when one of them is due before the next 
> scheduled run of the extender, the extender runs at once (on its own single 
> thread, so it does not overlap a scheduled run). Extensions after the first 
> are unchanged. Cost: with long polling, one extra 
> {{ChangeMessageVisibilityBatch}} call for a batch whose poll waited long.
> *Tests*: new {{SqsConsumerExtendMessageVisibilityLongPollTest}} with the 
> module's {{AmazonSQSClientMock}} (no AWS): 
> {{maxMessagesPerPoll=20&visibilityTimeout=4&extendMessageVisibility=true}}, 
> one request of the poll returns the message at once, the other waits 3 s (a 
> long poll on a queue with no more messages), the route holds the message 
> until it was extended. It asserts that the first 
> {{ChangeMessageVisibilityBatch}} for the message comes less than 4 s after 
> its receive. On main it fails: {{Expecting actual: 4995L to be less than: 
> 4000L}} (4998 ms on the reruns). With the fix it passes; camel-aws2-sqs unit 
> tests: 78 run, 0 failures.
> *How it was found*: a Z3 model of the extension schedule vs the visibility 
> window (period {{max(1, V/2)}} s, deadline registration + 0.8 V, gap L 
> between receive and registration): no counterexample for L = 0, a late first 
> extension once L exceeds about 0.2 V; then the JUnit test above.
> *Affected*: main, camel-4.23.x, camel-4.22.x and camel-4.18.x (same deadline, 
> period and concurrent receive requests; on those branches without CAMEL-25700 
> a message is registered only when its turn in the batch comes, so the gap is 
> larger; read, not run).
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to