Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Signed-off-by: Attila Mészáros <a_meszaros@apple.com>
609a12f to
cacd8be
Compare
There was a problem hiding this comment.
🟡 Changes recommended
One or more issues must be addressed before approval.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds optional Java 21 virtual-thread execution support while preserving configured concurrency limits and Java 17 compatibility.
Changes:
- Adds virtual-thread configuration and property loading.
- Implements bounded and unbounded virtual-thread executors with fallback behavior.
- Adds unit, integration, and documentation coverage.
File summaries
| File | Description |
|---|---|
| operator-framework/src/test/java/io/javaoperatorsdk/operator/config/loader/ConfigLoaderTest.java | Updated as part of this pull request. |
| operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/virtualthreads/VirtualThreadsTestReconciler.java | Updated as part of this pull request. |
| operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/virtualthreads/VirtualThreadsIT.java | Updated as part of this pull request. |
| operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/virtualthreads/VirtualThreadsCustomResource.java | Updated as part of this pull request. |
| operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/ConfigLoader.java | Updated as part of this pull request. |
| operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/VirtualThreadsTest.java | Updated as part of this pull request. |
| operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverriderTest.java | Updated as part of this pull request. |
| operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/VirtualThreads.java | Updated as part of this pull request. |
| operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ExecutorServiceManager.java | Updated as part of this pull request. |
| operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java | Updated as part of this pull request. |
| operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java | Updated as part of this pull request. |
| docs/content/en/docs/documentation/operations/configuration.md | Updated as part of this pull request. |
Review details
Suppressed comments (1)
operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/VirtualThreads.java:143
- This implementation creates and parks one virtual thread for every submitted task before acquiring a permit. Unlike the previous fixed pool, a large reconciliation backlog therefore becomes one live virtual-thread object per queued event, so a burst or outage can consume substantial heap/thread-scheduler resources even though only
maxConcurrencytasks execute. Please use a bounded dispatcher/queue (or otherwise cap pending submissions) so the concurrency limit also bounds resource usage, rather than relying on virtual threads being cheap.
delegate.execute(
() -> {
try {
permits.acquire();
- Files reviewed: 12/12 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| private BoundedExecutorService(ExecutorService delegate, int maxConcurrency) { | ||
| this.delegate = delegate; | ||
| // fair, so that tasks run roughly in submission order as they would on a thread pool | ||
| this.permits = new Semaphore(maxConcurrency, true); |
There was a problem hiding this comment.
🟡 Changes recommended
Address the shutdown/cancellation defect, reject zero concurrency limits, and clarify the scheduled-executor documentation.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (2)
docs/content/en/docs/documentation/operations/configuration.md:37
- This says that all framework internal housekeeping runs on virtual threads, but
ExecutorServiceManagerdeliberately keepsscheduledExecutorServiceon platform threads even when the flag is enabled (seeExecutorServiceManager.java:171-173). Please narrow this statement to the executors that are switched, or explicitly mention the scheduled executor exception so the user-facing documentation matches the implementation.
When enabled, reconciliations, dependent resource workflows and the framework's internal
housekeeping (starting the informers, for example) all run on virtual threads.
operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/VirtualThreads.java:135
- Unlike
Executors.newFixedThreadPool, this constructor acceptsmaxConcurrency == 0becauseSemaphore(0)is valid. Every submitted task then blocks forever waiting for a permit, so the new publicExecutorServiceManager.newBoundedExecutorService(0, true)can silently create a permanently hanging executor instead of rejecting the invalid limit. Validate that the limit is at least 1 before creating the semaphore (and keep the behavior consistent with the platform-backed path).
private BoundedExecutorService(ExecutorService delegate, int maxConcurrency) {
this.delegate = delegate;
// fair, so that tasks run roughly in submission order as they would on a thread pool
this.permits = new Semaphore(maxConcurrency, true);
- Files reviewed: 12/12 changed files
- Comments generated: 1
- Review effort level: Lite
| public List<Runnable> shutdownNow() { | ||
| return delegate.shutdownNow(); | ||
| } |
xstefank
left a comment
There was a problem hiding this comment.
Approving because I know that I will be probably only one against a global virtual thread flag here.
But maybe you want to wait for our next JUG session :) - https://www.meetup.com/brno-java-meetup/events/316579260/?eventOrigin=group_upcoming_events
What would you propose as an alternative? |
Signed-off-by: Attila Mészáros <a_meszaros@apple.com>
Introduces feature flag to use virtual threads instead of standard
ThreadPools.Thus, basically only replaces internal the thread pools, with ones that use virtual threads.
The concurrency limit also applies for this new mode (using
Semaphore).Note that for now we aim for Java 25, and the intention is that only that will be officially supported, since
synchronizedkeyword is used extensively in the codebase.Signed-off-by: Attila Mészáros a_meszaros@apple.com
TODO: