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]

Reply via email to