shashank created CAMEL-25523:
--------------------------------

             Summary: camel-slack - the consumer skips messages when more than 
maxResults messages are posted between two polls
                 Key: CAMEL-25523
                 URL: https://issues.apache.org/jira/browse/CAMEL-25523
             Project: Camel
          Issue Type: Bug
          Components: camel-slack
            Reporter: shashank


{{SlackConsumer.poll()}} (lines 75-94 at main a6979506bb1c) makes one 
{{conversations.history}} request with {{oldest}} set to the timestamp of the 
last consumed message and {{limit}} set to {{maxResults}} (default 10), routes 
the messages of that response and sets the timestamp to the first of them 
({{createExchanges}}, lines 96-123):

{code:java}
ConversationsHistoryResponse response = 
slack.methods(token).conversationsHistory(req -> req
        .channel(channelId)
        .oldest(timestamp)
        .limit(timestamp != null ? 
Integer.parseInt(slackEndpoint.getMaxResults()) : 1));
...
Queue<Exchange> exchanges = createExchanges(response.getMessages());
{code}

Slack returns "the most recent messages in the time range first" and at most 
{{limit}} of them; when there are more, {{has_more}} is true and 
{{response_metadata.next_cursor}} points to the following, older, page. The 
consumer ignores both. So when more than {{maxResults}} messages are posted to 
the channel between two polls (default delay 10 seconds), it routes the 
{{maxResults}} most recent ones, moves the timestamp past the others, and never 
consumes them. Nothing is logged. With the docs example {{maxResults=1}}, any 
two messages posted within one poll interval lose one of them. The docs say the 
consumer "will consume only newer messages in the channel", i.e. all of them.

h3. Reproduction

New {{SlackConsumerHasMoreTest}}: a local HTTP server answers 
{{conversations.list}} and {{conversations.history}} as Slack does ({{oldest}} 
exclusive, most recent first, {{limit}} per page, {{has_more}} and 
{{next_cursor}}), via the {{serverUrl}} option. The route uses 
{{maxResults=2}}; after the first poll has routed the last message of the 
history, five messages are posted at once. On main both tests (default order 
and {{naturalOrder=true}}) fail twice:
{noformat}
mock://result Received message count. Expected: <5> but was: <2>
{noformat}

h3. Proposed fix

When a poll that follows the first one gets {{has_more}}, the consumer reads 
the following pages with {{next_cursor}} (same {{limit}}) in the same poll and 
routes all the messages, in the same order as before (most recent first, or 
oldest first with {{naturalOrder}}); the timestamp is still the most recent 
message. A poll with no more than {{maxResults}} new messages sends the same 
single request as before, and the first poll (which reads the last message of 
the history) is unchanged. A poll can now route more than {{maxResults}} 
messages; the option description, the component docs (and the catalog copies) 
say that {{maxResults}} is the number of messages per request, and the 4.23 
upgrade guide has a note (raise {{maxResults}} for a busy channel to need fewer 
requests). camel-slack tests with the fix: 8, 0 failures (1 skipped, needs a 
Slack token).

Found with a Lean 4 model of the poll (a channel as a list of increasing 
timestamps, the API as "after oldest, most recent first, limit per page"): "a 
poll routes every message newer than the timestamp" fails for five new messages 
and {{limit}} 2, and with {{limit}} 1 the second of two messages is never 
routed by any later poll; main is proved to route at most {{limit}} messages 
(so it misses some whenever more are new). The fix is proved to route exactly 
the new messages for every channel, timestamp and {{maxResults}} >= 1, and to 
send the same single request as main when no more than {{maxResults}} messages 
are new. Confirmed with the real consumer.

Affected: main, camel-4.22.x, camel-4.18.x, camel-4.14.x (same code, GitHub 
contents API).

Duplicate check (2026-10-10): JIRA text "slack" and "consumer" (17, none about 
skipped messages; CAMEL-18187 is about pooled exchanges, CAMEL-12806 about an 
empty list), "conversations.history" (none); GitHub pull requests 
"SlackConsumer" (3, none related), "slack consumer" (none). No open pull 
request changes {{SlackConsumer}}.

_Filed with Claude Code on behalf of allthingssecurity._




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

Reply via email to