ammachado opened a new pull request, #28823: URL: https://github.com/apache/camel/pull/28823
# Description [CAMEL-26478](https://issues.apache.org/jira/browse/CAMEL-26478), found through a failing test with virtual threads, under [CAMEL-25132](https://issues.apache.org/jira/browse/CAMEL-25132). With `camel.threads.virtual.enabled=true`, `BoundedExecutorService` limits a pool to `maxQueueSize` permits. A parallel split runs in the executor and submits its items to it, so with a low `maxQueueSize` it waits for a permit it holds itself. - With `CallerRuns`, the default, each wait lasts until `keepAliveTime` expires. - With `Block`, the wait has no timeout, so from reading the code it hangs forever. This was not run on the old code end to end; `testNestedTaskRunsInlineWithBlockPolicy` shows it at the executor level. - With a split `timeout`, the unfinished items are dropped with **no exception**, so messages are lost. In `SplitTimeoutCancelTaskTest`, 1 of 4 messages arrived. Measured before this change, `maxQueueSize=1`, one exchange: | `keepAliveTime` | 4 items | 20 items | |---|---|---| | 1 s | 7 s | 39 s | | 3 s | 21 s | 117 s | With platform threads, the same settings took a few milliseconds. ## The change A task of this executor that finds no free permit no longer waits, unless the policy is `Abort`: - It **runs the work itself**, as `CallerRunsPolicy` does on platform threads. - **Past a depth of 64 it hands the work to a new task, without a permit.** A parallel split submits itself again for each item, so running everything inline overflows the stack: a first version of this change stopped after 1068 items of a 20000 item split and hung with no exception. Queueing the work to run later would avoid that, but it would deadlock a task that waits for what it submitted. `Abort` waits and fails as before, so nothing is lost silently. A submitter outside the executor waits as before, so backpressure does not change. The hand-off can exceed `maxQueueSize`, which the class already documents for caller-run tasks. Measured below, the items of a split peaked at 2 to 3 running at once with `maxQueueSize` 1 and 2. The meaning of `maxQueueSize` and `keepAliveTime` for virtual threads is deliberate (CAMEL-23602), so I left both alone. There is an upgrade guide entry. ## Measurements Virtual threads, JDK 25 macOS arm64, not JMH, default `keepAliveTime` of 60 s: | `maxQueueSize` | items | time | peak items running | |---|---|---|---| | 1 | 20000 | 25 to 84 ms | 2 to 3 | | 1 | 200000 | 131 to 162 ms | 2 | | 2 | 200000 | 220 to 295 ms | 2 to 3 | All items arrived, streaming and not. Concurrent exchanges were measured on the first version only, before the depth limit: 32 threads, 6400 exchanges, `maxQueueSize=1`, all 25600 items arrived. ## Tests 6 new tests in `BoundedExecutorServiceTest`. The 2 inline tests failed before the change. `testTaskThatResubmitsItselfDoesNotOverflowTheStack` failed with a `StackOverflowError` on the first version. The other 3 are guards for what must not change, and pass either way: `Abort` is still rejected, a free permit is still used, and a task of another executor still waits. Verified: - Full suites with platform threads: `camel-util` 331 tests, `camel-core` 8672 (44 skipped, not reviewed one by one), 0 failures. - 725 tests selected by name with virtual threads (split, multicast, recipient list, thread and executor tests): 4 failures. `SplitTimeoutCancelTaskTest` passes now. `ThreadsCoreAndMaxPoolInvalidTest`, `ThreadsZeroInCoreAndMaxPoolTest` and `ThreadsKeepAliveTimeTest` are addressed by #28821. `SplitterParallelAsyncProcessorIssueTest.testSplitParallelProcessingMaxThreads` fails the same way without this change; I did not look into it further. Component modules were not run. # 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. Not run from the root folder: I ran `mvn install -Dquickly -pl core/camel-core -am`, and `git status` showed only the changed files afterwards. # 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. 🤖 Generated with [Claude Code](https://claude.com/claude-code) on behalf of Adriano Machado (@ammachado) _This was generated by an AI agent and may contain inaccuracies. Please verify before relying on it._ -- 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]
