Add VirtualThreadPromiseFactory seed#15960
Conversation
Introduce virtual-thread PromiseFactory and document GPars deprecation path. Assisted-by: Sisyphus:xai/grok-4.5 [gpt-coding]
There was a problem hiding this comment.
Pull request overview
This PR seeds Java 21 virtual-thread support in grails-async by introducing a new VirtualThreadPromiseFactory, wiring it into PromiseFactoryBuilder behind an opt-in system property, and documenting the intended deprecation direction for GPars.
Changes:
- Added
VirtualThreadPromiseFactory(virtual-thread-per-task executor) tograils-async-core. - Updated
PromiseFactoryBuilderto select the virtual-thread factory when-Dgrails.async.promiseFactory=virtual-threadis set and noServiceLoaderfactory is present. - Updated async guide documentation and added a new Spock spec covering selection/execution.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
grails-async/core/src/main/groovy/org/grails/async/factory/future/VirtualThreadPromiseFactory.groovy |
Adds the new virtual-thread-backed PromiseFactory implementation. |
grails-async/core/src/main/groovy/org/grails/async/factory/PromiseFactoryBuilder.groovy |
Adds opt-in selection for the virtual-thread factory via system property. |
grails-async/core/src/test/groovy/grails/async/VirtualThreadPromiseFactorySpec.groovy |
Adds tests for opt-in selection and basic execution behavior. |
grails-doc/src/en/guide/async/asyncPromises.adoc |
Documents the opt-in virtual-thread factory and notes GPars deprecation direction. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @Override | ||
| <T> Promise<List<T>> onComplete(List<Promise<T>> promises, Closure<T> callable) { | ||
| return createPromise({ | ||
| List<T> values = waitAll(promises) | ||
| callable.call(values) | ||
| } as Closure<List<T>>) | ||
| } | ||
|
|
||
| @Override | ||
| <T> Promise<List<T>> onError(List<Promise<T>> promises, Closure<?> callable) { | ||
| return createPromise({ | ||
| try { | ||
| waitAll(promises) | ||
| return null | ||
| } | ||
| catch (Throwable e) { | ||
| callable.call(e) | ||
| return e | ||
| } | ||
| } as Closure<List<T>>) | ||
| } |
| void close() { | ||
| executorService.shutdown() | ||
| } |
|
|
||
| By default, the `Promises` static methods use an instance of `PromiseFactory`. This `PromiseFactory` interface has various implementations. The default implementation is link:{api}org/grails/async/factory/future/CachedThreadPoolPromiseFactory.html[CachedThreadPoolPromiseFactory] which uses a thread pool that will create threads as needed (the same as `java.util.concurrent.Executors.newCachedThreadPool()`) | ||
|
|
||
| Grails 8.1 also includes an opt-in Java 21 virtual-thread seed implementation, `org.grails.async.factory.future.VirtualThreadPromiseFactory`. |
| /** | ||
| * PromiseFactory implementation backed by Java virtual threads. | ||
| * | ||
| * @since 8.1 |
| class VirtualThreadPromiseFactorySpec extends Specification { | ||
|
|
||
| def cleanup() { | ||
| System.clearProperty('grails.async.promiseFactory') | ||
| Promises.promiseFactory = null | ||
| } | ||
|
|
||
| void 'builder can opt in to virtual thread promise factory'() { | ||
| given: | ||
| System.setProperty('grails.async.promiseFactory', 'virtual-thread') | ||
|
|
||
| expect: | ||
| PromiseFactoryBuilder.build() instanceof VirtualThreadPromiseFactory | ||
| } |
|
We've previously discussed with @paulk-asert about integrating Gpars into groovy. I do not agree with it's deprecation. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## 8.0.x #15960 +/- ##
==================================================
- Coverage 49.5403% 49.5345% -0.0057%
- Complexity 16922 16925 +3
==================================================
Files 1999 2000 +1
Lines 93754 93779 +25
Branches 16420 16421 +1
==================================================
+ Hits 46446 46453 +7
- Misses 40145 40161 +16
- Partials 7163 7165 +2
🚀 New features to boost your workflow:
|
✅ All tests passed ✅🏷️ Commit: 5722a42 Learn more about TestLens at testlens.app. |
Description
What was found
What changed
VirtualThreadPromiseFactoryin grails-async-corePromiseFactoryBuilderwith opt-in configOut of scope / follow-up
Related MD topics
Contributor Checklist
Issue and Scope
8.0.x.Code Quality
Licensing and Attribution
ai-generated-starting-pointlabel applied.Documentation
Assisted-by: Sisyphus:xai/grok-4.5 [gpt-coding]