allthingssecurity opened a new pull request, #27918: URL: https://github.com/apache/camel/pull/27918
# Description [CAMEL-25679](https://issues.apache.org/jira/browse/CAMEL-25679) The tailable cursor consumer (the default `consumerType`) and the change streams consumer read from a cursor on one thread, `MongoAbstractConsumerThread.run()`. When a read fails (for example the connection to the server is lost) the loop logs a WARN ("Will try again on next poll"), closes the cursor, waits `cursorRegenerationDelay` (1000 ms by default) and opens a new cursor. CAMEL-16025 put `doRun()` inside a `try`, but the new cursor is still opened after it (`cursor = initializeCursor()`, line 130 on main). While the server is still unreachable, opening the cursor fails once the driver's server selection timeout (30 seconds by default) is over, with `MongoTimeoutException`. The exception left `run()` and ended the consumer thread. The route stayed started and consumed nothing until it was restarted, and the only trace was the uncaught exception printed on stderr by the thread. With default options this happens whenever the server cannot be reached for longer than about 31 seconds (restart, slow failover, network outage). Changes (`MongoAbstractConsumerThread` only, so both consumers get it): - The new cursor is opened at the start of the next iteration, inside the `try`: a failure is logged like a failed read and tried again after `cursorRegenerationDelay`, until the server is back or the consumer is stopped. The order of the steps (close, wait, open, read) is the same as before. - A cursor that is opened while the consumer is being stopped is closed instead of read: `stop()` closes the cursor it sees, and on main a cursor opened right after that was left open. - The `cursor` field is volatile, as `stop()` reads it from another thread. What users can notice: after an outage the consumer reads again once the server is back. While the server is down there is one WARN with stack trace per attempt (about every 31 seconds with the defaults), the same WARN that main already logs for a failed read. No option or default changes, so no upgrade guide entry. Tests: - New `MongoDbConsumerCursorRegenerationTest` (3 tests), Mockito mocks of the driver objects, no server, every wait bounded, no sleeps: - tailable consumer: the cursor of the start fails its read (`MongoSocketReadException`), the first new cursor cannot be opened (`MongoTimeoutException`), the next one returns a document, which must be routed; - the same for the change streams consumer; - the consumer thread is stopped while it opens a new cursor: that cursor must be closed and not read. This test runs the tailing thread of the consumer on a thread of the test (no route), so that it can call `stop()` while the cursor is being opened without reaching into private fields. - Without the change (main's `MongoAbstractConsumerThread`, same tests) all three fail: `mock://result Received message count. Expected: <1> but was: <0>` for both consumers (the output shows `Exception in thread "Camel (camel-1) thread #1 - mongodb://myDb" com.mongodb.MongoTimeoutException: Timed out while waiting for a server`), and `Wanted but not invoked: mongoCursor.close()` for the third. - With the change the camel-mongodb unit tests pass: 21 run, 0 failures, 0 skipped. What is not changed: - The tailable consumer still ends quietly when the driver throws `IllegalStateException` from `hasNext()` (that branch is meant for a cursor closed by `stop()`). - The change streams consumer still logs a failed read at DEBUG only. - No backoff beyond `cursorRegenerationDelay`; opening a cursor while the server is down already blocks for the server selection timeout. What was not run: the module's integration tests (they need a MongoDB container), a real server outage. # Target - [x] I checked that the commit is targeting the correct branch (Camel 4 uses the `main` branch) # Tracking - [ ] 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). (The ticket is drafted and not filed yet; CAMEL-25679 is a placeholder until it is.) # 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-mongodb, including the formatter and import-sort plugins. 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]
