allthingssecurity opened a new pull request, #27674:
URL: https://github.com/apache/camel/pull/27674

   # Description
   
   [CAMEL-25523](https://issues.apache.org/jira/browse/CAMEL-25523)
   
   `SlackConsumer.poll()` made one `conversations.history` request with 
`oldest` (the timestamp of the last consumed message) and `limit` = 
`maxResults` (default 10), routed the messages of that response and moved the 
timestamp to the most recent of them. Slack returns the most recent messages of 
the range first, at most `limit` of them, and signals the older ones with 
`has_more` and `response_metadata.next_cursor`, which the consumer ignored. So 
when more than `maxResults` messages were posted between two polls (default 
delay 10 seconds), the older ones were skipped without a trace; with the docs 
example `maxResults=1`, two messages within one poll interval lost one.
   
   Now a poll that follows the first one reads the following pages with 
`next_cursor` (same `limit`) when the response has `has_more`, and routes all 
the new messages in the same order as before (most recent first, or oldest 
first with `naturalOrder`). A poll with at most `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, so the option description (with the generated 
`slack.json`, the catalog and the endpoint DSL copies), the component docs 
(with the catalog copy) and the 4.23 upgrade guide say that `maxResults` is the 
number of messages per request, and to raise it for a busy channel.
   
   If the request for a following page fails, for example because Slack rate 
limits it (apps that Slack limits to one `conversations.history` request per 
minute, commercially distributed apps outside the Slack Marketplace since May 
2025, get HTTP 429 for the second page), the poll does not fail: the consumer 
routes the most recent messages it has already read and moves the timestamp, as 
main does, and logs a WARN with the error saying that the older messages of 
that poll were skipped. So such apps are never worse off than with main, and a 
failing following page does not make every poll fail. The messages of a poll 
are held in memory until they are routed. The component docs (with the catalog 
copy) and the upgrade note describe this fallback.
   
   Tests:
   - New `SlackConsumerHasMoreTest`: a local HTTP server (via the `serverUrl` 
option) answers `conversations.list` and `conversations.history` as Slack does 
(`oldest` exclusive, most recent first, `limit` per page, `has_more`, 
`next_cursor`); with `maxResults=2`, five messages are posted at once after the 
first poll, in the default order and with `naturalOrder=true`.
   - A third test answers every following-page request with HTTP 429 
(`Retry-After: 60`, `{"ok":false,"error":"ratelimited"}`, which the Slack SDK 
raises as `SlackApiException`): the poll routes the two most recent messages 
once and does not fail (a failed poll would read the range again at every poll).
   - Without the change the first two fail: `mock://result Received message 
count. Expected: <5> but was: <2>`.
   - With the change: camel-slack 9 tests, 0 failures (1 skipped, needs a Slack 
token).
   
   Found with a Lean 4 model of the poll: "a poll routes every message newer 
than the timestamp" fails for five new messages and a limit of 2 (and with a 
limit of 1 the second of two messages is never routed by any later poll), and 
the fix is proved to route exactly the new messages for every `maxResults` >= 1 
and to send the same single request as before when no more than `maxResults` 
messages are new. I then reproduced it with the consumer.
   
   # Target
   
   - [x] I checked that the commit is targeting the correct branch (Camel 4 
uses the `main` branch)
   
   # Tracking
   - [x] If this is a large change, bug fix, or code improvement, I checked 
there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL) filed for 
the change (usually before you start working on it).
   
   # Apache Camel coding standards and style
   
   - [x] I checked that each commit in the pull request has a meaningful 
subject line and body.
   - [ ] I have run `mvn clean install -DskipTests` locally from root folder 
and I have committed all auto-generated changes.
     (I built and tested camel-slack, including the formatter and import-sort 
plugins, and updated the generated catalog and endpoint DSL copies of the 
option description by hand. I did not run the full root build.)
   
   # AI-assisted contributions
   
   - [x] If this PR includes AI-generated code, commits have proper 
co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR 
description identifies the AI tool used.
     This PR was prepared with Claude Code (Claude Opus 5.5). The commit 
carries a `Co-Authored-By` trailer.
   
   _Claude Code on behalf of allthingssecurity_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


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