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

Work on CAMEL-25684 started by shashank.
----------------------------------------
> camel-slack - the consumer skips the messages of a poll it did not route when 
> the route is suspended during that poll
> ---------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25684
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25684
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-slack
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>
> {{SlackConsumer.createExchanges}} moves {{timestamp}} to the most recent 
> message of the poll (lines 152 / 161 at main cd2ce899764e) before 
> {{processBatch}} routes the messages. {{processBatch}} (172-192) stops when 
> {{isBatchAllowed()}} is false, which {{ScheduledBatchPollingConsumer}} (104) 
> returns when the route is being suspended ({{RouteController.suspendRoute}}, 
> also from a route policy that suspends the route through the route controller 
> such as {{DurationRoutePolicy}}, or {{CamelContext.suspend()}}, which resumes 
> the same consumer): the message that is being routed completes and the rest 
> of the batch is not routed. When the route is resumed the same consumer asks 
> Slack for the messages after {{timestamp}} only, so the messages of that poll 
> that were not routed are never routed. Nothing is logged. With the defaults 
> the most recent message is routed first, so the older messages of the poll 
> are lost: the rest of that poll, which since CAMEL-25523 can be several pages 
> of {{maxResults}} (default 10) messages each.
> This is the shape that CAMEL-25570 fixed in aws2-ddbstream. A consumer 
> suspended directly ({{consumer.suspend()}}, as {{ScheduledRoutePolicy}} and 
> the throttling route policies do) does not end the batch and is not affected; 
> a route that is stopped and started (a new consumer) is not affected either.
> h3. Reproduction
> New {{SlackConsumerSuspendedBatchTest}} (4 tests): a real route against a 
> small local HTTP server that answers {{conversations.history}} as Slack does 
> (messages after {{oldest}}, most recent first). The processor of one message 
> suspends the route from another thread and waits until the batch has ended; 
> then the route is resumed; the fourth test suspends and resumes the 
> {{CamelContext}}. On main all 4 fail: {{expected: <[m5, m4, m3, m2]> but was: 
> <[m5, m4]>}}, in natural order {{expected: <[m2, m3, m4, m5]> but was: <[m2, 
> m3]>}}, with a message posted while suspended {{expected: <[m5, m6, m4, m3, 
> m2]> but was: <[m5, m6]>}}, and for the context suspend {{expected: <[m5, m4, 
> m3, m2]> but was: <[m5, m4]>}}. The same tests with the pooled exchange 
> factory, plus a check of its statistics (the exchanges of the messages that 
> were not routed are given back once), fail on main as well.
> h3. Proposed fix
> * The messages that were not routed are kept and routed by the next poll, 
> together with the messages posted in the meantime, in the order of the 
> endpoint. The timestamp cannot simply stay before them as in the ddbstream 
> fix: by default the most recent message is routed first, so the messages that 
> were not routed are older than the ones that were, and a timestamp before 
> them would route those again.
> * As in the ddbstream fix, the exchanges of those messages are given back to 
> the exchange factory, and {{processBatch}} returns the number of exchanges it 
> routed (used for {{sendEmptyMessageWhenIdle}} and greedy polling) instead of 
> the number it was given.
> * The timestamp is now set in {{poll()}} instead of in {{createExchanges}} 
> (same value).
> * An upgrade guide entry (4.24). The kept messages are in memory only: a 
> route that is stopped and started again does not route them (a new consumer).
> camel-slack tests with the fix (built with the current core modules): 19 run, 
> 0 failures, 1 skipped (as on main).
> How it was found: a TLA+ model of the poll (fetch, route one message at a 
> time while the batch is allowed, end of the batch, suspend and resume as 
> environment steps) violates "between two polls the consumer has not moved 
> past a message it did not route" on main (5 states), holds with the change 
> (newest-first and natural order); then the test.
> Affected: main (cd2ce899764e; tested), camel-4.23.x, camel-4.22.x, 
> camel-4.18.x, camel-4.14.x (the same {{createExchanges}} / {{processBatch}}; 
> read, not run).
> Duplicate check (2026-10-15): JIRA component camel-slack, text "slack 
> consumer suspend" (CAMEL-25523, reading the following pages of the history, 
> already fixed - a different cause of skipped messages); GitHub pull requests 
> "SlackConsumer" (#27674 = CAMEL-25523, merged; nothing open).
> _Filed with Claude Code on behalf of allthingssecurity._



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

Reply via email to