gnodet opened a new pull request, #28147:
URL: https://github.com/apache/camel/pull/28147
## Summary
Defer error handler startup in `MulticastProcessor` from `doInit()` to
`doStart()` to fix compatibility with `SupervisingRouteController` when a
producer cannot connect at context startup.
`Splitter` extends `MulticastProcessor` and is fixed by this change as well.
## Root Cause
`MulticastProcessor.doInit()` calls `wrapInErrorHandler()` for each child
processor, which eagerly invoked `ServiceHelper.startService(answer)` on the
wrapped error handler. Starting the error handler starts the wrapped
`SendProcessor`, which in turn starts the underlying `Producer` (via
`camelContext.addService(producer, true, true)`).
This producer startup happens:
- During route *initialization*, before `CamelContext` is fully started
- Outside the `SupervisingRouteController` retry scope
A producer that cannot connect yet (e.g. broker is temporarily down)
propagates the exception directly to `context.start()`, failing the entire
context — even though the route was marked for supervision.
## Fix
Two changes in `MulticastProcessor`:
1. **In `wrapInErrorHandler()`**: replaced the unconditional
`ServiceHelper.startService(answer)` with a conditional start: only start
immediately if `getCamelContext().isStarted()` (i.e., at runtime during message
processing). During `doInit()` the context is `STARTING`, so the built error
handler is cached in `errorHandlers` but not started.
2. **In `doStart()`**: added
`ServiceHelper.startService(errorHandlers.values())` to start any pre-built
error handlers that were deferred from `doInit()`. This runs under the route
lifecycle managed by `SupervisingRouteController`, so failures are caught and
the route is scheduled for retry with back-off.
`ServiceHelper.start()` is idempotent (no-op if already started), so there
is no double-start risk when new error handlers are built at runtime (context
`STARTED`) and `doStart()` iterates over `errorHandlers.values()`.
## Tests
New test class `DefaultSupervisingRouteControllerMulticastSplitTest` with
two test methods:
- `testSplitWithFlakyProducer()` — a `split().to("flaky:target")` route
where the producer fails its first 2 `doStart()` calls. Asserts
`context.start()` does not throw and the route eventually reaches `Started`
after the supervising controller retries.
- `testMulticastWithFlakyProducer()` — same scenario with
`multicast().to("flaky:target")`.
Fixes #CAMEL-25823
---
_Hermes Agent (Claude Sonnet 4.6) on behalf of Guillaume Nodet_
--
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]